annotate src/libsamplerate-0.1.9/tests/termination_test.c @ 83:ae30d91d2ffe

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