Bundle libsamplerate
[audio-libsamplerate.git] / libsamplerate / tests / termination_test.c
CommitLineData
8529da43
MG
1/*
2** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3** All rights reserved.
4**
5** This code is released under 2-clause BSD license. Please see the
6** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
7*/
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12
13#include <samplerate.h>
14
15#include "util.h"
16
17#define SHORT_BUFFER_LEN 2048
18#define LONG_BUFFER_LEN ((1 << 16) - 20)
19
20static void simple_test (int converter) ;
21static void stream_test (int converter, double ratio) ;
22static void init_term_test (int converter, double ratio) ;
23
24static int next_block_length (int reset) ;
25
26int
27main (void)
28{ static double src_ratios [] =
29 { 0.999900, 1.000100, 0.789012, 1.200000, 0.333333, 3.100000,
30 0.125000, 8.000000, 0.099900, 9.990000, 0.100000, 10.00000
31 } ;
32
33 int k ;
34
35 puts ("\n Zero Order Hold interpolator:") ;
36
37 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
38 init_term_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
39 puts ("") ;
40 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
41 stream_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
42
43
44 puts ("\n Linear interpolator:") ;
45 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
46 init_term_test (SRC_LINEAR, src_ratios [k]) ;
47 puts ("") ;
48 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
49 stream_test (SRC_LINEAR, src_ratios [k]) ;
50
51
52 puts ("\n Sinc interpolator:") ;
53 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
54 init_term_test (SRC_SINC_FASTEST, src_ratios [k]) ;
55 puts ("") ;
56 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
57 stream_test (SRC_SINC_FASTEST, src_ratios [k]) ;
58
59 puts ("") ;
60
61 simple_test (SRC_SINC_FASTEST) ;
62
63 return 0 ;
64} /* main */
65
66static void
67simple_test (int converter)
68{
69 int ilen = 199030, olen = 1000, error ;
70
71 {
72 float in [ilen] ;
73 float out [olen] ;
74 double ratio = (1.0 * olen) / ilen ;
75 SRC_DATA src_data =
76 { in, out,
77 ilen, olen,
78 0, 0, 0,
79 ratio
80 } ;
81
82 error = src_simple (&src_data, converter, 1) ;
83 if (error)
84 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
85 exit (1) ;
86 } ;
87 } ;
88
89 return ;
90} /* simple_test */
91
92static void
93init_term_test (int converter, double src_ratio)
94{ static float input [SHORT_BUFFER_LEN], output [SHORT_BUFFER_LEN] ;
95
96 SRC_DATA src_data ;
97
98 int k, input_len, output_len, error, terminate ;
99
100 printf ("\tinit_term_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
101 fflush (stdout) ;
102
103 /* Calculate maximun input and output lengths. */
104 if (src_ratio >= 1.0)
105 { output_len = SHORT_BUFFER_LEN ;
106 input_len = (int) floor (SHORT_BUFFER_LEN / src_ratio) ;
107 }
108 else
109 { input_len = SHORT_BUFFER_LEN ;
110 output_len = (int) floor (SHORT_BUFFER_LEN * src_ratio) ;
111 } ;
112
113 /* Reduce input_len by 10 so output is longer than necessary. */
114 input_len -= 10 ;
115
116 for (k = 0 ; k < ARRAY_LEN (input) ; k++)
117 input [k] = 1.0 ;
118
119 if (output_len > SHORT_BUFFER_LEN)
120 { printf ("\n\nLine %d : output_len > SHORT_BUFFER_LEN\n\n", __LINE__) ;
121 exit (1) ;
122 } ;
123
124 src_data.data_in = input ;
125 src_data.input_frames = input_len ;
126
127 src_data.src_ratio = src_ratio ;
128
129 src_data.data_out = output ;
130 src_data.output_frames = SHORT_BUFFER_LEN ;
131
132 if ((error = src_simple (&src_data, converter, 1)))
133 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
134 exit (1) ;
135 } ;
136
137 terminate = (int) ceil ((src_ratio >= 1.0) ? 1 : 1.0 / src_ratio) ;
138
139 if (fabs (src_ratio * input_len - src_data.output_frames_gen) > terminate)
140 { printf ("\n\nLine %d : Bad output frame count.\n\n", __LINE__) ;
141 printf ("\tterminate : %d\n", terminate) ;
142 printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
143 printf ("\tinput_len : %d\n"
144 "\tinput_len * src_ratio : %f\n", input_len, input_len * src_ratio) ;
145 printf ("\toutput_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
146 exit (1) ;
147 } ;
148
149 if (labs (src_data.input_frames_used - input_len) > 1)
150 { printf ("\n\nLine %d : input_frames_used should be %d, is %ld.\n\n",
151 __LINE__, input_len, src_data.input_frames_used) ;
152 printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
153 printf ("\tinput_len : %d\n\tinput_used : %ld\n\n", input_len, src_data.input_frames_used) ;
154 exit (1) ;
155 } ;
156
157 if (fabs (output [0]) < 0.1)
158 { printf ("\n\nLine %d : First output sample is bad.\n\n", __LINE__) ;
159 printf ("\toutput [0] == %f\n\n", output [0]) ;
160 exit (1) ;
161 }
162
163 puts ("ok") ;
164
165 return ;
166} /* init_term_test */
167
168static void
169stream_test (int converter, double src_ratio)
170{ static float input [LONG_BUFFER_LEN], output [LONG_BUFFER_LEN] ;
171
172 SRC_STATE *src_state ;
173 SRC_DATA src_data ;
174
175 int input_len, output_len, current_in, current_out ;
176 int k, error, terminate ;
177
178 printf ("\tstream_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
179 fflush (stdout) ;
180
181/* Erik */
182for (k = 0 ; k < LONG_BUFFER_LEN ; k++) input [k] = k * 1.0 ;
183
184 /* Calculate maximun input and output lengths. */
185 if (src_ratio >= 1.0)
186 { output_len = LONG_BUFFER_LEN ;
187 input_len = (int) floor (LONG_BUFFER_LEN / src_ratio) ;
188 }
189 else
190 { input_len = LONG_BUFFER_LEN ;
191 output_len = (int) floor (LONG_BUFFER_LEN * src_ratio) ;
192 } ;
193
194 /* Reduce input_len by 10 so output is longer than necessary. */
195 input_len -= 20 ;
196
197 if (output_len > LONG_BUFFER_LEN)
198 { printf ("\n\nLine %d : output_len > LONG_BUFFER_LEN\n\n", __LINE__) ;
199 exit (1) ;
200 } ;
201
202 current_in = current_out = 0 ;
203
204 /* Perform sample rate conversion. */
205 if ((src_state = src_new (converter, 1, &error)) == NULL)
206 { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
207 exit (1) ;
208 } ;
209
210 src_data.end_of_input = 0 ; /* Set this later. */
211
212 src_data.data_in = input ;
213
214 src_data.src_ratio = src_ratio ;
215
216 src_data.data_out = output ;
217 src_data.output_frames = ARRAY_LEN (output) / 10 ;
218
219 terminate = 1 + (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
220
221 while (1)
222 {
223 src_data.input_frames = next_block_length (0) ;
224 src_data.input_frames = MIN (src_data.input_frames, input_len - current_in) ;
225
226 src_data.output_frames = ARRAY_LEN (output) - current_out ;
227 /*-Erik MIN (src_data.output_frames, output_len - current_out) ;-*/
228
229 src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;
230
231 if ((error = src_process (src_state, &src_data)))
232 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
233 printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
234 printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
235 exit (1) ;
236 } ;
237
238 if (src_data.end_of_input && src_data.output_frames_gen == 0)
239 break ;
240
241 if (src_data.input_frames_used > src_data.input_frames)
242 { printf ("\n\nLine %d : input_frames_used > input_frames\n\n", __LINE__) ;
243 printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
244 printf (" src_data.input_frames_used : %ld\n", src_data.input_frames_used) ;
245 printf (" src_data.output_frames : %ld\n", src_data.output_frames) ;
246 printf (" src_data.output_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
247 exit (1) ;
248 } ;
249
250 if (src_data.input_frames_used < 0)
251 { printf ("\n\nLine %d : input_frames_used (%ld) < 0\n\n", __LINE__, src_data.input_frames_used) ;
252 exit (1) ;
253 } ;
254
255 if (src_data.output_frames_gen < 0)
256 { printf ("\n\nLine %d : output_frames_gen (%ld) < 0\n\n", __LINE__, src_data.output_frames_gen) ;
257 exit (1) ;
258 } ;
259
260 current_in += src_data.input_frames_used ;
261 current_out += src_data.output_frames_gen ;
262
263 if (current_in > input_len + terminate)
264 { printf ("\n\nLine %d : current_in (%d) > input_len (%d + %d)\n\n", __LINE__, current_in, input_len, terminate) ;
265 exit (1) ;
266 } ;
267
268 if (current_out > output_len)
269 { printf ("\n\nLine %d : current_out (%d) > output_len (%d)\n\n", __LINE__, current_out, output_len) ;
270 exit (1) ;
271 } ;
272
273 if (src_data.input_frames_used > input_len)
274 { printf ("\n\nLine %d : input_frames_used (%ld) > %d\n\n", __LINE__, src_data.input_frames_used, input_len) ;
275 exit (1) ;
276 } ;
277
278 if (src_data.output_frames_gen > output_len)
279 { printf ("\n\nLine %d : output_frames_gen (%ld) > %d\n\n", __LINE__, src_data.output_frames_gen, output_len) ;
280 exit (1) ;
281 } ;
282
283 if (src_data.data_in == NULL && src_data.output_frames_gen == 0)
284 break ;
285
286
287 src_data.data_in += src_data.input_frames_used ;
288 src_data.data_out += src_data.output_frames_gen ;
289 } ;
290
291 src_state = src_delete (src_state) ;
292
293 if (fabs (current_out - src_ratio * input_len) > terminate)
294 { printf ("\n\nLine %d : bad output data length %d should be %2.1f +/- %d.\n", __LINE__,
295 current_out, src_ratio * input_len, terminate) ;
296 printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
297 printf ("\tinput_len : %d\n\tinput_used : %d\n", input_len, current_in) ;
298 printf ("\toutput_len : %d\n\toutput_gen : %d\n\n", output_len, current_out) ;
299 exit (1) ;
300 } ;
301
302 if (current_in != input_len)
303 { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
304 printf ("\tinput_len : %d\n", input_len) ;
305 printf ("\tinput_frames_used : %d\n\n", current_in) ;
306 exit (1) ;
307 } ;
308
309 puts ("ok") ;
310
311 return ;
312} /* stream_test */
313
314static int
315next_block_length (int reset)
316{ static int block_lengths [] = /* Should be an odd length. */
317 { /*-2, 500, 5, 400, 10, 300, 20, 200, 50, 100, 70 -*/
318 5, 400, 10, 300, 20, 200, 50, 100, 70
319 } ;
320 static int block_len_index = 0 ;
321
322 if (reset)
323 block_len_index = 0 ;
324 else
325 block_len_index = (block_len_index + 1) % ARRAY_LEN (block_lengths) ;
326
327 return block_lengths [block_len_index] ;
328} /* next_block_length */
329
This page took 0.02847 seconds and 4 git commands to generate.