2 ** Copyright (c) 2003-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
14 #include <samplerate.h>
18 #define BUFFER_LEN 10000
19 #define CB_READ_LEN 256
21 static void callback_test (int converter
, double ratio
) ;
22 static void end_of_stream_test (int converter
) ;
26 { static double src_ratios
[] =
27 { 1.0, 0.099, 0.1, 0.33333333, 0.789, 1.0001, 1.9, 3.1, 9.9
34 puts (" Zero Order Hold interpolator :") ;
35 for (k
= 0 ; k
< ARRAY_LEN (src_ratios
) ; k
++)
36 callback_test (SRC_ZERO_ORDER_HOLD
, src_ratios
[k
]) ;
38 puts (" Linear interpolator :") ;
39 for (k
= 0 ; k
< ARRAY_LEN (src_ratios
) ; k
++)
40 callback_test (SRC_LINEAR
, src_ratios
[k
]) ;
42 puts (" Sinc interpolator :") ;
43 for (k
= 0 ; k
< ARRAY_LEN (src_ratios
) ; k
++)
44 callback_test (SRC_SINC_FASTEST
, src_ratios
[k
]) ;
48 puts (" End of stream test :") ;
49 end_of_stream_test (SRC_ZERO_ORDER_HOLD
) ;
50 end_of_stream_test (SRC_LINEAR
) ;
51 end_of_stream_test (SRC_SINC_FASTEST
) ;
57 /*=====================================================================================
64 float data
[BUFFER_LEN
] ;
68 test_callback_func (void *cb_data
, float **data
)
69 { TEST_CB_DATA
*pcb_data
;
73 if ((pcb_data
= cb_data
) == NULL
)
79 if (pcb_data
->total
- pcb_data
->count
> CB_READ_LEN
)
80 frames
= CB_READ_LEN
/ pcb_data
->channels
;
82 frames
= (pcb_data
->total
- pcb_data
->count
) / pcb_data
->channels
;
84 *data
= pcb_data
->data
+ pcb_data
->count
;
85 pcb_data
->count
+= frames
;
88 } /* test_callback_func */
92 callback_test (int converter
, double src_ratio
)
93 { static TEST_CB_DATA test_callback_data
;
94 static float output
[BUFFER_LEN
] ;
96 SRC_STATE
*src_state
;
98 long read_count
, read_total
;
101 printf ("\tcallback_test (SRC ratio = %6.4f) ........... ", src_ratio
) ;
104 test_callback_data
.channels
= 2 ;
105 test_callback_data
.count
= 0 ;
106 test_callback_data
.end_of_data
= 0 ;
107 test_callback_data
.total
= ARRAY_LEN (test_callback_data
.data
) ;
109 if ((src_state
= src_callback_new (test_callback_func
, converter
, test_callback_data
.channels
, &error
, &test_callback_data
)) == NULL
)
110 { printf ("\n\nLine %d : %s\n\n", __LINE__
, src_strerror (error
)) ;
116 { /* We will be throwing away output data, so just grab as much as possible. */
117 read_count
= ARRAY_LEN (output
) / test_callback_data
.channels
;
118 read_count
= src_callback_read (src_state
, src_ratio
, read_count
, output
) ;
119 read_total
+= read_count
;
121 while (read_count
> 0) ;
123 if ((error
= src_error (src_state
)) != 0)
124 { printf ("\n\nLine %d : %s\n\n", __LINE__
, src_strerror (error
)) ;
128 src_state
= src_delete (src_state
) ;
130 if (fabs (read_total
/ src_ratio
- ARRAY_LEN (test_callback_data
.data
)) > 2.0)
131 { printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__
) ;
132 printf (" input len : %d\n", ARRAY_LEN (test_callback_data
.data
)) ;
133 printf (" output len : %ld (should be %g +/- 2)\n\n", read_total
,
134 floor (0.5 + src_ratio
* ARRAY_LEN (test_callback_data
.data
))) ;
141 } /* callback_test */
143 /*=====================================================================================
147 eos_callback_func (void *cb_data
, float **data
)
149 TEST_CB_DATA
*pcb_data
;
155 if ((pcb_data
= cb_data
) == NULL
)
159 ** Return immediately if there is no more data.
160 ** In this case, the output pointer 'data' will not be set and
161 ** valgrind should not warn about it.
163 if (pcb_data
->end_of_data
)
166 if (pcb_data
->total
- pcb_data
->count
> CB_READ_LEN
)
167 frames
= CB_READ_LEN
/ pcb_data
->channels
;
169 frames
= (pcb_data
->total
- pcb_data
->count
) / pcb_data
->channels
;
171 *data
= pcb_data
->data
+ pcb_data
->count
;
172 pcb_data
->count
+= frames
;
175 ** Set end_of_data so that the next call to the callback function will
176 ** return zero ocunt without setting the 'data' pointer.
178 if (pcb_data
->total
< 2 * pcb_data
->count
)
179 pcb_data
->end_of_data
= 1 ;
182 } /* eos_callback_data */
186 end_of_stream_test (int converter
)
187 { static TEST_CB_DATA test_callback_data
;
188 static float output
[BUFFER_LEN
] ;
190 SRC_STATE
*src_state
;
192 double src_ratio
= 0.3 ;
193 long read_count
, read_total
;
196 printf ("\t%-30s ........... ", src_get_name (converter
)) ;
199 test_callback_data
.channels
= 2 ;
200 test_callback_data
.count
= 0 ;
201 test_callback_data
.end_of_data
= 0 ;
202 test_callback_data
.total
= ARRAY_LEN (test_callback_data
.data
) ;
204 if ((src_state
= src_callback_new (eos_callback_func
, converter
, test_callback_data
.channels
, &error
, &test_callback_data
)) == NULL
)
205 { printf ("\n\nLine %d : %s\n\n", __LINE__
, src_strerror (error
)) ;
211 { /* We will be throwing away output data, so just grab as much as possible. */
212 read_count
= ARRAY_LEN (output
) / test_callback_data
.channels
;
213 read_count
= src_callback_read (src_state
, src_ratio
, read_count
, output
) ;
214 read_total
+= read_count
;
216 while (read_count
> 0) ;
218 if ((error
= src_error (src_state
)) != 0)
219 { printf ("\n\nLine %d : %s\n\n", __LINE__
, src_strerror (error
)) ;
223 src_state
= src_delete (src_state
) ;
225 if (test_callback_data
.end_of_data
== 0)
226 { printf ("\n\nLine %d : test_callback_data.end_of_data should not be 0."
227 " This is a bug in the test.\n\n", __LINE__
) ;
233 } /* end_of_stream_test */