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