comparison src/libsndfile-1.0.27/tests/pcm_test.tpl @ 125:cd6cdf86811e

Current libsndfile source
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 18 Oct 2016 13:22:47 +0100
parents
children
comparison
equal deleted inserted replaced
124:e3d5853d5918 125:cd6cdf86811e
1 [+ AutoGen5 template c +]
2 /*
3 ** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #include "sfconfig.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 #include <inttypes.h>
27
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #include <sndfile.h>
33
34 #include "utils.h"
35
36 #define BUFFER_SIZE (1 << 12)
37
38 static void lrintf_test (void) ;
39
40 [+ FOR data_type
41 +]static void pcm_test_[+ (get "name") +] (const char *filename, int filetype, uint64_t hash) ;
42 [+ ENDFOR data_type
43 +]
44 static void pcm_test_float (const char *filename, int filetype, uint64_t hash, int replace_float) ;
45 static void pcm_test_double (const char *filename, int filetype, uint64_t hash, int replace_float) ;
46
47 typedef union
48 { double d [BUFFER_SIZE + 1] ;
49 float f [BUFFER_SIZE + 1] ;
50 int i [BUFFER_SIZE + 1] ;
51 short s [BUFFER_SIZE + 1] ;
52 } BUFFER ;
53
54 /* Data written to the file. */
55 static BUFFER data_out ;
56
57 /* Data read back from the file. */
58 static BUFFER data_in ;
59
60 int
61 main (void)
62 {
63 lrintf_test () ;
64
65 pcm_test_bits_8 ("pcm-s8.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_S8, 0xa335091249dbfLL) ;
66 pcm_test_bits_8 ("pcm-u8.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_U8, 0x48c433d695f3fLL) ;
67
68 pcm_test_bits_16 ("le-pcm16.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_16, 0xb956c881ebf08LL) ;
69 pcm_test_bits_16 ("be-pcm16.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_16, 0x2f840c55750f8LL) ;
70
71 pcm_test_bits_24 ("le-pcm24.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_24, 0xb6a759ab496f8LL) ;
72 pcm_test_bits_24 ("be-pcm24.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_24, 0xf3eaf9c30b6f8LL) ;
73
74 pcm_test_bits_32 ("le-pcm32.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_32, 0xaece1c1c17f08LL) ;
75 pcm_test_bits_32 ("be-pcm32.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_32, 0x9ddf142d0b0f8LL) ;
76
77 /* Lite remove start */
78 pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0xad04f7554267aLL, SF_FALSE) ;
79 pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0xde3e248fa9186LL, SF_FALSE) ;
80
81 pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0x2726f958f669cLL, SF_FALSE) ;
82 pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0x3583f8ee51164LL, SF_FALSE) ;
83
84 pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0xad04f7554267aLL, SF_TRUE) ;
85 pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0xde3e248fa9186LL, SF_TRUE) ;
86
87 pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0x2726f958f669cLL, SF_TRUE) ;
88 pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0x3583f8ee51164LL, SF_TRUE) ;
89 /* Lite remove end */
90
91 return 0 ;
92 } /* main */
93
94 /*============================================================================================
95 ** Here are the test functions.
96 */
97
98 static void
99 lrintf_test (void)
100 { int k, items ;
101 float *float_data ;
102 int *int_data ;
103
104 print_test_name ("lrintf_test", "") ;
105
106 items = 1024 ;
107
108 float_data = data_out.f ;
109 int_data = data_in.i ;
110
111 for (k = 0 ; k < items ; k++)
112 float_data [k] = (k * ((k % 2) ? 333333.0 : -333333.0)) ;
113
114 for (k = 0 ; k < items ; k++)
115 int_data [k] = lrintf (float_data [k]) ;
116
117 for (k = 0 ; k < items ; k++)
118 if (fabs (int_data [k] - float_data [k]) > 1.0)
119 { printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %d).\n", __LINE__, k, float_data [k], int_data [k]) ;
120 exit (1) ;
121 } ;
122
123 printf ("ok\n") ;
124 } /* lrintf_test */
125
126 [+ FOR data_type
127 +]static void
128 pcm_test_[+ (get "name") +] (const char *filename, int filetype, uint64_t hash)
129 { SNDFILE *file ;
130 SF_INFO sfinfo ;
131 int k, items, zero_count ;
132 short *short_out, *short_in ;
133 int *int_out, *int_in ;
134 /* Lite remove start */
135 float *float_out, *float_in ;
136 double *double_out, *double_in ;
137 /* Lite remove end */
138
139 print_test_name ("pcm_test_[+ (get "name") +]", filename) ;
140
141 items = [+ (get "item_count") +] ;
142
143 short_out = data_out.s ;
144 short_in = data_in.s ;
145
146 zero_count = 0 ;
147 for (k = 0 ; k < items ; k++)
148 { short_out [k] = [+ (get "short_func") +] ;
149 zero_count = short_out [k] ? zero_count : zero_count + 1 ;
150 } ;
151
152 if (zero_count > items / 4)
153 { printf ("\n\nLine %d: too many zeros.\n", __LINE__) ;
154 exit (1) ;
155 } ;
156
157 sfinfo.samplerate = 44100 ;
158 sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
159 sfinfo.channels = 1 ;
160 sfinfo.format = filetype ;
161
162 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
163
164 test_write_short_or_die (file, 0, short_out, items, __LINE__) ;
165
166 sf_close (file) ;
167
168 memset (short_in, 0, items * sizeof (short)) ;
169
170 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
171
172 if (sfinfo.format != filetype)
173 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
174 exit (1) ;
175 } ;
176
177 if (sfinfo.frames != items)
178 { printf ("\n\nLine %d: Incorrect number of frames in file. (%d => %" PRId64 ")\n", __LINE__, items, sfinfo.frames) ;
179 exit (1) ;
180 } ;
181
182 if (sfinfo.channels != 1)
183 { printf ("\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
184 exit (1) ;
185 } ;
186
187 check_log_buffer_or_die (file, __LINE__) ;
188
189 test_read_short_or_die (file, 0, short_in, items, __LINE__) ;
190
191 for (k = 0 ; k < items ; k++)
192 if (short_out [k] != short_in [k])
193 { printf ("\n\nLine %d: Incorrect sample (#%d : 0x%x => 0x%x).\n", __LINE__, k, short_out [k], short_in [k]) ;
194 exit (1) ;
195 } ;
196
197 sf_close (file) ;
198
199 /* Finally, check the file hash. */
200 check_file_hash_or_die (filename, hash, __LINE__) ;
201
202 /*--------------------------------------------------------------------------
203 ** Test sf_read/write_int ()
204 */
205 zero_count = 0 ;
206
207 int_out = data_out.i ;
208 int_in = data_in.i ;
209 for (k = 0 ; k < items ; k++)
210 { int_out [k] = [+ (get "int_func") +] ;
211 zero_count = int_out [k] ? zero_count : zero_count + 1 ;
212 } ;
213
214 if (zero_count > items / 4)
215 { printf ("\n\nLine %d: too many zeros.\n", __LINE__) ;
216 exit (1) ;
217 } ;
218
219 sfinfo.samplerate = 44100 ;
220 sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
221 sfinfo.channels = 1 ;
222 sfinfo.format = filetype ;
223
224 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
225
226 test_write_int_or_die (file, 0, int_out, items, __LINE__) ;
227
228 sf_close (file) ;
229
230 memset (int_in, 0, items * sizeof (int)) ;
231
232 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
233
234 if (sfinfo.format != filetype)
235 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
236 exit (1) ;
237 } ;
238
239 if (sfinfo.frames != items)
240 { printf ("\n\nLine %d: Incorrect number of frames in file. (%d => %" PRId64 ")\n", __LINE__, items, sfinfo.frames) ;
241 exit (1) ;
242 } ;
243
244 if (sfinfo.channels != 1)
245 { printf ("\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
246 exit (1) ;
247 } ;
248
249 check_log_buffer_or_die (file, __LINE__) ;
250
251 test_read_int_or_die (file, 0, int_in, items, __LINE__) ;
252
253 for (k = 0 ; k < items ; k++)
254 if (int_out [k] != int_in [k])
255 { printf ("\n\nLine %d: int : Incorrect sample (#%d : 0x%x => 0x%x).\n", __LINE__, k, int_out [k], int_in [k]) ;
256 exit (1) ;
257 } ;
258
259 sf_close (file) ;
260
261 /* Lite remove start */
262 /*--------------------------------------------------------------------------
263 ** Test sf_read/write_float ()
264 */
265 zero_count = 0 ;
266
267 float_out = data_out.f ;
268 float_in = data_in.f ;
269 for (k = 0 ; k < items ; k++)
270 { float_out [k] = [+ (get "float_func") +] ;
271 zero_count = (fabs (float_out [k]) > 1e-10) ? zero_count : zero_count + 1 ;
272 } ;
273
274 if (zero_count > items / 4)
275 { printf ("\n\nLine %d: too many zeros (%d/%d).\n", __LINE__, zero_count, items) ;
276 exit (1) ;
277 } ;
278
279 sfinfo.samplerate = 44100 ;
280 sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
281 sfinfo.channels = 1 ;
282 sfinfo.format = filetype ;
283
284 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
285
286 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
287
288 test_write_float_or_die (file, 0, float_out, items, __LINE__) ;
289
290 sf_close (file) ;
291
292 memset (float_in, 0, items * sizeof (float)) ;
293
294 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
295
296 if (sfinfo.format != filetype)
297 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
298 exit (1) ;
299 } ;
300
301 if (sfinfo.frames != items)
302 { printf ("\n\nLine %d: Incorrect number of frames in file. (%d => %" PRId64 ")\n", __LINE__, items, sfinfo.frames) ;
303 exit (1) ;
304 } ;
305
306 if (sfinfo.channels != 1)
307 { printf ("\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
308 exit (1) ;
309 } ;
310
311 check_log_buffer_or_die (file, __LINE__) ;
312
313 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
314
315 test_read_float_or_die (file, 0, float_in, items, __LINE__) ;
316
317 for (k = 0 ; k < items ; k++)
318 if (fabs (float_out [k] - float_in [k]) > 1e-10)
319 { printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
320 exit (1) ;
321 } ;
322
323 sf_close (file) ;
324
325 /*--------------------------------------------------------------------------
326 ** Test sf_read/write_double ()
327 */
328 zero_count = 0 ;
329
330 double_out = data_out.d ;
331 double_in = data_in.d ;
332 for (k = 0 ; k < items ; k++)
333 { double_out [k] = [+ (get "float_func") +] ;
334 zero_count = (fabs (double_out [k]) > 1e-10) ? zero_count : zero_count + 1 ;
335 } ;
336
337 if (zero_count > items / 4)
338 { printf ("\n\nLine %d: too many zeros (%d/%d).\n", __LINE__, zero_count, items) ;
339 exit (1) ;
340 } ;
341
342 sfinfo.samplerate = 44100 ;
343 sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
344 sfinfo.channels = 1 ;
345 sfinfo.format = filetype ;
346
347 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
348
349 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
350
351 test_write_double_or_die (file, 0, double_out, items, __LINE__) ;
352
353 sf_close (file) ;
354
355 memset (double_in, 0, items * sizeof (double)) ;
356
357 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
358
359 if (sfinfo.format != filetype)
360 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
361 exit (1) ;
362 } ;
363
364 if (sfinfo.frames != items)
365 { printf ("\n\nLine %d: Incorrect number of frames in file. (%d => %" PRId64 ")\n", __LINE__, items, sfinfo.frames) ;
366 exit (1) ;
367 } ;
368
369 if (sfinfo.channels != 1)
370 { printf ("\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
371 exit (1) ;
372 } ;
373
374 check_log_buffer_or_die (file, __LINE__) ;
375
376 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
377
378 test_read_double_or_die (file, 0, double_in, items, __LINE__) ;
379
380 for (k = 0 ; k < items ; k++)
381 if (fabs (double_out [k] - double_in [k]) > 1e-10)
382 { printf ("\n\nLine %d: double : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, double_out [k], double_in [k]) ;
383 exit (1) ;
384 } ;
385
386 sf_close (file) ;
387 /* Lite remove end */
388 unlink (filename) ;
389
390 puts ("ok") ;
391 } /* pcm_test_[+ (get "name") +] */
392
393 [+ ENDFOR data_type
394 +]
395
396 /*==============================================================================
397 */
398
399 static void
400 pcm_test_float (const char *filename, int filetype, uint64_t hash, int replace_float)
401 { SNDFILE *file ;
402 SF_INFO sfinfo ;
403 int k, items, frames ;
404 int sign ;
405 double *data, error ;
406
407 print_test_name (replace_float ? "pcm_test_float (replace)" : "pcm_test_float", filename) ;
408
409 items = BUFFER_SIZE ;
410
411 data = data_out.d ;
412 for (sign = 1, k = 0 ; k < items ; k++)
413 { data [k] = ((double) (k * sign)) / 100.0 ;
414 sign = (sign > 0) ? -1 : 1 ;
415 } ;
416
417 sfinfo.samplerate = 44100 ;
418 sfinfo.frames = items ;
419 sfinfo.channels = 1 ;
420 sfinfo.format = filetype ;
421
422 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
423 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
424 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
425 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
426 dump_log_buffer (file) ;
427 exit (1) ;
428 } ;
429
430 test_write_double_or_die (file, 0, data, items, __LINE__) ;
431
432 sf_close (file) ;
433
434 check_file_hash_or_die (filename, hash, __LINE__) ;
435
436 memset (data, 0, items * sizeof (double)) ;
437
438 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
439 memset (&sfinfo, 0, sizeof (sfinfo)) ;
440
441 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
442 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
443 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
444 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
445 dump_log_buffer (file) ;
446 exit (1) ;
447 } ;
448
449 if (sfinfo.format != filetype)
450 { printf ("\n\nError (%s:%d) Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __FILE__, __LINE__, filetype, sfinfo.format) ;
451 exit (1) ;
452 } ;
453
454 if (sfinfo.frames != items)
455 { printf ("\n\nError (%s:%d) Mono : Incorrect number of frames in file. (%d => %" PRId64 ")\n", __FILE__, __LINE__, items, sfinfo.frames) ;
456 exit (1) ;
457 } ;
458
459 if (sfinfo.channels != 1)
460 { printf ("\n\nError (%s:%d) Mono : Incorrect number of channels in file.\n", __FILE__, __LINE__) ;
461 exit (1) ;
462 } ;
463
464 check_log_buffer_or_die (file, __LINE__) ;
465
466 test_read_double_or_die (file, 0, data, items, __LINE__) ;
467
468 for (sign = -1, k = 0 ; k < items ; k++)
469 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
470 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
471 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
472 exit (1) ;
473 } ;
474 } ;
475
476 /* Seek to end of file. */
477 test_seek_or_die (file, 0, SEEK_END, sfinfo.frames, sfinfo.channels, __LINE__) ;
478
479 /* Seek to start of file. */
480 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
481
482 test_read_double_or_die (file, 0, data, 4, __LINE__) ;
483 for (k = 0 ; k < 4 ; k++)
484 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
485 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
486 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
487 exit (1) ;
488 } ;
489 } ;
490
491 /* Seek to offset from start of file. */
492 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
493
494 test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
495 for (k = 10 ; k < 14 ; k++)
496 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
497 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
498 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
499 exit (1) ;
500 } ;
501 } ;
502
503 /* Seek to offset from current position. */
504 test_seek_or_die (file, 6, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
505
506 test_read_double_or_die (file, 0, data + 20, 4, __LINE__) ;
507 for (k = 20 ; k < 24 ; k++)
508 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
509 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
510 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
511 exit (1) ;
512 } ;
513 } ;
514
515 /* Seek to offset from end of file. */
516 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
517
518 test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
519 for (k = 10 ; k < 14 ; k++)
520 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
521 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
522 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
523 exit (1) ;
524 } ;
525 } ;
526
527 sf_close (file) ;
528
529 /* Now test Stereo. */
530
531 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_SVX) /* SVX is mono only */
532 { printf ("ok\n") ;
533 return ;
534 } ;
535
536 items = BUFFER_SIZE ;
537
538 data = data_out.d ;
539 for (sign = -1, k = 0 ; k < items ; k++)
540 data [k] = ((double) k) / 100.0 * (sign *= -1) ;
541
542 sfinfo.samplerate = 44100 ;
543 sfinfo.frames = items ;
544 sfinfo.channels = 2 ;
545 sfinfo.format = filetype ;
546
547 frames = items / sfinfo.channels ;
548
549 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
550 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
551 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
552 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
553 dump_log_buffer (file) ;
554 exit (1) ;
555 } ;
556
557 test_writef_double_or_die (file, 0, data, frames, __LINE__) ;
558
559 sf_close (file) ;
560
561 check_file_hash_or_die (filename, hash, __LINE__) ;
562
563 memset (data, 0, items * sizeof (double)) ;
564
565 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
566 memset (&sfinfo, 0, sizeof (sfinfo)) ;
567
568 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
569 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
570 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
571 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
572 dump_log_buffer (file) ;
573 exit (1) ;
574 } ;
575
576 if (sfinfo.format != filetype)
577 { printf ("\n\nError (%s:%d) Stereo : Returned format incorrect (0x%08X => 0x%08X).\n", __FILE__, __LINE__, filetype, sfinfo.format) ;
578 exit (1) ;
579 } ;
580
581 if (sfinfo.frames != frames)
582 { printf ("\n\nError (%s:%d) Stereo : Incorrect number of frames in file. (%d => %" PRId64 ")\n", __FILE__, __LINE__, frames, sfinfo.frames) ;
583 exit (1) ;
584 } ;
585
586 if (sfinfo.channels != 2)
587 { printf ("\n\nError (%s:%d) Stereo : Incorrect number of channels in file.\n", __FILE__, __LINE__) ;
588 exit (1) ;
589 } ;
590
591 check_log_buffer_or_die (file, __LINE__) ;
592
593 test_readf_double_or_die (file, 0, data, frames, __LINE__) ;
594 for (sign = -1, k = 0 ; k < items ; k++)
595 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
596 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
597 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
598 exit (1) ;
599 } ;
600 } ;
601
602 /* Seek to start of file. */
603 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
604
605 test_readf_double_or_die (file, 0, data, 4, __LINE__) ;
606 for (k = 0 ; k < 4 ; k++)
607 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
608 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
609 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
610 exit (1) ;
611 } ;
612 } ;
613
614 /* Seek to offset from start of file. */
615 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
616
617 test_readf_double_or_die (file, 0, data + 20, 2, __LINE__) ;
618 for (k = 20 ; k < 24 ; k++)
619 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
620 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
621 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
622 exit (1) ;
623 } ;
624 } ;
625
626 /* Seek to offset from current position. */
627 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
628
629 test_readf_double_or_die (file, 0, data + 40, 2, __LINE__) ;
630 for (k = 40 ; k < 44 ; k++)
631 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
632 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
633 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
634 exit (1) ;
635 } ;
636 } ;
637
638 /* Seek to offset from end of file. */
639 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
640
641 test_readf_double_or_die (file, 0, data + 20, 2, __LINE__) ;
642 for (k = 20 ; k < 24 ; k++)
643 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
644 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
645 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
646 exit (1) ;
647 } ;
648 } ;
649
650 sf_close (file) ;
651
652 printf ("ok\n") ;
653 unlink (filename) ;
654 } /* pcm_test_float */
655
656 static void
657 pcm_test_double (const char *filename, int filetype, uint64_t hash, int replace_float)
658 { SNDFILE *file ;
659 SF_INFO sfinfo ;
660 int k, items, frames ;
661 int sign ;
662 double *data, error ;
663
664 /* This is the best test routine. Other should be brought up to this standard. */
665
666 print_test_name (replace_float ? "pcm_test_double (replace)" : "pcm_test_double", filename) ;
667
668 items = BUFFER_SIZE ;
669
670 data = data_out.d ;
671 for (sign = 1, k = 0 ; k < items ; k++)
672 { data [k] = ((double) (k * sign)) / 100.0 ;
673 sign = (sign > 0) ? -1 : 1 ;
674 } ;
675
676 sfinfo.samplerate = 44100 ;
677 sfinfo.frames = items ;
678 sfinfo.channels = 1 ;
679 sfinfo.format = filetype ;
680
681 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
682 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
683 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
684 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
685 dump_log_buffer (file) ;
686 exit (1) ;
687 } ;
688
689 test_write_double_or_die (file, 0, data, items, __LINE__) ;
690
691 sf_close (file) ;
692
693 #if (defined (WIN32) || defined (_WIN32))
694 /* File hashing on Win32 fails due to slighty different
695 ** calculated values of the sin() function.
696 */
697 hash = hash ; /* Avoid compiler warning. */
698 #else
699 check_file_hash_or_die (filename, hash, __LINE__) ;
700 #endif
701
702 memset (data, 0, items * sizeof (double)) ;
703
704 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
705 memset (&sfinfo, 0, sizeof (sfinfo)) ;
706
707 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
708 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
709 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
710 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
711 dump_log_buffer (file) ;
712 exit (1) ;
713 } ;
714
715 if (sfinfo.format != filetype)
716 { printf ("\n\nError (%s:%d) Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __FILE__, __LINE__, filetype, sfinfo.format) ;
717 exit (1) ;
718 } ;
719
720 if (sfinfo.frames != items)
721 { printf ("\n\nError (%s:%d) Mono : Incorrect number of frames in file. (%d => %" PRId64 ")\n", __FILE__, __LINE__, items, sfinfo.frames) ;
722 exit (1) ;
723 } ;
724
725 if (sfinfo.channels != 1)
726 { printf ("\n\nError (%s:%d) Mono : Incorrect number of channels in file.\n", __FILE__, __LINE__) ;
727 exit (1) ;
728 } ;
729
730 check_log_buffer_or_die (file, __LINE__) ;
731
732 test_read_double_or_die (file, 0, data, items, __LINE__) ;
733
734 for (sign = -1, k = 0 ; k < items ; k++)
735 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
736 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
737 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
738 exit (1) ;
739 } ;
740 } ;
741
742 /* Seek to start of file. */
743 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
744
745 test_read_double_or_die (file, 0, data, 4, __LINE__) ;
746 for (k = 0 ; k < 4 ; k++)
747 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
748 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
749 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
750 exit (1) ;
751 } ;
752 } ;
753
754 /* Seek to offset from start of file. */
755 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
756
757 test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
758
759 test_seek_or_die (file, 0, SEEK_CUR, 14, sfinfo.channels, __LINE__) ;
760
761 for (k = 10 ; k < 14 ; k++)
762 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
763 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
764 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
765 exit (1) ;
766 } ;
767 } ;
768
769 /* Seek to offset from current position. */
770 test_seek_or_die (file, 6, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
771
772 test_read_double_or_die (file, 0, data + 20, 4, __LINE__) ;
773 for (k = 20 ; k < 24 ; k++)
774 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
775 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
776 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
777 exit (1) ;
778 } ;
779 } ;
780
781 /* Seek to offset from end of file. */
782 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
783
784 test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
785 for (k = 10 ; k < 14 ; k++)
786 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
787 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
788 { printf ("\n\nError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
789 exit (1) ;
790 } ;
791 } ;
792
793 sf_close (file) ;
794
795 /* Now test Stereo. */
796
797 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_SVX) /* SVX is mono only */
798 { printf ("ok\n") ;
799 return ;
800 } ;
801
802 items = BUFFER_SIZE ;
803
804 data = data_out.d ;
805 for (sign = -1, k = 0 ; k < items ; k++)
806 data [k] = ((double) k) / 100.0 * (sign *= -1) ;
807
808 sfinfo.samplerate = 44100 ;
809 sfinfo.frames = items ;
810 sfinfo.channels = 2 ;
811 sfinfo.format = filetype ;
812
813 frames = items / sfinfo.channels ;
814
815 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
816 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
817 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
818 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
819 dump_log_buffer (file) ;
820 exit (1) ;
821 } ;
822
823 test_writef_double_or_die (file, 0, data, frames, __LINE__) ;
824
825 sf_close (file) ;
826
827 #if (defined (WIN32) || defined (_WIN32))
828 /* File hashing on Win32 fails due to slighty different
829 ** calculated values.
830 */
831 hash = hash ; /* Avoid compiler warning. */
832 #else
833 check_file_hash_or_die (filename, hash, __LINE__) ;
834 #endif
835
836 memset (data, 0, items * sizeof (double)) ;
837
838 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
839 memset (&sfinfo, 0, sizeof (sfinfo)) ;
840
841 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
842 sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
843 if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
844 { printf ("\n\nLine %d : Float replacement code not working.\n\n", __LINE__) ;
845 dump_log_buffer (file) ;
846 exit (1) ;
847 } ;
848
849 if (sfinfo.format != filetype)
850 { printf ("\n\nError (%s:%d) Stereo : Returned format incorrect (0x%08X => 0x%08X).\n", __FILE__, __LINE__, filetype, sfinfo.format) ;
851 exit (1) ;
852 } ;
853
854 if (sfinfo.frames != frames)
855 { printf ("\n\nError (%s:%d) Stereo : Incorrect number of frames in file. (%d => %" PRId64 ")\n", __FILE__, __LINE__, frames, sfinfo.frames) ;
856 exit (1) ;
857 } ;
858
859 if (sfinfo.channels != 2)
860 { printf ("\n\nError (%s:%d) Stereo : Incorrect number of channels in file.\n", __FILE__, __LINE__) ;
861 exit (1) ;
862 } ;
863
864 check_log_buffer_or_die (file, __LINE__) ;
865
866 test_readf_double_or_die (file, 0, data, frames, __LINE__) ;
867
868 for (sign = -1, k = 0 ; k < items ; k++)
869 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
870 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
871 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
872 exit (1) ;
873 } ;
874 } ;
875
876 /* Seek to start of file. */
877 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
878
879 test_read_double_or_die (file, 0, data, 4, __LINE__) ;
880 for (k = 0 ; k < 4 ; k++)
881 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
882 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
883 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
884 exit (1) ;
885 } ;
886 } ;
887
888 /* Seek to offset from start of file. */
889 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
890
891 test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
892 for (k = 20 ; k < 24 ; k++)
893 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
894 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
895 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
896 exit (1) ;
897 } ;
898 } ;
899
900 /* Seek to offset from current position. */
901 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
902
903 test_readf_double_or_die (file, 0, data + 40, 4, __LINE__) ;
904 for (k = 40 ; k < 44 ; k++)
905 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
906 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
907 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
908 exit (1) ;
909 } ;
910 } ;
911
912 /* Seek to offset from end of file. */
913 test_seek_or_die (file, -1 * (sfinfo.frames -10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
914
915 test_readf_double_or_die (file, 0, data + 20, 4, __LINE__) ;
916 for (k = 20 ; k < 24 ; k++)
917 { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
918 if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
919 { printf ("\n\nError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).\n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
920 exit (1) ;
921 } ;
922 } ;
923
924 sf_close (file) ;
925
926 printf ("ok\n") ;
927 unlink (filename) ;
928 } /* pcm_test_double */
929
930 /*==============================================================================
931 */