2 ** Copyright (C) 2001-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #define BUFFER_LEN (1 << 10)
39 #define LOG_BUFFER_SIZE 1024
41 static void float_norm_test (const char *filename) ;
42 static void double_norm_test (const char *filename) ;
43 static void format_tests (void) ;
44 static void calc_peak_test (int filetype, const char *filename, int channels) ;
45 static void truncate_test (const char *filename, int filetype) ;
46 static void instrument_test (const char *filename, int filetype) ;
47 static void channel_map_test (const char *filename, int filetype) ;
48 static void current_sf_info_test (const char *filename) ;
49 static void raw_needs_endswap_test (const char *filename, int filetype) ;
51 static void broadcast_test (const char *filename, int filetype) ;
52 static void broadcast_rdwr_test (const char *filename, int filetype) ;
53 static void broadcast_coding_history_test (const char *filename) ;
54 static void broadcast_coding_history_size (const char *filename) ;
56 /* Cart Chunk tests */
57 static void cart_test (const char *filename, int filetype) ;
58 static void cart_rdwr_test (const char *filename, int filetype) ;
60 /* Force the start of this buffer to be double aligned. Sparc-solaris will
64 static int int_data [BUFFER_LEN] ;
65 static float float_data [BUFFER_LEN] ;
66 static double double_data [BUFFER_LEN] ;
69 main (int argc, char *argv [])
74 { printf ("Usage : %s <test>\n", argv [0]) ;
75 printf (" Where <test> is one of the following:\n") ;
76 printf (" ver - test sf_command (SFC_GETLIB_VERSION)\n") ;
77 printf (" norm - test floating point normalisation\n") ;
78 printf (" format - test format string commands\n") ;
79 printf (" peak - test peak calculation\n") ;
80 printf (" trunc - test file truncation\n") ;
81 printf (" inst - test set/get of SF_INSTRUMENT.\n") ;
82 printf (" chanmap - test set/get of channel map data..\n") ;
83 printf (" bext - test set/get of SF_BROADCAST_INFO.\n") ;
84 printf (" bextch - test set/get of SF_BROADCAST_INFO coding_history.\n") ;
85 printf (" cart - test set/get of SF_CART_INFO.\n") ;
86 printf (" rawend - test SFC_RAW_NEEDS_ENDSWAP.\n") ;
87 printf (" all - perform all tests\n") ;
91 do_all = ! strcmp (argv [1], "all") ;
93 if (do_all || strcmp (argv [1], "ver") == 0)
96 print_test_name ("version_test", "(none)") ;
98 sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
99 if (strlen (buffer) < 1)
100 { printf ("Line %d: could not retrieve lib version.\n", __LINE__) ;
107 if (do_all || strcmp (argv [1], "norm") == 0)
108 { /* Preliminary float/double normalisation tests. More testing
109 ** is done in the program 'floating_point_test'.
111 float_norm_test ("float.wav") ;
112 double_norm_test ("double.wav") ;
116 if (do_all || strcmp (argv [1], "peak") == 0)
117 { calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw", 1) ;
118 calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw", 1) ;
119 calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw", 7) ;
120 calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw", 7) ;
124 if (do_all || ! strcmp (argv [1], "format"))
129 if (do_all || strcmp (argv [1], "trunc") == 0)
130 { truncate_test ("truncate.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_32) ;
131 truncate_test ("truncate.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16) ;
135 if (do_all || strcmp (argv [1], "inst") == 0)
136 { instrument_test ("instrument.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
137 instrument_test ("instrument.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ;
138 /*-instrument_test ("instrument.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16) ;-*/
142 if (do_all || strcmp (argv [1], "current_sf_info") == 0)
143 { current_sf_info_test ("current.wav") ;
147 if (do_all || strcmp (argv [1], "bext") == 0)
148 { broadcast_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
149 broadcast_rdwr_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
151 broadcast_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
152 broadcast_rdwr_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
154 broadcast_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
155 broadcast_rdwr_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
159 if (do_all || strcmp (argv [1], "cart") == 0)
160 { cart_test ("cart.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
161 cart_rdwr_test ("cart.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
162 cart_test ("cart.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
163 cart_rdwr_test ("cart.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
167 if (do_all || strcmp (argv [1], "bextch") == 0)
168 { broadcast_coding_history_test ("coding_history.wav") ;
169 broadcast_coding_history_size ("coding_hist_size.wav") ;
173 if (do_all || strcmp (argv [1], "chanmap") == 0)
174 { channel_map_test ("chanmap.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
175 channel_map_test ("chanmap.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
176 channel_map_test ("chanmap.aifc" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
177 channel_map_test ("chanmap.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16) ;
181 if (do_all || strcmp (argv [1], "rawend") == 0)
182 { raw_needs_endswap_test ("raw_end.wav", SF_FORMAT_WAV) ;
183 raw_needs_endswap_test ("raw_end.wavex", SF_FORMAT_WAVEX) ;
184 raw_needs_endswap_test ("raw_end.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
185 raw_needs_endswap_test ("raw_end.aiff", SF_FORMAT_AIFF) ;
186 raw_needs_endswap_test ("raw_end.aiff_le", SF_ENDIAN_LITTLE | SF_FORMAT_AIFF) ;
191 { printf ("Mono : ************************************\n") ;
192 printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
193 printf ("Mono : ************************************\n") ;
200 /*============================================================================================
201 ** Here are the test functions.
205 float_norm_test (const char *filename)
210 print_test_name ("float_norm_test", filename) ;
212 sfinfo.samplerate = 44100 ;
213 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ;
214 sfinfo.channels = 1 ;
215 sfinfo.frames = BUFFER_LEN ;
217 /* Create float_data with all values being less than 1.0. */
218 for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
219 float_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ;
220 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++)
221 float_data [k] = (k + 5) ;
223 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
224 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ;
226 puts (sf_strerror (NULL)) ;
230 /* Normalisation is on by default so no need to do anything here. */
232 if ((k = sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
233 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
237 /* Turn normalisation off. */
238 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
240 if ((k = sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
241 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
247 /* sfinfo struct should still contain correct data. */
248 if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
249 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ;
251 puts (sf_strerror (NULL)) ;
255 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16))
256 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ;
260 if (sfinfo.frames != BUFFER_LEN)
261 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %" PRId64 ")\n", __LINE__, BUFFER_LEN, sfinfo.frames) ;
265 if (sfinfo.channels != 1)
266 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ;
270 /* Read float_data and check that it is normalised (ie default). */
271 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
272 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
276 for (k = 0 ; k < BUFFER_LEN ; k++)
277 if (float_data [k] >= 1.0)
278 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ;
282 /* Seek to start of file, turn normalisation off, read float_data and check again. */
283 sf_seek (file, 0, SEEK_SET) ;
284 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
286 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
287 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
291 for (k = 0 ; k < BUFFER_LEN ; k++)
292 if (float_data [k] < 1.0)
293 { printf ("\n\nLine %d: float_data [%d] == %f which is less than 1.0\n", __LINE__, k, float_data [k]) ;
297 /* Seek to start of file, turn normalisation on, read float_data and do final check. */
298 sf_seek (file, 0, SEEK_SET) ;
299 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE) ;
301 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
302 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
306 for (k = 0 ; k < BUFFER_LEN ; k++)
307 if (float_data [k] > 1.0)
308 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ;
318 } /* float_norm_test */
321 double_norm_test (const char *filename)
326 print_test_name ("double_norm_test", filename) ;
328 sfinfo.samplerate = 44100 ;
329 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ;
330 sfinfo.channels = 1 ;
331 sfinfo.frames = BUFFER_LEN ;
333 /* Create double_data with all values being less than 1.0. */
334 for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
335 double_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ;
336 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++)
337 double_data [k] = (k + 5) ;
339 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
340 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ;
342 puts (sf_strerror (NULL)) ;
346 /* Normailsation is on by default so no need to do anything here. */
347 /*-sf_command (file, "set-norm-double", "true", 0) ;-*/
349 if ((k = sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
350 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
354 /* Turn normalisation off. */
355 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
357 if ((k = sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
358 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
364 if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
365 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ;
367 puts (sf_strerror (NULL)) ;
371 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16))
372 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ;
376 if (sfinfo.frames != BUFFER_LEN)
377 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %" PRId64 ")\n", __LINE__, BUFFER_LEN, sfinfo.frames) ;
381 if (sfinfo.channels != 1)
382 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ;
386 /* Read double_data and check that it is normalised (ie default). */
387 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
388 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
392 for (k = 0 ; k < BUFFER_LEN ; k++)
393 if (double_data [k] >= 1.0)
394 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ;
398 /* Seek to start of file, turn normalisation off, read double_data and check again. */
399 sf_seek (file, 0, SEEK_SET) ;
400 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
402 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
403 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
407 for (k = 0 ; k < BUFFER_LEN ; k++)
408 if (double_data [k] < 1.0)
409 { printf ("\n\nLine %d: double_data [%d] == %f which is less than 1.0\n", __LINE__, k, double_data [k]) ;
413 /* Seek to start of file, turn normalisation on, read double_data and do final check. */
414 sf_seek (file, 0, SEEK_SET) ;
415 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ;
417 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
418 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
422 for (k = 0 ; k < BUFFER_LEN ; k++)
423 if (double_data [k] > 1.0)
424 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ;
434 } /* double_norm_test */
438 { SF_FORMAT_INFO format_info ;
440 const char *last_name ;
443 print_test_name ("format_tests", "(null)") ;
445 /* Clear out SF_INFO struct and set channels > 0. */
446 memset (&sfinfo, 0, sizeof (sfinfo)) ;
447 sfinfo.channels = 1 ;
449 /* First test simple formats. */
451 sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &count, sizeof (int)) ;
453 if (count < 0 || count > 30)
454 { printf ("Line %d: Weird count.\n", __LINE__) ;
458 format_info.format = 0 ;
459 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
461 last_name = format_info.name ;
462 for (k = 1 ; k < count ; k ++)
463 { format_info.format = k ;
464 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
465 if (strcmp (last_name, format_info.name) >= 0)
466 { printf ("\n\nLine %d: format names out of sequence `%s' < `%s'.\n", __LINE__, last_name, format_info.name) ;
469 sfinfo.format = format_info.format ;
471 if (! sf_format_check (&sfinfo))
472 { printf ("\n\nLine %d: sf_format_check failed.\n", __LINE__) ;
473 printf (" Name : %s\n", format_info.name) ;
474 printf (" Format : 0x%X\n", sfinfo.format) ;
475 printf (" Channels : 0x%X\n", sfinfo.channels) ;
476 printf (" Sample Rate : 0x%X\n", sfinfo.samplerate) ;
479 last_name = format_info.name ;
481 format_info.format = 666 ;
482 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
484 /* Now test major formats. */
485 sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ;
487 if (count < 0 || count > 30)
488 { printf ("Line %d: Weird count.\n", __LINE__) ;
492 format_info.format = 0 ;
493 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
495 last_name = format_info.name ;
496 for (k = 1 ; k < count ; k ++)
497 { format_info.format = k ;
498 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
499 if (strcmp (last_name, format_info.name) >= 0)
500 { printf ("\n\nLine %d: format names out of sequence (%d) `%s' < `%s'.\n", __LINE__, k, last_name, format_info.name) ;
504 last_name = format_info.name ;
506 format_info.format = 666 ;
507 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
509 /* Now test subtype formats. */
510 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ;
512 if (count < 0 || count > 30)
513 { printf ("Line %d: Weird count.\n", __LINE__) ;
517 format_info.format = 0 ;
518 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
520 last_name = format_info.name ;
521 for (k = 1 ; k < count ; k ++)
522 { format_info.format = k ;
523 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
525 format_info.format = 666 ;
526 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
533 calc_peak_test (int filetype, const char *filename, int channels)
538 sf_count_t buffer_len, frame_count ;
541 snprintf (label, sizeof (label), "calc_peak_test (%d channels)", channels) ;
542 print_test_name (label, filename) ;
544 format = filetype | SF_FORMAT_PCM_16 ;
546 buffer_len = BUFFER_LEN - (BUFFER_LEN % channels) ;
547 frame_count = buffer_len / channels ;
549 sfinfo.samplerate = 44100 ;
550 sfinfo.format = format ;
551 sfinfo.channels = channels ;
552 sfinfo.frames = frame_count ;
554 /* Create double_data with max value of 0.5. */
555 for (k = 0 ; k < buffer_len ; k++)
556 double_data [k] = (k + 1) / (2.0 * buffer_len) ;
558 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
560 test_writef_double_or_die (file, 0, double_data, frame_count, __LINE__) ;
564 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
566 if (sfinfo.format != format)
567 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
571 if (sfinfo.frames != frame_count)
572 { printf ("\n\nLine %d: Incorrect number of frames in file. (%" PRId64 " => %" PRId64 ")\n", __LINE__, frame_count, sfinfo.frames) ;
576 if (sfinfo.channels != channels)
577 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ;
581 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ;
582 if (fabs (peak - (1 << 14)) > 1.0)
583 { printf ("Line %d : Peak value should be %d (is %f).\n", __LINE__, (1 << 14), peak) ;
587 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ;
588 if (fabs (peak - 0.5) > 4e-5)
589 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ;
595 format = (filetype | SF_FORMAT_FLOAT) ;
596 sfinfo.samplerate = 44100 ;
597 sfinfo.format = format ;
598 sfinfo.channels = channels ;
599 sfinfo.frames = frame_count ;
601 /* Create double_data with max value of 0.5. */
602 for (k = 0 ; k < buffer_len ; k++)
603 double_data [k] = (k + 1) / (2.0 * buffer_len) ;
605 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
607 test_writef_double_or_die (file, 0, double_data, frame_count, __LINE__) ;
611 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
613 if (sfinfo.format != format)
614 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
618 if (sfinfo.frames != frame_count)
619 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%" PRId64 " => %" PRId64 ")\n", __LINE__, frame_count, sfinfo.frames) ;
623 if (sfinfo.channels != channels)
624 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ;
628 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ;
629 if (fabs (peak - 0.5) > 1e-5)
630 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ;
634 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ;
635 if (fabs (peak - 0.5) > 1e-5)
636 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ;
645 } /* calc_peak_test */
648 truncate_test (const char *filename, int filetype)
653 print_test_name ("truncate_test", filename) ;
655 sfinfo.samplerate = 11025 ;
656 sfinfo.format = filetype ;
657 sfinfo.channels = 2 ;
659 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
661 test_write_int_or_die (file, 0, int_data, BUFFER_LEN, __LINE__) ;
664 if (sf_command (file, SFC_FILE_TRUNCATE, &len, sizeof (len)))
665 { printf ("Line %d: sf_command (SFC_FILE_TRUNCATE) returned error.\n", __LINE__) ;
669 test_seek_or_die (file, 0, SEEK_CUR, len, 2, __LINE__) ;
670 test_seek_or_die (file, 0, SEEK_END, len, 2, __LINE__) ;
676 } /* truncate_test */
678 /*------------------------------------------------------------------------------
682 instrumet_rw_test (const char *filename)
686 memset (&sfinfo, 0, sizeof (SF_INFO)) ;
688 sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
690 if (sf_command (sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
691 { inst.basenote = 22 ;
693 if (sf_command (sndfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
694 printf ("Sucess: [%s] updated\n", filename) ;
696 printf ("Error: SFC_SET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ;
699 printf ("Error: SFC_GET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ;
702 if (sf_command (sndfile, SFC_UPDATE_HEADER_NOW, NULL, 0) != 0)
703 printf ("Error: SFC_UPDATE_HEADER_NOW on [%s] [%s]\n", filename, sf_strerror (sndfile)) ;
705 sf_write_sync (sndfile) ;
709 } /* instrumet_rw_test */
712 instrument_test (const char *filename, int filetype)
713 { static SF_INSTRUMENT write_inst =
717 5, 6, /* key low and high */
718 7, 8, /* velocity low and high */
724 SF_INSTRUMENT read_inst ;
728 print_test_name ("instrument_test", filename) ;
730 sfinfo.samplerate = 11025 ;
731 sfinfo.format = filetype ;
732 sfinfo.channels = 1 ;
734 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
735 if (sf_command (file, SFC_SET_INSTRUMENT, &write_inst, sizeof (write_inst)) == SF_FALSE)
736 { printf ("\n\nLine %d : sf_command (SFC_SET_INSTRUMENT) failed.\n\n", __LINE__) ;
739 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
742 memset (&read_inst, 0, sizeof (read_inst)) ;
744 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
745 if (sf_command (file, SFC_GET_INSTRUMENT, &read_inst, sizeof (read_inst)) == SF_FALSE)
746 { printf ("\n\nLine %d : sf_command (SFC_GET_INSTRUMENT) failed.\n\n", __LINE__) ;
750 check_log_buffer_or_die (file, __LINE__) ;
753 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
755 ** For all the fields that WAV doesn't support, modify the
756 ** write_inst struct to hold the default value that the WAV
757 ** module should hold.
759 write_inst.detune = 0 ;
760 write_inst.key_lo = write_inst.velocity_lo = 0 ;
761 write_inst.key_hi = write_inst.velocity_hi = 127 ;
762 write_inst.gain = 1 ;
765 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI)
767 ** For all the fields that XI doesn't support, modify the
768 ** write_inst struct to hold the default value that the XI
769 ** module should hold.
771 write_inst.basenote = 0 ;
772 write_inst.detune = 0 ;
773 write_inst.key_lo = write_inst.velocity_lo = 0 ;
774 write_inst.key_hi = write_inst.velocity_hi = 127 ;
775 write_inst.gain = 1 ;
778 if (memcmp (&write_inst, &read_inst, sizeof (write_inst)) != 0)
779 { printf ("\n\nLine %d : instrument comparison failed.\n\n", __LINE__) ;
780 printf ("W Base Note : %u\n"
782 " Low Note : %u\tHigh Note : %u\n"
783 " Low Vel. : %u\tHigh Vel. : %u\n"
784 " Gain : %d\tCount : %d\n"
786 " start : %d\tend : %d\tcount :%d\n"
788 " start : %d\tend : %d\tcount :%d\n\n",
791 write_inst.key_lo, write_inst.key_hi,
792 write_inst.velocity_lo, write_inst.velocity_hi,
793 write_inst.gain, write_inst.loop_count,
794 write_inst.loops [0].mode, write_inst.loops [0].start,
795 write_inst.loops [0].end, write_inst.loops [0].count,
796 write_inst.loops [1].mode, write_inst.loops [1].start,
797 write_inst.loops [1].end, write_inst.loops [1].count) ;
798 printf ("R Base Note : %u\n"
800 " Low Note : %u\tHigh Note : %u\n"
801 " Low Vel. : %u\tHigh Vel. : %u\n"
802 " Gain : %d\tCount : %d\n"
804 " start : %d\tend : %d\tcount :%d\n"
806 " start : %d\tend : %d\tcount :%d\n\n",
809 read_inst.key_lo, read_inst.key_hi,
810 read_inst.velocity_lo, read_inst.velocity_hi,
811 read_inst.gain, read_inst.loop_count,
812 read_inst.loops [0].mode, read_inst.loops [0].start,
813 read_inst.loops [0].end, read_inst.loops [0].count,
814 read_inst.loops [1].mode, read_inst.loops [1].start,
815 read_inst.loops [1].end, read_inst.loops [1].count) ;
817 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI)
821 if (0) instrumet_rw_test (filename) ;
825 } /* instrument_test */
828 current_sf_info_test (const char *filename)
829 { SNDFILE *outfile, *infile ;
830 SF_INFO outinfo, ininfo ;
832 print_test_name ("current_sf_info_test", filename) ;
834 outinfo.samplerate = 44100 ;
835 outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
836 outinfo.channels = 1 ;
839 outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ;
840 sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ;
842 exit_if_true (outinfo.frames != 0,
843 "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__
846 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
847 sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ;
849 exit_if_true (outinfo.frames != BUFFER_LEN,
850 "\n\nLine %d : Initial sfinfo.frames (%" PRId64 ") should be %d.\n\n", __LINE__,
851 outinfo.frames, BUFFER_LEN
854 /* Read file making sure no channel map exists. */
855 memset (&ininfo, 0, sizeof (ininfo)) ;
856 infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ;
858 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
860 sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ;
862 exit_if_true (ininfo.frames != BUFFER_LEN,
863 "\n\nLine %d : Initial sfinfo.frames (%" PRId64 ") should be %d.\n\n", __LINE__,
864 ininfo.frames, BUFFER_LEN
872 } /* current_sf_info_test */
875 broadcast_test (const char *filename, int filetype)
876 { static SF_BROADCAST_INFO bc_write, bc_read ;
881 print_test_name ("broadcast_test", filename) ;
883 sfinfo.samplerate = 11025 ;
884 sfinfo.format = filetype ;
885 sfinfo.channels = 1 ;
887 memset (&bc_write, 0, sizeof (bc_write)) ;
889 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
890 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
891 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
892 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
893 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
894 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
895 bc_write.coding_history_size = 0 ;
897 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
898 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
899 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
902 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
905 memset (&bc_read, 0, sizeof (bc_read)) ;
907 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
908 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
909 { printf ("\n\nLine %d : sf_command (SFC_GET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
913 check_log_buffer_or_die (file, __LINE__) ;
916 if (bc_read.version != 1)
917 { printf ("\n\nLine %d : Read bad version number %d.\n\n", __LINE__, bc_read.version) ;
922 bc_read.version = bc_write.version = 0 ;
924 if (memcmp (bc_write.description, bc_read.description, sizeof (bc_write.description)) != 0)
925 { printf ("\n\nLine %d : description mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.description, bc_read.description) ;
929 if (memcmp (bc_write.originator, bc_read.originator, sizeof (bc_write.originator)) != 0)
930 { printf ("\n\nLine %d : originator mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator, bc_read.originator) ;
934 if (memcmp (bc_write.originator_reference, bc_read.originator_reference, sizeof (bc_write.originator_reference)) != 0)
935 { printf ("\n\nLine %d : originator_reference mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator_reference, bc_read.originator_reference) ;
939 if (memcmp (bc_write.origination_date, bc_read.origination_date, sizeof (bc_write.origination_date)) != 0)
940 { printf ("\n\nLine %d : origination_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_date, bc_read.origination_date) ;
944 if (memcmp (bc_write.origination_time, bc_read.origination_time, sizeof (bc_write.origination_time)) != 0)
945 { printf ("\n\nLine %d : origination_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_time, bc_read.origination_time) ;
949 if (memcmp (bc_write.umid, bc_read.umid, sizeof (bc_write.umid)) != 0)
950 { printf ("\n\nLine %d : umid mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.umid, bc_read.umid) ;
959 } /* broadcast_test */
962 broadcast_rdwr_test (const char *filename, int filetype)
963 { SF_BROADCAST_INFO binfo ;
968 print_test_name (__func__, filename) ;
970 create_short_sndfile (filename, filetype, 2) ;
972 memset (&sfinfo, 0, sizeof (sfinfo)) ;
973 memset (&binfo, 0, sizeof (binfo)) ;
975 snprintf (binfo.description, sizeof (binfo.description), "Test description") ;
976 snprintf (binfo.originator, sizeof (binfo.originator), "Test originator") ;
977 snprintf (binfo.originator_reference, sizeof (binfo.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
978 snprintf (binfo.origination_date, sizeof (binfo.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
979 snprintf (binfo.origination_time, sizeof (binfo.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
980 snprintf (binfo.umid, sizeof (binfo.umid), "Some umid") ;
981 binfo.coding_history_size = 0 ;
983 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
984 frames = sfinfo.frames ;
985 if (sf_command (file, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) != SF_FALSE)
986 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) should have failed but didn't.\n\n", __LINE__) ;
991 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
993 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
997 } /* broadcast_rdwr_test */
1000 check_coding_history_newlines (const char *filename)
1001 { static SF_BROADCAST_INFO bc_write, bc_read ;
1006 sfinfo.samplerate = 22050 ;
1007 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
1008 sfinfo.channels = 1 ;
1010 memset (&bc_write, 0, sizeof (bc_write)) ;
1012 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
1013 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
1014 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
1015 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
1016 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
1017 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
1018 bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "This has\nUnix\nand\rMac OS9\rline endings.\nLast line") ; ;
1020 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1021 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
1022 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1026 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1029 memset (&bc_read, 0, sizeof (bc_read)) ;
1031 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1032 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
1033 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1036 check_log_buffer_or_die (file, __LINE__) ;
1039 if (bc_read.coding_history_size == 0)
1040 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ;
1044 if (strstr (bc_read.coding_history, "Last line") == NULL)
1045 { printf ("\n\nLine %d : coding history truncated.\n\n", __LINE__) ;
1049 for (k = 1 ; k < bc_read.coding_history_size ; k++)
1050 { if (bc_read.coding_history [k] == '\n' && bc_read.coding_history [k - 1] != '\r')
1051 { printf ("\n\nLine %d : '\\n' without '\\r' before.\n\n", __LINE__) ;
1055 if (bc_read.coding_history [k] == '\r' && bc_read.coding_history [k + 1] != '\n')
1056 { printf ("\n\nLine %d : '\\r' without '\\n' after.\n\n", __LINE__) ;
1060 if (bc_read.coding_history [k] == 0 && k < bc_read.coding_history_size - 1)
1061 { printf ("\n\nLine %d : '\\0' within coding history at index %d of %d.\n\n", __LINE__, k, bc_read.coding_history_size) ;
1067 } /* check_coding_history_newlines */
1070 broadcast_coding_history_test (const char *filename)
1071 { static SF_BROADCAST_INFO bc_write, bc_read ;
1074 const char *default_history = "A=PCM,F=22050,W=16,M=mono" ;
1075 const char *supplied_history =
1076 "A=PCM,F=44100,W=24,M=mono,T=other\r\n"
1077 "A=PCM,F=22050,W=16,M=mono,T=yet_another\r\n" ;
1079 print_test_name ("broadcast_coding_history_test", filename) ;
1081 sfinfo.samplerate = 22050 ;
1082 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
1083 sfinfo.channels = 1 ;
1085 memset (&bc_write, 0, sizeof (bc_write)) ;
1087 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
1088 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
1089 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
1090 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
1091 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
1092 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
1093 /* Coding history will be filled in by the library. */
1094 bc_write.coding_history_size = 0 ;
1096 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1097 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
1098 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1102 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1105 memset (&bc_read, 0, sizeof (bc_read)) ;
1107 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1108 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
1109 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1112 check_log_buffer_or_die (file, __LINE__) ;
1115 if (bc_read.coding_history_size == 0)
1116 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ;
1120 if (bc_read.coding_history_size < strlen (default_history) || memcmp (bc_read.coding_history, default_history, strlen (default_history)) != 0)
1122 "Line %d : unexpected coding history '%.*s',\n"
1123 " should be '%s'\n\n", __LINE__, bc_read.coding_history_size, bc_read.coding_history, default_history) ;
1127 bc_write.coding_history_size = strlen (supplied_history) ;
1128 bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "%s", supplied_history) ;
1130 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1131 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
1132 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1136 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1139 memset (&bc_read, 0, sizeof (bc_read)) ;
1141 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1142 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
1143 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1147 check_log_buffer_or_die (file, __LINE__) ;
1150 if (strstr (bc_read.coding_history, supplied_history) != bc_read.coding_history)
1151 { printf ("\n\nLine %d : unexpected coding history :\n"
1152 "----------------------------------------------------\n%s"
1153 "----------------------------------------------------\n"
1154 "should be this :\n"
1155 "----------------------------------------------------\n%s"
1156 "----------------------------------------------------\n"
1157 "with one more line at the end.\n\n",
1158 __LINE__, bc_read.coding_history, supplied_history) ;
1162 check_coding_history_newlines (filename) ;
1166 } /* broadcast_coding_history_test */
1168 /*==============================================================================
1172 broadcast_coding_history_size (const char *filename)
1173 { /* SF_BROADCAST_INFO struct with coding_history field of 1024 bytes. */
1174 static SF_BROADCAST_INFO_VAR (1024) bc_write ;
1175 static SF_BROADCAST_INFO_VAR (1024) bc_read ;
1180 print_test_name (__func__, filename) ;
1182 sfinfo.samplerate = 22050 ;
1183 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
1184 sfinfo.channels = 1 ;
1186 memset (&bc_write, 0, sizeof (bc_write)) ;
1188 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
1189 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
1190 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
1191 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
1192 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
1193 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
1194 bc_write.coding_history_size = 0 ;
1196 for (k = 0 ; bc_write.coding_history_size < 512 ; k++)
1197 { snprintf (bc_write.coding_history + bc_write.coding_history_size,
1198 sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4d\n", k) ;
1199 bc_write.coding_history_size = strlen (bc_write.coding_history) ;
1202 exit_if_true (bc_write.coding_history_size < 512,
1203 "\n\nLine %d : bc_write.coding_history_size (%d) should be > 512.\n\n", __LINE__, bc_write.coding_history_size) ;
1205 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1206 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
1207 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1211 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1214 memset (&bc_read, 0, sizeof (bc_read)) ;
1216 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1217 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
1218 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ;
1221 check_log_buffer_or_die (file, __LINE__) ;
1224 exit_if_true (bc_read.coding_history_size < 512,
1225 "\n\nLine %d : unexpected coding history size %d (should be > 512).\n\n", __LINE__, bc_read.coding_history_size) ;
1227 exit_if_true (strstr (bc_read.coding_history, "libsndfile") == NULL,
1228 "\n\nLine %d : coding history incomplete (should contain 'libsndfile').\n\n", __LINE__) ;
1232 } /* broadcast_coding_history_size */
1234 /*==============================================================================
1237 cart_test (const char *filename, int filetype)
1238 { static SF_CART_INFO ca_write, ca_read ;
1243 print_test_name ("cart_test", filename) ;
1245 sfinfo.samplerate = 11025 ;
1246 sfinfo.format = filetype ;
1247 sfinfo.channels = 1 ;
1248 memset (&ca_write, 0, sizeof (ca_write)) ;
1250 // example test data
1251 snprintf (ca_write.artist, sizeof (ca_write.artist), "Test artist") ;
1252 snprintf (ca_write.version, sizeof (ca_write.version), "Test version") ;
1253 snprintf (ca_write.cut_id, sizeof (ca_write.cut_id), "Test cut ID") ;
1254 snprintf (ca_write.client_id, sizeof (ca_write.client_id), "Test client ID") ;
1255 snprintf (ca_write.category, sizeof (ca_write.category), "Test category") ;
1256 snprintf (ca_write.classification, sizeof (ca_write.classification), "Test classification") ;
1257 snprintf (ca_write.out_cue, sizeof (ca_write.out_cue), "Test out cue") ;
1258 snprintf (ca_write.start_date, sizeof (ca_write.start_date), "%d/%02d/%02d", 2006, 3, 30) ;
1259 snprintf (ca_write.start_time, sizeof (ca_write.start_time), "%02d:%02d:%02d", 20, 27, 0) ;
1260 snprintf (ca_write.end_date, sizeof (ca_write.end_date), "%d/%02d/%02d", 2006, 3, 30) ;
1261 snprintf (ca_write.end_time, sizeof (ca_write.end_time), "%02d:%02d:%02d", 20, 27, 0) ;
1262 snprintf (ca_write.producer_app_id, sizeof (ca_write.producer_app_id), "Test producer app id") ;
1263 snprintf (ca_write.producer_app_version, sizeof (ca_write.producer_app_version), "Test producer app version") ;
1264 snprintf (ca_write.user_def, sizeof (ca_write.user_def), "test user def test test") ;
1265 ca_write.level_reference = 42 ;
1266 snprintf (ca_write.url, sizeof (ca_write.url), "http://www.test.com/test_url") ;
1267 snprintf (ca_write.tag_text, sizeof (ca_write.tag_text), "tag text test! \r\n") ; // must be terminated \r\n to be valid
1268 ca_write.tag_text_size = strlen (ca_write.tag_text) ;
1270 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1271 if (sf_command (file, SFC_SET_CART_INFO, &ca_write, sizeof (ca_write)) == SF_FALSE)
1274 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1277 memset (&ca_read, 0, sizeof (ca_read)) ;
1279 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1280 if (sf_command (file, SFC_GET_CART_INFO, &ca_read, sizeof (ca_read)) == SF_FALSE)
1281 { printf ("\n\nLine %d : sf_command (SFC_GET_CART_INFO) failed.\n\n", __LINE__) ;
1285 check_log_buffer_or_die (file, __LINE__) ;
1289 if (memcmp (ca_write.artist, ca_read.artist, sizeof (ca_write.artist)) != 0)
1290 { printf ("\n\nLine %d : artist mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.artist, ca_read.artist) ;
1294 if (memcmp (ca_write.version, ca_read.version, sizeof (ca_write.version)) != 0)
1295 { printf ("\n\nLine %d : version mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.version, ca_read.version) ;
1299 if (memcmp (ca_write.title, ca_read.title, sizeof (ca_write.title)) != 0)
1300 { printf ("\n\nLine %d : title mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.title, ca_read.title) ;
1304 if (memcmp (ca_write.cut_id, ca_read.cut_id, sizeof (ca_write.cut_id)) != 0)
1305 { printf ("\n\nLine %d : cut_id mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.cut_id, ca_read.cut_id) ;
1309 if (memcmp (ca_write.client_id, ca_read.client_id, sizeof (ca_write.client_id)) != 0)
1310 { printf ("\n\nLine %d : client_id mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.client_id, ca_read.client_id) ;
1314 if (memcmp (ca_write.category, ca_read.category, sizeof (ca_write.category)) != 0)
1315 { printf ("\n\nLine %d : category mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.category, ca_read.category) ;
1319 if (memcmp (ca_write.out_cue, ca_read.out_cue, sizeof (ca_write.out_cue)) != 0)
1320 { printf ("\n\nLine %d : out_cue mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.out_cue, ca_read.out_cue) ;
1324 if (memcmp (ca_write.start_date, ca_read.start_date, sizeof (ca_write.start_date)) != 0)
1325 { printf ("\n\nLine %d : start_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.start_date, ca_read.start_date) ;
1330 if (memcmp (ca_write.start_time, ca_read.start_time, sizeof (ca_write.start_time)) != 0)
1331 { printf ("\n\nLine %d : start_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.start_time, ca_read.start_time) ;
1336 if (memcmp (ca_write.end_date, ca_read.end_date, sizeof (ca_write.end_date)) != 0)
1337 { printf ("\n\nLine %d : end_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.end_date, ca_read.end_date) ;
1342 if (memcmp (ca_write.end_time, ca_read.end_time, sizeof (ca_write.end_time)) != 0)
1343 { printf ("\n\nLine %d : end_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.end_time, ca_read.end_time) ;
1348 if (memcmp (ca_write.producer_app_id, ca_read.producer_app_id, sizeof (ca_write.producer_app_id)) != 0)
1349 { printf ("\n\nLine %d : producer_app_id mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.producer_app_id, ca_read.producer_app_id) ;
1354 if (memcmp (ca_write.producer_app_version, ca_read.producer_app_version, sizeof (ca_write.producer_app_version)) != 0)
1355 { printf ("\n\nLine %d : producer_app_version mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.producer_app_version, ca_read.producer_app_version) ;
1360 if (memcmp (ca_write.user_def, ca_read.user_def, sizeof (ca_write.user_def)) != 0)
1361 { printf ("\n\nLine %d : user_def mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.user_def, ca_read.user_def) ;
1366 if (ca_write.level_reference != ca_read.level_reference)
1367 { printf ("\n\nLine %d : level_reference mismatch :\n\twrite : '%d'\n\tread : '%d'\n\n", __LINE__, ca_write.level_reference, ca_read.level_reference) ;
1371 // TODO: make this more helpful
1372 if (memcmp (ca_write.post_timers, ca_read.post_timers, sizeof (ca_write.post_timers)) != 0)
1373 { printf ("\n\nLine %d : post_timers mismatch :\n'\n\n", __LINE__) ;
1377 if (memcmp (ca_write.url, ca_read.url, sizeof (ca_write.url)) != 0)
1378 { printf ("\n\nLine %d : url mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.url, ca_read.url) ;
1383 if (memcmp (ca_write.tag_text, ca_read.tag_text, (size_t) (ca_read.tag_text_size)) != 0)
1384 { printf ("\n\nLine %d : tag_text mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.tag_text, ca_read.tag_text) ;
1397 cart_rdwr_test (const char *filename, int filetype)
1398 { SF_CART_INFO cinfo ;
1403 print_test_name (__func__, filename) ;
1405 create_short_sndfile (filename, filetype, 2) ;
1407 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1408 memset (&cinfo, 0, sizeof (cinfo)) ;
1410 snprintf (cinfo.artist, sizeof (cinfo.artist), "Test artist") ;
1411 snprintf (cinfo.version, sizeof (cinfo.version), "Test version") ;
1412 snprintf (cinfo.cut_id, sizeof (cinfo.cut_id), "Test cut ID") ;
1413 snprintf (cinfo.client_id, sizeof (cinfo.client_id), "Test client ID") ;
1414 snprintf (cinfo.category, sizeof (cinfo.category), "Test category") ;
1415 snprintf (cinfo.classification, sizeof (cinfo.classification), "Test classification") ;
1416 snprintf (cinfo.out_cue, sizeof (cinfo.out_cue), "Test out cue") ;
1417 snprintf (cinfo.start_date, sizeof (cinfo.start_date), "%d/%02d/%02d", 2006, 3, 30) ;
1418 snprintf (cinfo.start_time, sizeof (cinfo.start_time), "%02d:%02d:%02d", 20, 27, 0) ;
1419 snprintf (cinfo.end_date, sizeof (cinfo.end_date), "%d/%02d/%02d", 2006, 3, 30) ;
1420 snprintf (cinfo.end_time, sizeof (cinfo.end_time), "%02d:%02d:%02d", 20, 27, 0) ;
1421 snprintf (cinfo.producer_app_id, sizeof (cinfo.producer_app_id), "Test producer app id") ;
1422 snprintf (cinfo.producer_app_version, sizeof (cinfo.producer_app_version), "Test producer app version") ;
1423 snprintf (cinfo.user_def, sizeof (cinfo.user_def), "test user def test test") ;
1424 cinfo.level_reference = 42 ;
1425 snprintf (cinfo.url, sizeof (cinfo.url), "http://www.test.com/test_url") ;
1426 snprintf (cinfo.tag_text, sizeof (cinfo.tag_text), "tag text test!\r\n") ;
1427 cinfo.tag_text_size = strlen (cinfo.tag_text) ;
1429 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
1430 frames = sfinfo.frames ;
1431 if (sf_command (file, SFC_SET_CART_INFO, &cinfo, sizeof (cinfo)) != SF_FALSE)
1432 { printf ("\n\nLine %d : sf_command (SFC_SET_CART_INFO) should have failed but didn't.\n\n", __LINE__) ;
1437 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1439 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
1443 } /* cart_rdwr_test */
1445 /*==============================================================================
1449 channel_map_test (const char *filename, int filetype)
1452 int channel_map_read [4], channel_map_write [4] =
1453 { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE,
1454 SF_CHANNEL_MAP_REAR_CENTER
1457 print_test_name ("channel_map_test", filename) ;
1459 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1460 sfinfo.samplerate = 11025 ;
1461 sfinfo.format = filetype ;
1462 sfinfo.channels = ARRAY_LEN (channel_map_read) ;
1464 switch (filetype & SF_FORMAT_TYPEMASK)
1465 { /* WAVEX and RF64 have a default channel map, even if you don't specify one. */
1466 case SF_FORMAT_WAVEX :
1467 case SF_FORMAT_RF64 :
1468 /* Write file without channel map. */
1469 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1470 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1473 /* Read file making default channel map exists. */
1474 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1476 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) == SF_FALSE,
1477 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should not have failed.\n\n", __LINE__
1479 check_log_buffer_or_die (file, __LINE__) ;
1487 /* Write file with a channel map. */
1488 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1490 sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE,
1491 "\n\nLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__
1493 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1496 /* Read file making sure no channel map exists. */
1497 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1499 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_TRUE,
1500 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__
1502 check_log_buffer_or_die (file, __LINE__) ;
1506 memcmp (channel_map_read, channel_map_write, sizeof (channel_map_read)) != 0,
1507 "\n\nLine %d : Channel map read does not match channel map written.\n\n", __LINE__
1512 } /* channel_map_test */
1515 raw_needs_endswap_test (const char *filename, int filetype)
1516 { static int subtypes [] =
1517 { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE,
1518 SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1525 print_test_name (__func__, filename) ;
1527 for (k = 0 ; k < ARRAY_LEN (subtypes) ; k++)
1529 if (filetype == (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF))
1530 switch (subtypes [k])
1531 { /* Little endian AIFF does not AFAIK support fl32 and fl64. */
1532 case SF_FORMAT_FLOAT :
1533 case SF_FORMAT_DOUBLE :
1539 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1540 sfinfo.samplerate = 11025 ;
1541 sfinfo.format = filetype | subtypes [k] ;
1542 sfinfo.channels = 1 ;
1544 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1545 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
1548 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1549 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1551 needs_endswap = sf_command (file, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0) ;
1554 { case SF_FORMAT_WAV :
1555 case SF_FORMAT_WAVEX :
1556 case SF_FORMAT_AIFF | SF_ENDIAN_LITTLE :
1557 exit_if_true (needs_endswap != CPU_IS_BIG_ENDIAN,
1558 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ;
1561 case SF_FORMAT_AIFF :
1562 case SF_FORMAT_WAV | SF_ENDIAN_BIG :
1563 exit_if_true (needs_endswap != CPU_IS_LITTLE_ENDIAN,
1564 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ;
1568 printf ("\n\nLine %d : bad format value %d.\n\n", __LINE__, filetype) ;
1578 } /* raw_needs_endswap_test */