1/* 2** Copyright (C) 2001-2019 Erik de Castro Lopo <erikd@mega-nerd.com> 3** 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. 8** 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. 13** 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. 17*/ 18 19#include "sfconfig.h" 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <stdint.h> 24#include <inttypes.h> 25#include <string.h> 26#include <time.h> 27 28#if HAVE_UNISTD_H 29#include <unistd.h> 30#else 31#include "sf_unistd.h" 32#endif 33 34#include <math.h> 35 36#include <sndfile.h> 37 38#include "sfendian.h" 39#include "utils.h" 40 41#define BUFFER_LEN (1 << 10) 42#define LOG_BUFFER_SIZE 1024 43#define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a') 44 45static void float_norm_test (const char *filename) ; 46static void double_norm_test (const char *filename) ; 47static void format_tests (void) ; 48static void calc_peak_test (int filetype, const char *filename, int channels) ; 49static void truncate_test (const char *filename, int filetype) ; 50static void instrument_test (const char *filename, int filetype) ; 51static void cue_test (const char *filename, int filetype) ; 52static void cue_test_var (const char *filename, int filetype, int count) ; 53static void channel_map_test (const char *filename, int filetype) ; 54static void current_sf_info_test (const char *filename) ; 55static void raw_needs_endswap_test (const char *filename, int filetype) ; 56 57static void broadcast_test (const char *filename, int filetype) ; 58static void broadcast_rdwr_test (const char *filename, int filetype) ; 59static void broadcast_coding_history_test (const char *filename) ; 60static void broadcast_coding_history_size (const char *filename) ; 61 62/* Cart Chunk tests */ 63static void cart_test (const char *filename, int filetype) ; 64static void cart_rdwr_test (const char *filename, int filetype) ; 65 66/* Force the start of this buffer to be double aligned. Sparc-solaris will 67** choke if its not. 68*/ 69 70static int int_data [BUFFER_LEN] ; 71static float float_data [BUFFER_LEN] ; 72static double double_data [BUFFER_LEN] ; 73 74int 75main (int argc, char *argv []) 76{ int do_all = 0 ; 77 int test_count = 0 ; 78 79 if (argc != 2) 80 { printf ("Usage : %s <test>\n", argv [0]) ; 81 printf (" Where <test> is one of the following:\n") ; 82 printf (" ver - test sf_command (SFC_GETLIB_VERSION)\n") ; 83 printf (" norm - test floating point normalisation\n") ; 84 printf (" format - test format string commands\n") ; 85 printf (" peak - test peak calculation\n") ; 86 printf (" trunc - test file truncation\n") ; 87 printf (" inst - test set/get of SF_INSTRUMENT.\n") ; 88 printf (" cue - test set/get of SF_CUES.\n") ; 89 printf (" chanmap - test set/get of channel map data..\n") ; 90 printf (" bext - test set/get of SF_BROADCAST_INFO.\n") ; 91 printf (" bextch - test set/get of SF_BROADCAST_INFO coding_history.\n") ; 92 printf (" cart - test set/get of SF_CART_INFO.\n") ; 93 printf (" rawend - test SFC_RAW_NEEDS_ENDSWAP.\n") ; 94 printf (" all - perform all tests\n") ; 95 exit (1) ; 96 } ; 97 98 do_all = ! strcmp (argv [1], "all") ; 99 100 if (do_all || strcmp (argv [1], "ver") == 0) 101 { char buffer [128] ; 102 103 print_test_name ("version_test", "(none)") ; 104 buffer [0] = 0 ; 105 sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ; 106 if (strlen (buffer) < 1) 107 { printf ("Line %d: could not retrieve lib version.\n", __LINE__) ; 108 exit (1) ; 109 } ; 110 puts ("ok") ; 111 test_count ++ ; 112 } ; 113 114 if (do_all || strcmp (argv [1], "norm") == 0) 115 { /* Preliminary float/double normalisation tests. More testing 116 ** is done in the program 'floating_point_test'. 117 */ 118 float_norm_test ("cmd_float.wav") ; 119 double_norm_test ("cmd_double.wav") ; 120 test_count ++ ; 121 } ; 122 123 if (do_all || strcmp (argv [1], "peak") == 0) 124 { calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw", 1) ; 125 calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw", 1) ; 126 calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw", 7) ; 127 calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw", 7) ; 128 test_count ++ ; 129 } ; 130 131 if (do_all || ! strcmp (argv [1], "format")) 132 { format_tests () ; 133 test_count ++ ; 134 } ; 135 136 if (do_all || strcmp (argv [1], "trunc") == 0) 137 { truncate_test ("truncate.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_32) ; 138 truncate_test ("truncate.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16) ; 139 test_count ++ ; 140 } ; 141 142 if (do_all || strcmp (argv [1], "inst") == 0) 143 { instrument_test ("instrument.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 144 /*-instrument_test ("instrument.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ;-*/ 145 /*-instrument_test ("instrument.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16) ;-*/ 146 test_count ++ ; 147 } ; 148 149 if (do_all || strcmp (argv [1], "cue") == 0) 150 { /* 2500 is close to the largest number of cues possible because of block sizes (enforced in aiff.c, wav.c) */ 151 int cuecounts [] = { 0, 1, 10, 100, 101, 1000, 1001, 2500 } ; 152 unsigned int i ; 153 154 cue_test ("cue.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 155 cue_test ("cue.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ; 156 157 for (i = 0 ; i < ARRAY_LEN (cuecounts) ; i++) 158 { cue_test_var ("cue.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16, cuecounts [i]) ; 159 cue_test_var ("cue.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_24, cuecounts [i]) ; 160 } ; 161 162 test_count ++ ; 163 } ; 164 165 if (do_all || strcmp (argv [1], "current_sf_info") == 0) 166 { current_sf_info_test ("current.wav") ; 167 test_count ++ ; 168 } ; 169 170 if (do_all || strcmp (argv [1], "bext") == 0) 171 { broadcast_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 172 broadcast_rdwr_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 173 174 broadcast_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; 175 broadcast_rdwr_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; 176 177 broadcast_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; 178 broadcast_rdwr_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; 179 test_count ++ ; 180 } ; 181 182 if (do_all || strcmp (argv [1], "cart") == 0) 183 { cart_test ("cart.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 184 cart_rdwr_test ("cart.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 185 cart_test ("cart.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; 186 cart_rdwr_test ("cart.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; 187 test_count ++ ; 188 } ; 189 190 if (do_all || strcmp (argv [1], "bextch") == 0) 191 { broadcast_coding_history_test ("coding_history.wav") ; 192 broadcast_coding_history_size ("coding_hist_size.wav") ; 193 test_count ++ ; 194 } ; 195 196 if (do_all || strcmp (argv [1], "chanmap") == 0) 197 { channel_map_test ("chanmap.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; 198 channel_map_test ("chanmap.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; 199 channel_map_test ("chanmap.aifc" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ; 200 channel_map_test ("chanmap.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16) ; 201 test_count ++ ; 202 } ; 203 204 if (do_all || strcmp (argv [1], "rawend") == 0) 205 { raw_needs_endswap_test ("raw_end.wav", SF_FORMAT_WAV) ; 206 raw_needs_endswap_test ("raw_end.wavex", SF_FORMAT_WAVEX) ; 207 raw_needs_endswap_test ("raw_end.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ; 208 raw_needs_endswap_test ("raw_end.aiff", SF_FORMAT_AIFF) ; 209 raw_needs_endswap_test ("raw_end.aiff_le", SF_ENDIAN_LITTLE | SF_FORMAT_AIFF) ; 210 test_count ++ ; 211 } ; 212 213 if (test_count == 0) 214 { printf ("Mono : ************************************\n") ; 215 printf ("Mono : * No '%s' test defined.\n", argv [1]) ; 216 printf ("Mono : ************************************\n") ; 217 return 1 ; 218 } ; 219 220 return 0 ; 221} /* main */ 222 223/*============================================================================================ 224** Here are the test functions. 225*/ 226 227static void 228float_norm_test (const char *filename) 229{ SNDFILE *file ; 230 SF_INFO sfinfo ; 231 unsigned int k ; 232 233 print_test_name ("float_norm_test", filename) ; 234 235 sfinfo.samplerate = 44100 ; 236 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ; 237 sfinfo.channels = 1 ; 238 sfinfo.frames = BUFFER_LEN ; 239 240 /* Create float_data with all values being less than 1.0. */ 241 for (k = 0 ; k < BUFFER_LEN / 2 ; k++) 242 float_data [k] = (k + 5) / (2.0f * BUFFER_LEN) ; 243 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++) 244 float_data [k] = (float) (k + 5) ; 245 246 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) 247 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; 248 fflush (stdout) ; 249 puts (sf_strerror (NULL)) ; 250 exit (1) ; 251 } ; 252 253 /* Normalisation is on by default so no need to do anything here. */ 254 255 if ((k = (unsigned int) sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2) 256 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 257 exit (1) ; 258 } ; 259 260 /* Turn normalisation off. */ 261 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 262 263 if ((k = (unsigned int) sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2) 264 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 265 exit (1) ; 266 } ; 267 268 sf_close (file) ; 269 270 /* sfinfo struct should still contain correct data. */ 271 if (! (file = sf_open (filename, SFM_READ, &sfinfo))) 272 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; 273 fflush (stdout) ; 274 puts (sf_strerror (NULL)) ; 275 exit (1) ; 276 } ; 277 278 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16)) 279 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ; 280 exit (1) ; 281 } ; 282 283 if (sfinfo.frames != BUFFER_LEN) 284 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %" PRId64 ")\n", __LINE__, BUFFER_LEN, sfinfo.frames) ; 285 exit (1) ; 286 } ; 287 288 if (sfinfo.channels != 1) 289 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; 290 exit (1) ; 291 } ; 292 293 /* Read float_data and check that it is normalised (ie default). */ 294 if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) 295 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 296 exit (1) ; 297 } ; 298 299 for (k = 0 ; k < BUFFER_LEN ; k++) 300 if (float_data [k] >= 1.0) 301 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ; 302 exit (1) ; 303 } ; 304 305 /* Seek to start of file, turn normalisation off, read float_data and check again. */ 306 sf_seek (file, 0, SEEK_SET) ; 307 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 308 309 if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) 310 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 311 exit (1) ; 312 } ; 313 314 for (k = 0 ; k < BUFFER_LEN ; k++) 315 if (float_data [k] < 1.0) 316 { printf ("\n\nLine %d: float_data [%d] == %f which is less than 1.0\n", __LINE__, k, float_data [k]) ; 317 exit (1) ; 318 } ; 319 320 /* Seek to start of file, turn normalisation on, read float_data and do final check. */ 321 sf_seek (file, 0, SEEK_SET) ; 322 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE) ; 323 324 if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) 325 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 326 exit (1) ; 327 } ; 328 329 for (k = 0 ; k < BUFFER_LEN ; k++) 330 if (float_data [k] > 1.0) 331 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ; 332 exit (1) ; 333 } ; 334 335 336 sf_close (file) ; 337 338 unlink (filename) ; 339 340 printf ("ok\n") ; 341} /* float_norm_test */ 342 343static void 344double_norm_test (const char *filename) 345{ SNDFILE *file ; 346 SF_INFO sfinfo ; 347 unsigned int k ; 348 349 print_test_name ("double_norm_test", filename) ; 350 351 sfinfo.samplerate = 44100 ; 352 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ; 353 sfinfo.channels = 1 ; 354 sfinfo.frames = BUFFER_LEN ; 355 356 /* Create double_data with all values being less than 1.0. */ 357 for (k = 0 ; k < BUFFER_LEN / 2 ; k++) 358 double_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ; 359 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++) 360 double_data [k] = (k + 5) ; 361 362 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) 363 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; 364 fflush (stdout) ; 365 puts (sf_strerror (NULL)) ; 366 exit (1) ; 367 } ; 368 369 /* Normailsation is on by default so no need to do anything here. */ 370 /*-sf_command (file, "set-norm-double", "true", 0) ;-*/ 371 372 if ((k = (unsigned int) sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2) 373 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 374 exit (1) ; 375 } ; 376 377 /* Turn normalisation off. */ 378 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 379 380 if ((k = (unsigned int) sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2) 381 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 382 exit (1) ; 383 } ; 384 385 sf_close (file) ; 386 387 if (! (file = sf_open (filename, SFM_READ, &sfinfo))) 388 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; 389 fflush (stdout) ; 390 puts (sf_strerror (NULL)) ; 391 exit (1) ; 392 } ; 393 394 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16)) 395 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ; 396 exit (1) ; 397 } ; 398 399 if (sfinfo.frames != BUFFER_LEN) 400 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %" PRId64 ")\n", __LINE__, BUFFER_LEN, sfinfo.frames) ; 401 exit (1) ; 402 } ; 403 404 if (sfinfo.channels != 1) 405 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; 406 exit (1) ; 407 } ; 408 409 /* Read double_data and check that it is normalised (ie default). */ 410 if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) 411 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 412 exit (1) ; 413 } ; 414 415 for (k = 0 ; k < BUFFER_LEN ; k++) 416 if (double_data [k] >= 1.0) 417 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; 418 exit (1) ; 419 } ; 420 421 /* Seek to start of file, turn normalisation off, read double_data and check again. */ 422 sf_seek (file, 0, SEEK_SET) ; 423 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 424 425 if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) 426 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 427 exit (1) ; 428 } ; 429 430 for (k = 0 ; k < BUFFER_LEN ; k++) 431 if (double_data [k] < 1.0) 432 { printf ("\n\nLine %d: double_data [%d] == %f which is less than 1.0\n", __LINE__, k, double_data [k]) ; 433 exit (1) ; 434 } ; 435 436 /* Seek to start of file, turn normalisation on, read double_data and do final check. */ 437 sf_seek (file, 0, SEEK_SET) ; 438 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ; 439 440 if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) 441 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; 442 exit (1) ; 443 } ; 444 445 for (k = 0 ; k < BUFFER_LEN ; k++) 446 if (double_data [k] > 1.0) 447 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; 448 exit (1) ; 449 } ; 450 451 452 sf_close (file) ; 453 454 unlink (filename) ; 455 456 printf ("ok\n") ; 457} /* double_norm_test */ 458 459static void 460format_tests (void) 461{ SF_FORMAT_INFO format_info ; 462 SF_INFO sfinfo ; 463 const char *last_name ; 464 int k, count ; 465 466 print_test_name ("format_tests", "(null)") ; 467 468 /* Clear out SF_INFO struct and set channels > 0. */ 469 memset (&sfinfo, 0, sizeof (sfinfo)) ; 470 sfinfo.channels = 1 ; 471 472 /* First test simple formats. */ 473 474 sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &count, sizeof (int)) ; 475 476 if (count < 0 || count > 30) 477 { printf ("Line %d: Weird count.\n", __LINE__) ; 478 exit (1) ; 479 } ; 480 481 format_info.format = 0 ; 482 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; 483 484 last_name = format_info.name ; 485 for (k = 1 ; k < count ; k ++) 486 { format_info.format = k ; 487 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; 488 if (strcmp (last_name, format_info.name) >= 0) 489 { printf ("\n\nLine %d: format names out of sequence `%s' < `%s'.\n", __LINE__, last_name, format_info.name) ; 490 exit (1) ; 491 } ; 492 sfinfo.format = format_info.format ; 493 494 if (! sf_format_check (&sfinfo)) 495 { printf ("\n\nLine %d: sf_format_check failed.\n", __LINE__) ; 496 printf (" Name : %s\n", format_info.name) ; 497 printf (" Format : 0x%X\n", sfinfo.format) ; 498 printf (" Channels : 0x%X\n", sfinfo.channels) ; 499 printf (" Sample Rate : 0x%X\n", sfinfo.samplerate) ; 500 exit (1) ; 501 } ; 502 last_name = format_info.name ; 503 } ; 504 format_info.format = 666 ; 505 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; 506 507 /* Now test major formats. */ 508 sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ; 509 510 if (count < 0 || count > 30) 511 { printf ("Line %d: Weird count.\n", __LINE__) ; 512 exit (1) ; 513 } ; 514 515 format_info.format = 0 ; 516 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; 517 518 last_name = format_info.name ; 519 for (k = 1 ; k < count ; k ++) 520 { format_info.format = k ; 521 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; 522 if (strcmp (last_name, format_info.name) >= 0) 523 { printf ("\n\nLine %d: format names out of sequence (%d) `%s' < `%s'.\n", __LINE__, k, last_name, format_info.name) ; 524 exit (1) ; 525 } ; 526 527 last_name = format_info.name ; 528 } ; 529 format_info.format = 666 ; 530 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; 531 532 /* Now test subtype formats. */ 533 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ; 534 535 if (count < 0 || count > 33) 536 { printf ("Line %d: Weird count.\n", __LINE__) ; 537 exit (1) ; 538 } ; 539 540 format_info.format = 0 ; 541 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; 542 543 last_name = format_info.name ; 544 for (k = 1 ; k < count ; k ++) 545 { format_info.format = k ; 546 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; 547 } ; 548 format_info.format = 666 ; 549 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; 550 551 552 printf ("ok\n") ; 553} /* format_tests */ 554 555static void 556calc_peak_test (int filetype, const char *filename, int channels) 557{ SNDFILE *file ; 558 SF_INFO sfinfo ; 559 char label [128] ; 560 int k, format ; 561 sf_count_t buffer_len, frame_count ; 562 double peak ; 563 564 snprintf (label, sizeof (label), "calc_peak_test (%d channels)", channels) ; 565 print_test_name (label, filename) ; 566 567 format = filetype | SF_FORMAT_PCM_16 ; 568 569 buffer_len = BUFFER_LEN - (BUFFER_LEN % channels) ; 570 frame_count = buffer_len / channels ; 571 572 sfinfo.samplerate = 44100 ; 573 sfinfo.format = format ; 574 sfinfo.channels = channels ; 575 sfinfo.frames = frame_count ; 576 577 /* Create double_data with max value of 0.5. */ 578 for (k = 0 ; k < buffer_len ; k++) 579 double_data [k] = (k + 1) / (2.0 * buffer_len) ; 580 581 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 582 583 test_writef_double_or_die (file, 0, double_data, frame_count, __LINE__) ; 584 585 sf_close (file) ; 586 587 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 588 589 if (sfinfo.format != format) 590 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ; 591 exit (1) ; 592 } ; 593 594 if (sfinfo.frames != frame_count) 595 { printf ("\n\nLine %d: Incorrect number of frames in file. (%" PRId64 " => %" PRId64 ")\n", __LINE__, frame_count, sfinfo.frames) ; 596 exit (1) ; 597 } ; 598 599 if (sfinfo.channels != channels) 600 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; 601 exit (1) ; 602 } ; 603 604 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ; 605 if (fabs (peak - (1 << 14)) > 1.0) 606 { printf ("Line %d : Peak value should be %d (is %f).\n", __LINE__, (1 << 14), peak) ; 607 exit (1) ; 608 } ; 609 610 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ; 611 if (fabs (peak - 0.5) > 4e-5) 612 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; 613 exit (1) ; 614 } ; 615 616 sf_close (file) ; 617 618 format = (filetype | SF_FORMAT_FLOAT) ; 619 sfinfo.samplerate = 44100 ; 620 sfinfo.format = format ; 621 sfinfo.channels = channels ; 622 sfinfo.frames = frame_count ; 623 624 /* Create double_data with max value of 0.5. */ 625 for (k = 0 ; k < buffer_len ; k++) 626 double_data [k] = (k + 1) / (2.0 * buffer_len) ; 627 628 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 629 630 test_writef_double_or_die (file, 0, double_data, frame_count, __LINE__) ; 631 632 sf_close (file) ; 633 634 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 635 636 if (sfinfo.format != format) 637 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ; 638 exit (1) ; 639 } ; 640 641 if (sfinfo.frames != frame_count) 642 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%" PRId64 " => %" PRId64 ")\n", __LINE__, frame_count, sfinfo.frames) ; 643 exit (1) ; 644 } ; 645 646 if (sfinfo.channels != channels) 647 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; 648 exit (1) ; 649 } ; 650 651 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ; 652 if (fabs (peak - 0.5) > 1e-5) 653 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; 654 exit (1) ; 655 } ; 656 657 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ; 658 if (fabs (peak - 0.5) > 1e-5) 659 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; 660 exit (1) ; 661 } ; 662 663 sf_close (file) ; 664 665 unlink (filename) ; 666 667 printf ("ok\n") ; 668} /* calc_peak_test */ 669 670static void 671truncate_test (const char *filename, int filetype) 672{ SNDFILE *file ; 673 SF_INFO sfinfo ; 674 sf_count_t len ; 675 676 print_test_name ("truncate_test", filename) ; 677 678 sfinfo.samplerate = 11025 ; 679 sfinfo.format = filetype ; 680 sfinfo.channels = 2 ; 681 682 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; 683 684 test_write_int_or_die (file, 0, int_data, BUFFER_LEN, __LINE__) ; 685 686 len = 100 ; 687 if (sf_command (file, SFC_FILE_TRUNCATE, &len, sizeof (len))) 688 { printf ("Line %d: sf_command (SFC_FILE_TRUNCATE) returned error.\n", __LINE__) ; 689 exit (1) ; 690 } ; 691 692 test_seek_or_die (file, 0, SEEK_CUR, len, 2, __LINE__) ; 693 test_seek_or_die (file, 0, SEEK_END, len, 2, __LINE__) ; 694 695 sf_close (file) ; 696 697 unlink (filename) ; 698 puts ("ok") ; 699} /* truncate_test */ 700 701/*------------------------------------------------------------------------------ 702*/ 703 704static void 705instrumet_rw_test (const char *filename) 706{ SNDFILE *sndfile ; 707 SF_INFO sfinfo ; 708 SF_INSTRUMENT inst ; 709 memset (&sfinfo, 0, sizeof (SF_INFO)) ; 710 711 sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; 712 713 if (sf_command (sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE) 714 { inst.basenote = 22 ; 715 716 if (sf_command (sndfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE) 717 printf ("Sucess: [%s] updated\n", filename) ; 718 else 719 printf ("Error: SFC_SET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 720 } 721 else 722 printf ("Error: SFC_GET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 723 724 725 if (sf_command (sndfile, SFC_UPDATE_HEADER_NOW, NULL, 0) != 0) 726 printf ("Error: SFC_UPDATE_HEADER_NOW on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 727 728 sf_write_sync (sndfile) ; 729 sf_close (sndfile) ; 730 731 return ; 732} /* instrumet_rw_test */ 733 734static void 735instrument_test (const char *filename, int filetype) 736{ static SF_INSTRUMENT write_inst = 737 { 2, /* gain */ 738 3, /* detune */ 739 4, /* basenote */ 740 5, 6, /* key low and high */ 741 7, 8, /* velocity low and high */ 742 2, /* loop_count */ 743 { { 801, 2, 3, 0 }, 744 { 801, 3, 4, 0 }, 745 } 746 } ; 747 SF_INSTRUMENT read_inst ; 748 SNDFILE *file ; 749 SF_INFO sfinfo ; 750 751 print_test_name ("instrument_test", filename) ; 752 753 sfinfo.samplerate = 11025 ; 754 sfinfo.format = filetype ; 755 sfinfo.channels = 1 ; 756 757 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 758 if (sf_command (file, SFC_SET_INSTRUMENT, &write_inst, sizeof (write_inst)) == SF_FALSE) 759 { printf ("\n\nLine %d : sf_command (SFC_SET_INSTRUMENT) failed.\n\n", __LINE__) ; 760 exit (1) ; 761 } ; 762 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 763 sf_close (file) ; 764 765 memset (&read_inst, 0, sizeof (read_inst)) ; 766 767 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 768 if (sf_command (file, SFC_GET_INSTRUMENT, &read_inst, sizeof (read_inst)) == SF_FALSE) 769 { printf ("\n\nLine %d : sf_command (SFC_GET_INSTRUMENT) failed.\n\n", __LINE__) ; 770 exit (1) ; 771 return ; 772 } ; 773 check_log_buffer_or_die (file, __LINE__) ; 774 sf_close (file) ; 775 776 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV) 777 { /* 778 ** For all the fields that WAV doesn't support, modify the 779 ** write_inst struct to hold the default value that the WAV 780 ** module should hold. 781 */ 782 write_inst.key_lo = write_inst.velocity_lo = 0 ; 783 write_inst.key_hi = write_inst.velocity_hi = 127 ; 784 write_inst.gain = 1 ; 785 } ; 786 787 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI) 788 { /* 789 ** For all the fields that XI doesn't support, modify the 790 ** write_inst struct to hold the default value that the XI 791 ** module should hold. 792 */ 793 write_inst.basenote = 0 ; 794 write_inst.detune = 0 ; 795 write_inst.key_lo = write_inst.velocity_lo = 0 ; 796 write_inst.key_hi = write_inst.velocity_hi = 127 ; 797 write_inst.gain = 1 ; 798 } ; 799 800 if (memcmp (&write_inst, &read_inst, sizeof (write_inst)) != 0) 801 { printf ("\n\nLine %d : instrument comparison failed.\n\n", __LINE__) ; 802 printf ("W Base Note : %u\n" 803 " Detune : %u\n" 804 " Low Note : %u\tHigh Note : %u\n" 805 " Low Vel. : %u\tHigh Vel. : %u\n" 806 " Gain : %d\tCount : %d\n" 807 " mode : %d\n" 808 " start : %d\tend : %d\tcount :%d\n" 809 " mode : %d\n" 810 " start : %d\tend : %d\tcount :%d\n\n", 811 write_inst.basenote, 812 write_inst.detune, 813 write_inst.key_lo, write_inst.key_hi, 814 write_inst.velocity_lo, write_inst.velocity_hi, 815 write_inst.gain, write_inst.loop_count, 816 write_inst.loops [0].mode, write_inst.loops [0].start, 817 write_inst.loops [0].end, write_inst.loops [0].count, 818 write_inst.loops [1].mode, write_inst.loops [1].start, 819 write_inst.loops [1].end, write_inst.loops [1].count) ; 820 printf ("R Base Note : %u\n" 821 " Detune : %u\n" 822 " Low Note : %u\tHigh Note : %u\n" 823 " Low Vel. : %u\tHigh Vel. : %u\n" 824 " Gain : %d\tCount : %d\n" 825 " mode : %d\n" 826 " start : %d\tend : %d\tcount :%d\n" 827 " mode : %d\n" 828 " start : %d\tend : %d\tcount :%d\n\n", 829 read_inst.basenote, 830 read_inst.detune, 831 read_inst.key_lo, read_inst.key_hi, 832 read_inst.velocity_lo, read_inst.velocity_hi, 833 read_inst.gain, read_inst.loop_count, 834 read_inst.loops [0].mode, read_inst.loops [0].start, 835 read_inst.loops [0].end, read_inst.loops [0].count, 836 read_inst.loops [1].mode, read_inst.loops [1].start, 837 read_inst.loops [1].end, read_inst.loops [1].count) ; 838 839 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI) 840 exit (1) ; 841 } ; 842 843 if (0) instrumet_rw_test (filename) ; 844 845 unlink (filename) ; 846 puts ("ok") ; 847} /* instrument_test */ 848 849static void 850print_cue (SF_CUES *cue, int i) 851{ 852 printf (" indx[%d] : %d\n" 853 " position : %u\n" 854 " fcc_chunk : %x\n" 855 " chunk_start : %d\n" 856 " block_start : %d\n" 857 " sample_offset : %u\n" 858 " name : %s\n", 859 i, 860 cue->cue_points [i].indx, 861 cue->cue_points [i].position, 862 cue->cue_points [i].fcc_chunk, 863 cue->cue_points [i].chunk_start, 864 cue->cue_points [i].block_start, 865 cue->cue_points [i].sample_offset, 866 cue->cue_points [i].name) ; 867} 868 869static int 870cue_compare (SF_CUES *write_cue, SF_CUES *read_cue, size_t cue_size, int line) 871{ 872 if (memcmp (write_cue, read_cue, cue_size) != 0) 873 { 874 printf ("\n\nLine %d : cue comparison failed.\n\n", line) ; 875 printf ("W Cue count : %d\n", write_cue->cue_count) ; 876 if (write_cue->cue_count > 0) 877 print_cue (write_cue, 0) ; 878 if (write_cue->cue_count > 2) /* print last if at least 2 */ 879 print_cue (write_cue, write_cue->cue_count - 1) ; 880 881 printf ("R Cue count : %d\n", read_cue->cue_count) ; 882 if (read_cue->cue_count > 0) 883 print_cue (read_cue, 0) ; 884 if (read_cue->cue_count > 2) /* print last if at least 2 */ 885 print_cue (read_cue, read_cue->cue_count - 1) ; 886 887 return SF_FALSE ; 888 } ; 889 890 return SF_TRUE ; 891} /* cue_compare */ 892 893static void 894cue_rw_test (const char *filename) 895{ SNDFILE *sndfile ; 896 SF_INFO sfinfo ; 897 SF_CUES cues ; 898 memset (&sfinfo, 0, sizeof (SF_INFO)) ; 899 900 sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; 901 902 exit_if_true ( 903 sf_command (sndfile, SFC_GET_CUE_COUNT, &cues.cue_count, sizeof (cues.cue_count)) != SF_TRUE, 904 "\nLine %d: SFC_GET_CUE_COUNT command failed.\n\n", __LINE__ 905 ) ; 906 907 exit_if_true ( 908 cues.cue_count != 3, 909 "\nLine %d: Expected cue_count (%u) to be 3.\n\n", __LINE__, cues.cue_count 910 ) ; 911 912 if (sf_command (sndfile, SFC_GET_CUE, &cues, sizeof (cues)) == SF_TRUE) 913 { cues.cue_points [1].sample_offset = 3 ; 914 915 if (sf_command (sndfile, SFC_SET_CUE, &cues, sizeof (cues)) == SF_TRUE) 916 printf ("Sucess: [%s] updated\n", filename) ; 917 else 918 printf ("Error: SFC_SET_CUE on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 919 } 920 else 921 printf ("Error: SFC_GET_CUE on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 922 923 924 if (sf_command (sndfile, SFC_UPDATE_HEADER_NOW, NULL, 0) != 0) 925 printf ("Error: SFC_UPDATE_HEADER_NOW on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; 926 927 sf_write_sync (sndfile) ; 928 sf_close (sndfile) ; 929 930 return ; 931} /* cue_rw_test */ 932 933static void 934cue_test (const char *filename, int filetype) 935{ SF_CUES write_cue ; 936 SF_CUES read_cue ; 937 SNDFILE *file ; 938 SF_INFO sfinfo ; 939 940 if (filetype == (SF_FORMAT_WAV | SF_FORMAT_PCM_16)) 941 { write_cue = (SF_CUES) 942 { 2, /* cue_count */ 943 { { 1, 0, data_MARKER, 0, 0, 1, "" }, 944 { 2, 0, data_MARKER, 0, 0, 2, "" }, 945 } 946 } ; 947 } 948 else 949 { write_cue = (SF_CUES) 950 { 2, /* cue_count */ 951 { { 1, 0, data_MARKER, 0, 0, 1, "Cue1" }, 952 { 2, 0, data_MARKER, 0, 0, 2, "Cue2" }, 953 } 954 } ; 955 } 956 957 print_test_name ("cue_test", filename) ; 958 959 sfinfo.samplerate = 11025 ; 960 sfinfo.format = filetype ; 961 sfinfo.channels = 1 ; 962 963 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 964 if (sf_command (file, SFC_SET_CUE, &write_cue, sizeof (write_cue)) == SF_FALSE) 965 { printf ("\n\nLine %d : sf_command (SFC_SET_CUE) failed.\n\n", __LINE__) ; 966 exit (1) ; 967 } ; 968 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 969 sf_close (file) ; 970 971 memset (&read_cue, 0, sizeof (read_cue)) ; 972 973 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 974 if (sf_command (file, SFC_GET_CUE, &read_cue, sizeof (read_cue)) == SF_FALSE) 975 { printf ("\n\nLine %d : sf_command (SFC_GET_CUE) failed.\n\n", __LINE__) ; 976 exit (1) ; 977 return ; 978 } ; 979 check_log_buffer_or_die (file, __LINE__) ; 980 sf_close (file) ; 981 982 if (cue_compare (&write_cue, &read_cue, sizeof (write_cue), __LINE__) == SF_FALSE) 983 exit (1) ; 984 985 if (0) cue_rw_test (filename) ; 986 987 unlink (filename) ; 988 puts ("ok") ; 989} /* cue_test */ 990 991/* calculate size of SF_CUES struct given number of cues */ 992#define SF_CUES_SIZE(count) (sizeof (uint32_t) + sizeof (SF_CUE_POINT) * (count)) 993 994static void 995cue_test_var (const char *filename, int filetype, int count) 996{ size_t cues_size = SF_CUES_SIZE (count) ; 997 SF_CUES *write_cue = calloc (1, cues_size) ; 998 SF_CUES *read_cue = calloc (1, cues_size) ; 999 SNDFILE *file ; 1000 SF_INFO sfinfo ; 1001 char name [40] ; 1002 int i ; 1003 1004 snprintf (name, sizeof (name), "cue_test_var %d", count) ; 1005 print_test_name (name, filename) ; 1006 1007 if (write_cue == NULL || read_cue == NULL) 1008 { printf ("ok (can't alloc)\n") ; 1009 return ; 1010 } ; 1011 1012 write_cue->cue_count = count ; 1013 for (i = 0 ; i < count ; i++) 1014 { write_cue->cue_points [i] = (SF_CUE_POINT) { i, 0, data_MARKER, 0, 0, i, "" } ; 1015 if (filetype == (SF_FORMAT_AIFF | SF_FORMAT_PCM_24)) 1016 snprintf (write_cue->cue_points [i].name, sizeof (write_cue->cue_points [i].name), "Cue%03d", i) ; 1017 } ; 1018 1019 sfinfo.samplerate = 11025 ; 1020 sfinfo.format = filetype ; 1021 sfinfo.channels = 1 ; 1022 1023 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1024 if (sf_command (file, SFC_SET_CUE, write_cue, (int) cues_size) == SF_FALSE) 1025 { printf ("\n\nLine %d : sf_command (SFC_SET_CUE) failed with %d cues, datasize %zu --> error: %s\n\n", __LINE__, count, cues_size, sf_strerror (file)) ; 1026 exit (1) ; 1027 } ; 1028 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1029 sf_close (file) ; 1030 1031 memset (read_cue, 0, cues_size) ; 1032 1033 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1034 1035 if (sf_command (file, SFC_GET_CUE, read_cue, (int) cues_size) == SF_FALSE) 1036 { printf ("\n\nLine %d : sf_command (SFC_GET_CUE) failed with %d cues, datasize %zu --> error: %s\n\n", __LINE__, count, cues_size, sf_strerror (file)) ; 1037 exit (1) ; 1038 } ; 1039 check_log_buffer_or_die (file, __LINE__) ; 1040 sf_close (file) ; 1041 1042 if (cue_compare (write_cue, read_cue, cues_size, __LINE__) == SF_FALSE) 1043 { printf ("\n\nLine %d : cue_compare failed.\n\n", __LINE__) ; 1044 exit (1) ; 1045 } ; 1046 1047 free (write_cue) ; 1048 free (read_cue) ; 1049 unlink (filename) ; 1050 puts ("ok") ; 1051} /* cue_test_var */ 1052 1053static void 1054current_sf_info_test (const char *filename) 1055{ SNDFILE *outfile, *infile ; 1056 SF_INFO outinfo, ininfo ; 1057 1058 print_test_name ("current_sf_info_test", filename) ; 1059 1060 outinfo.samplerate = 44100 ; 1061 outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; 1062 outinfo.channels = 1 ; 1063 outinfo.frames = 0 ; 1064 1065 outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ; 1066 sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ; 1067 1068 exit_if_true (outinfo.frames != 0, 1069 "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__ 1070 ) ; 1071 1072 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; 1073 sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ; 1074 1075 exit_if_true (outinfo.frames != BUFFER_LEN, 1076 "\n\nLine %d : Initial sfinfo.frames (%" PRId64 ") should be %d.\n\n", __LINE__, 1077 outinfo.frames, BUFFER_LEN 1078 ) ; 1079 1080 /* Read file making sure no channel map exists. */ 1081 memset (&ininfo, 0, sizeof (ininfo)) ; 1082 infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ; 1083 1084 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; 1085 1086 sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ; 1087 1088 exit_if_true (ininfo.frames != BUFFER_LEN, 1089 "\n\nLine %d : Initial sfinfo.frames (%" PRId64 ") should be %d.\n\n", __LINE__, 1090 ininfo.frames, BUFFER_LEN 1091 ) ; 1092 1093 sf_close (outfile) ; 1094 sf_close (infile) ; 1095 1096 unlink (filename) ; 1097 puts ("ok") ; 1098} /* current_sf_info_test */ 1099 1100static void 1101broadcast_test (const char *filename, int filetype) 1102{ static SF_BROADCAST_INFO bc_write, bc_read ; 1103 SNDFILE *file ; 1104 SF_INFO sfinfo ; 1105 int errors = 0 ; 1106 1107 print_test_name ("broadcast_test", filename) ; 1108 1109 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1110 sfinfo.samplerate = 11025 ; 1111 sfinfo.format = filetype ; 1112 sfinfo.channels = 1 ; 1113 1114 memset (&bc_write, 0, sizeof (bc_write)) ; 1115 1116 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; 1117 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; 1118 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; 1119 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; 1120 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; 1121 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; 1122 bc_write.coding_history_size = 0 ; 1123 1124 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1125 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) 1126 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1127 exit (1) ; 1128 } ; 1129 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1130 sf_close (file) ; 1131 1132 memset (&bc_read, 0, sizeof (bc_read)) ; 1133 1134 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1135 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) 1136 { printf ("\n\nLine %d : sf_command (SFC_GET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1137 exit (1) ; 1138 return ; 1139 } ; 1140 check_log_buffer_or_die (file, __LINE__) ; 1141 sf_close (file) ; 1142 1143 if (bc_read.version != 2) 1144 { printf ("\n\nLine %d : Read bad version number %d.\n\n", __LINE__, bc_read.version) ; 1145 exit (1) ; 1146 return ; 1147 } ; 1148 1149 bc_read.version = bc_write.version = 0 ; 1150 1151 if (memcmp (bc_write.description, bc_read.description, sizeof (bc_write.description)) != 0) 1152 { printf ("\n\nLine %d : description mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.description, bc_read.description) ; 1153 errors ++ ; 1154 } ; 1155 1156 if (memcmp (bc_write.originator, bc_read.originator, sizeof (bc_write.originator)) != 0) 1157 { printf ("\n\nLine %d : originator mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator, bc_read.originator) ; 1158 errors ++ ; 1159 } ; 1160 1161 if (memcmp (bc_write.originator_reference, bc_read.originator_reference, sizeof (bc_write.originator_reference)) != 0) 1162 { printf ("\n\nLine %d : originator_reference mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator_reference, bc_read.originator_reference) ; 1163 errors ++ ; 1164 } ; 1165 1166 if (memcmp (bc_write.origination_date, bc_read.origination_date, sizeof (bc_write.origination_date)) != 0) 1167 { printf ("\n\nLine %d : origination_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_date, bc_read.origination_date) ; 1168 errors ++ ; 1169 } ; 1170 1171 if (memcmp (bc_write.origination_time, bc_read.origination_time, sizeof (bc_write.origination_time)) != 0) 1172 { printf ("\n\nLine %d : origination_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_time, bc_read.origination_time) ; 1173 errors ++ ; 1174 } ; 1175 1176 if (memcmp (bc_write.umid, bc_read.umid, sizeof (bc_write.umid)) != 0) 1177 { printf ("\n\nLine %d : umid mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.umid, bc_read.umid) ; 1178 errors ++ ; 1179 } ; 1180 1181 if (errors) 1182 exit (1) ; 1183 1184 unlink (filename) ; 1185 puts ("ok") ; 1186} /* broadcast_test */ 1187 1188static void 1189broadcast_rdwr_test (const char *filename, int filetype) 1190{ SF_BROADCAST_INFO binfo ; 1191 SNDFILE *file ; 1192 SF_INFO sfinfo ; 1193 sf_count_t frames ; 1194 1195 print_test_name (__func__, filename) ; 1196 1197 create_short_sndfile (filename, filetype, 2) ; 1198 1199 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1200 memset (&binfo, 0, sizeof (binfo)) ; 1201 1202 snprintf (binfo.description, sizeof (binfo.description), "Test description") ; 1203 snprintf (binfo.originator, sizeof (binfo.originator), "Test originator") ; 1204 snprintf (binfo.originator_reference, sizeof (binfo.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; 1205 snprintf (binfo.origination_date, sizeof (binfo.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; 1206 snprintf (binfo.origination_time, sizeof (binfo.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; 1207 snprintf (binfo.umid, sizeof (binfo.umid), "Some umid") ; 1208 binfo.coding_history_size = 0 ; 1209 1210 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; 1211 frames = sfinfo.frames ; 1212 if (sf_command (file, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) != SF_FALSE) 1213 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) should have failed but didn't.\n\n", __LINE__) ; 1214 exit (1) ; 1215 } ; 1216 sf_close (file) ; 1217 1218 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1219 sf_close (file) ; 1220 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; 1221 1222 unlink (filename) ; 1223 puts ("ok") ; 1224} /* broadcast_rdwr_test */ 1225 1226static void 1227check_coding_history_newlines (const char *filename) 1228{ static SF_BROADCAST_INFO bc_write, bc_read ; 1229 SNDFILE *file ; 1230 SF_INFO sfinfo ; 1231 unsigned k ; 1232 1233 sfinfo.samplerate = 22050 ; 1234 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; 1235 sfinfo.channels = 1 ; 1236 1237 memset (&bc_write, 0, sizeof (bc_write)) ; 1238 1239 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; 1240 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; 1241 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; 1242 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; 1243 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; 1244 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; 1245 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") ; ; 1246 1247 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1248 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) 1249 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1250 exit (1) ; 1251 } ; 1252 1253 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1254 sf_close (file) ; 1255 1256 memset (&bc_read, 0, sizeof (bc_read)) ; 1257 1258 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1259 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) 1260 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1261 exit (1) ; 1262 } ; 1263 check_log_buffer_or_die (file, __LINE__) ; 1264 sf_close (file) ; 1265 1266 if (bc_read.coding_history_size == 0) 1267 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ; 1268 exit (1) ; 1269 } ; 1270 1271 if (strstr (bc_read.coding_history, "Last line") == NULL) 1272 { printf ("\n\nLine %d : coding history truncated.\n\n", __LINE__) ; 1273 exit (1) ; 1274 } ; 1275 1276 for (k = 1 ; k < bc_read.coding_history_size ; k++) 1277 { if (bc_read.coding_history [k] == '\n' && bc_read.coding_history [k - 1] != '\r') 1278 { printf ("\n\nLine %d : '\\n' without '\\r' before.\n\n", __LINE__) ; 1279 exit (1) ; 1280 } ; 1281 1282 if (bc_read.coding_history [k] == '\r' && bc_read.coding_history [k + 1] != '\n') 1283 { printf ("\n\nLine %d : '\\r' without '\\n' after.\n\n", __LINE__) ; 1284 exit (1) ; 1285 } ; 1286 1287 if (bc_read.coding_history [k] == 0 && k < bc_read.coding_history_size - 1) 1288 { printf ("\n\nLine %d : '\\0' within coding history at index %d of %d.\n\n", __LINE__, k, bc_read.coding_history_size) ; 1289 exit (1) ; 1290 } ; 1291 } ; 1292 1293 return ; 1294} /* check_coding_history_newlines */ 1295 1296static void 1297broadcast_coding_history_test (const char *filename) 1298{ static SF_BROADCAST_INFO bc_write, bc_read ; 1299 SNDFILE *file ; 1300 SF_INFO sfinfo ; 1301 const char *default_history = "A=PCM,F=22050,W=16,M=mono" ; 1302 const char *supplied_history = 1303 "A=PCM,F=44100,W=24,M=mono,T=other\r\n" 1304 "A=PCM,F=22050,W=16,M=mono,T=yet_another\r\n" ; 1305 1306 print_test_name ("broadcast_coding_history_test", filename) ; 1307 1308 sfinfo.samplerate = 22050 ; 1309 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; 1310 sfinfo.channels = 1 ; 1311 1312 memset (&bc_write, 0, sizeof (bc_write)) ; 1313 1314 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; 1315 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; 1316 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; 1317 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; 1318 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; 1319 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; 1320 /* Coding history will be filled in by the library. */ 1321 bc_write.coding_history_size = 0 ; 1322 1323 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1324 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) 1325 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1326 exit (1) ; 1327 } ; 1328 1329 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1330 sf_close (file) ; 1331 1332 memset (&bc_read, 0, sizeof (bc_read)) ; 1333 1334 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1335 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) 1336 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1337 exit (1) ; 1338 } ; 1339 check_log_buffer_or_die (file, __LINE__) ; 1340 sf_close (file) ; 1341 1342 if (bc_read.coding_history_size == 0) 1343 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ; 1344 exit (1) ; 1345 } ; 1346 1347 if (bc_read.coding_history_size < strlen (default_history) || memcmp (bc_read.coding_history, default_history, strlen (default_history)) != 0) 1348 { printf ("\n\n" 1349 "Line %d : unexpected coding history '%.*s',\n" 1350 " should be '%s'\n\n", __LINE__, bc_read.coding_history_size, bc_read.coding_history, default_history) ; 1351 exit (1) ; 1352 } ; 1353 1354 bc_write.coding_history_size = (uint32_t) strlen (supplied_history) ; 1355 bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "%s", supplied_history) ; 1356 1357 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1358 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) 1359 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1360 exit (1) ; 1361 } ; 1362 1363 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1364 sf_close (file) ; 1365 1366 memset (&bc_read, 0, sizeof (bc_read)) ; 1367 1368 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1369 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) 1370 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1371 exit (1) ; 1372 } ; 1373 1374 check_log_buffer_or_die (file, __LINE__) ; 1375 sf_close (file) ; 1376 1377 if (strstr (bc_read.coding_history, supplied_history) != bc_read.coding_history) 1378 { printf ("\n\nLine %d : unexpected coding history :\n" 1379 "----------------------------------------------------\n%s" 1380 "----------------------------------------------------\n" 1381 "should be this :\n" 1382 "----------------------------------------------------\n%s" 1383 "----------------------------------------------------\n" 1384 "with one more line at the end.\n\n", 1385 __LINE__, bc_read.coding_history, supplied_history) ; 1386 exit (1) ; 1387 } ; 1388 1389 check_coding_history_newlines (filename) ; 1390 1391 unlink (filename) ; 1392 puts ("ok") ; 1393} /* broadcast_coding_history_test */ 1394 1395/*============================================================================== 1396*/ 1397 1398static void 1399broadcast_coding_history_size (const char *filename) 1400{ /* SF_BROADCAST_INFO struct with coding_history field of 1024 bytes. */ 1401 static SF_BROADCAST_INFO_VAR (1024) bc_write ; 1402 static SF_BROADCAST_INFO_VAR (1024) bc_read ; 1403 SNDFILE *file ; 1404 SF_INFO sfinfo ; 1405 int k ; 1406 1407 print_test_name (__func__, filename) ; 1408 1409 sfinfo.samplerate = 22050 ; 1410 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; 1411 sfinfo.channels = 1 ; 1412 1413 memset (&bc_write, 0, sizeof (bc_write)) ; 1414 1415 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; 1416 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; 1417 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; 1418 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; 1419 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; 1420 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; 1421 bc_write.coding_history_size = 0 ; 1422 1423 for (k = 0 ; bc_write.coding_history_size < 512 ; k++) 1424 { snprintf (bc_write.coding_history + bc_write.coding_history_size, 1425 sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4d\n", k) ; 1426 bc_write.coding_history_size = (uint32_t) strlen (bc_write.coding_history) ; 1427 } ; 1428 1429 exit_if_true (bc_write.coding_history_size < 512, 1430 "\n\nLine %d : bc_write.coding_history_size (%d) should be > 512.\n\n", __LINE__, bc_write.coding_history_size) ; 1431 1432 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1433 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) 1434 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1435 exit (1) ; 1436 } ; 1437 1438 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1439 sf_close (file) ; 1440 1441 memset (&bc_read, 0, sizeof (bc_read)) ; 1442 1443 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1444 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) 1445 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; 1446 exit (1) ; 1447 } ; 1448 check_log_buffer_or_die (file, __LINE__) ; 1449 sf_close (file) ; 1450 1451 exit_if_true (bc_read.coding_history_size < 512, 1452 "\n\nLine %d : unexpected coding history size %d (should be > 512).\n\n", __LINE__, bc_read.coding_history_size) ; 1453 1454 exit_if_true (strstr (bc_read.coding_history, "libsndfile") == NULL, 1455 "\n\nLine %d : coding history incomplete (should contain 'libsndfile').\n\n", __LINE__) ; 1456 1457 unlink (filename) ; 1458 puts ("ok") ; 1459} /* broadcast_coding_history_size */ 1460 1461/*============================================================================== 1462*/ 1463static void 1464cart_test (const char *filename, int filetype) 1465{ static SF_CART_INFO ca_write, ca_read ; 1466 SNDFILE *file ; 1467 SF_INFO sfinfo ; 1468 int errors = 0 ; 1469 1470 print_test_name ("cart_test", filename) ; 1471 1472 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1473 sfinfo.samplerate = 11025 ; 1474 sfinfo.format = filetype ; 1475 sfinfo.channels = 1 ; 1476 memset (&ca_write, 0, sizeof (ca_write)) ; 1477 1478 // example test data 1479 snprintf (ca_write.artist, sizeof (ca_write.artist), "Test artist") ; 1480 snprintf (ca_write.version, sizeof (ca_write.version), "Test version") ; 1481 snprintf (ca_write.cut_id, sizeof (ca_write.cut_id), "Test cut ID") ; 1482 snprintf (ca_write.client_id, sizeof (ca_write.client_id), "Test client ID") ; 1483 snprintf (ca_write.category, sizeof (ca_write.category), "Test category") ; 1484 snprintf (ca_write.classification, sizeof (ca_write.classification), "Test classification") ; 1485 snprintf (ca_write.out_cue, sizeof (ca_write.out_cue), "Test out cue") ; 1486 snprintf (ca_write.start_date, sizeof (ca_write.start_date), "%d/%02d/%02d", 2006, 3, 30) ; 1487 snprintf (ca_write.start_time, sizeof (ca_write.start_time), "%02d:%02d:%02d", 20, 27, 0) ; 1488 snprintf (ca_write.end_date, sizeof (ca_write.end_date), "%d/%02d/%02d", 2006, 3, 30) ; 1489 snprintf (ca_write.end_time, sizeof (ca_write.end_time), "%02d:%02d:%02d", 20, 27, 0) ; 1490 snprintf (ca_write.producer_app_id, sizeof (ca_write.producer_app_id), "Test producer app id") ; 1491 snprintf (ca_write.producer_app_version, sizeof (ca_write.producer_app_version), "Test producer app version") ; 1492 snprintf (ca_write.user_def, sizeof (ca_write.user_def), "test user def test test") ; 1493 ca_write.level_reference = 42 ; 1494 snprintf (ca_write.url, sizeof (ca_write.url), "http://www.test.com/test_url") ; 1495 snprintf (ca_write.tag_text, sizeof (ca_write.tag_text), "tag text test! \r\n") ; // must be terminated \r\n to be valid 1496 ca_write.tag_text_size = (uint32_t) strlen (ca_write.tag_text) ; 1497 1498 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1499 if (sf_command (file, SFC_SET_CART_INFO, &ca_write, sizeof (ca_write)) == SF_FALSE) 1500 exit (1) ; 1501 1502 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1503 sf_close (file) ; 1504 1505 memset (&ca_read, 0, sizeof (ca_read)) ; 1506 1507 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1508 if (sf_command (file, SFC_GET_CART_INFO, &ca_read, sizeof (ca_read)) == SF_FALSE) 1509 { printf ("\n\nLine %d : sf_command (SFC_GET_CART_INFO) failed.\n\n", __LINE__) ; 1510 exit (1) ; 1511 return ; 1512 } ; 1513 check_log_buffer_or_die (file, __LINE__) ; 1514 sf_close (file) ; 1515 1516 1517 if (memcmp (ca_write.artist, ca_read.artist, sizeof (ca_write.artist)) != 0) 1518 { printf ("\n\nLine %d : artist mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.artist, ca_read.artist) ; 1519 errors ++ ; 1520 } ; 1521 1522 if (memcmp (ca_write.version, ca_read.version, sizeof (ca_write.version)) != 0) 1523 { printf ("\n\nLine %d : version mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.version, ca_read.version) ; 1524 errors ++ ; 1525 } ; 1526 1527 if (memcmp (ca_write.title, ca_read.title, sizeof (ca_write.title)) != 0) 1528 { printf ("\n\nLine %d : title mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.title, ca_read.title) ; 1529 errors ++ ; 1530 } ; 1531 1532 if (memcmp (ca_write.cut_id, ca_read.cut_id, sizeof (ca_write.cut_id)) != 0) 1533 { printf ("\n\nLine %d : cut_id mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.cut_id, ca_read.cut_id) ; 1534 errors ++ ; 1535 } ; 1536 1537 if (memcmp (ca_write.client_id, ca_read.client_id, sizeof (ca_write.client_id)) != 0) 1538 { printf ("\n\nLine %d : client_id mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.client_id, ca_read.client_id) ; 1539 errors ++ ; 1540 } ; 1541 1542 if (memcmp (ca_write.category, ca_read.category, sizeof (ca_write.category)) != 0) 1543 { printf ("\n\nLine %d : category mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.category, ca_read.category) ; 1544 errors ++ ; 1545 } ; 1546 1547 if (memcmp (ca_write.out_cue, ca_read.out_cue, sizeof (ca_write.out_cue)) != 0) 1548 { printf ("\n\nLine %d : out_cue mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.out_cue, ca_read.out_cue) ; 1549 errors ++ ; 1550 } ; 1551 1552 if (memcmp (ca_write.start_date, ca_read.start_date, sizeof (ca_write.start_date)) != 0) 1553 { printf ("\n\nLine %d : start_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.start_date, ca_read.start_date) ; 1554 errors ++ ; 1555 } ; 1556 1557 1558 if (memcmp (ca_write.start_time, ca_read.start_time, sizeof (ca_write.start_time)) != 0) 1559 { printf ("\n\nLine %d : start_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.start_time, ca_read.start_time) ; 1560 errors ++ ; 1561 } ; 1562 1563 1564 if (memcmp (ca_write.end_date, ca_read.end_date, sizeof (ca_write.end_date)) != 0) 1565 { printf ("\n\nLine %d : end_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.end_date, ca_read.end_date) ; 1566 errors ++ ; 1567 } ; 1568 1569 1570 if (memcmp (ca_write.end_time, ca_read.end_time, sizeof (ca_write.end_time)) != 0) 1571 { printf ("\n\nLine %d : end_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.end_time, ca_read.end_time) ; 1572 errors ++ ; 1573 } ; 1574 1575 1576 if (memcmp (ca_write.producer_app_id, ca_read.producer_app_id, sizeof (ca_write.producer_app_id)) != 0) 1577 { 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) ; 1578 errors ++ ; 1579 } ; 1580 1581 1582 if (memcmp (ca_write.producer_app_version, ca_read.producer_app_version, sizeof (ca_write.producer_app_version)) != 0) 1583 { 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) ; 1584 errors ++ ; 1585 } ; 1586 1587 1588 if (memcmp (ca_write.user_def, ca_read.user_def, sizeof (ca_write.user_def)) != 0) 1589 { printf ("\n\nLine %d : user_def mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.user_def, ca_read.user_def) ; 1590 errors ++ ; 1591 } ; 1592 1593 1594 if (ca_write.level_reference != ca_read.level_reference) 1595 { printf ("\n\nLine %d : level_reference mismatch :\n\twrite : '%d'\n\tread : '%d'\n\n", __LINE__, ca_write.level_reference, ca_read.level_reference) ; 1596 errors ++ ; 1597 } ; 1598 1599 // TODO: make this more helpful 1600 if (memcmp (ca_write.post_timers, ca_read.post_timers, sizeof (ca_write.post_timers)) != 0) 1601 { printf ("\n\nLine %d : post_timers mismatch :\n'\n\n", __LINE__) ; 1602 errors ++ ; 1603 } ; 1604 1605 if (memcmp (ca_write.url, ca_read.url, sizeof (ca_write.url)) != 0) 1606 { printf ("\n\nLine %d : url mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.url, ca_read.url) ; 1607 errors ++ ; 1608 } ; 1609 1610 1611 if (memcmp (ca_write.tag_text, ca_read.tag_text, (size_t) (ca_read.tag_text_size)) != 0) 1612 { printf ("\n\nLine %d : tag_text mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, ca_write.tag_text, ca_read.tag_text) ; 1613 errors ++ ; 1614 } ; 1615 1616 1617 if (errors) 1618 exit (1) ; 1619 1620 unlink (filename) ; 1621 puts ("ok") ; 1622} /* cart_test */ 1623 1624static void 1625cart_rdwr_test (const char *filename, int filetype) 1626{ SF_CART_INFO cinfo ; 1627 SNDFILE *file ; 1628 SF_INFO sfinfo ; 1629 sf_count_t frames ; 1630 1631 print_test_name (__func__, filename) ; 1632 1633 create_short_sndfile (filename, filetype, 2) ; 1634 1635 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1636 memset (&cinfo, 0, sizeof (cinfo)) ; 1637 1638 snprintf (cinfo.artist, sizeof (cinfo.artist), "Test artist") ; 1639 snprintf (cinfo.version, sizeof (cinfo.version), "Test version") ; 1640 snprintf (cinfo.cut_id, sizeof (cinfo.cut_id), "Test cut ID") ; 1641 snprintf (cinfo.client_id, sizeof (cinfo.client_id), "Test client ID") ; 1642 snprintf (cinfo.category, sizeof (cinfo.category), "Test category") ; 1643 snprintf (cinfo.classification, sizeof (cinfo.classification), "Test classification") ; 1644 snprintf (cinfo.out_cue, sizeof (cinfo.out_cue), "Test out cue") ; 1645 snprintf (cinfo.start_date, sizeof (cinfo.start_date), "%d/%02d/%02d", 2006, 3, 30) ; 1646 snprintf (cinfo.start_time, sizeof (cinfo.start_time), "%02d:%02d:%02d", 20, 27, 0) ; 1647 snprintf (cinfo.end_date, sizeof (cinfo.end_date), "%d/%02d/%02d", 2006, 3, 30) ; 1648 snprintf (cinfo.end_time, sizeof (cinfo.end_time), "%02d:%02d:%02d", 20, 27, 0) ; 1649 snprintf (cinfo.producer_app_id, sizeof (cinfo.producer_app_id), "Test producer app id") ; 1650 snprintf (cinfo.producer_app_version, sizeof (cinfo.producer_app_version), "Test producer app version") ; 1651 snprintf (cinfo.user_def, sizeof (cinfo.user_def), "test user def test test") ; 1652 cinfo.level_reference = 42 ; 1653 snprintf (cinfo.url, sizeof (cinfo.url), "http://www.test.com/test_url") ; 1654 snprintf (cinfo.tag_text, sizeof (cinfo.tag_text), "tag text test!\r\n") ; 1655 cinfo.tag_text_size = (uint32_t) strlen (cinfo.tag_text) ; 1656 1657 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; 1658 frames = sfinfo.frames ; 1659 if (sf_command (file, SFC_SET_CART_INFO, &cinfo, sizeof (cinfo)) != SF_FALSE) 1660 { printf ("\n\nLine %d : sf_command (SFC_SET_CART_INFO) should have failed but didn't.\n\n", __LINE__) ; 1661 exit (1) ; 1662 } ; 1663 sf_close (file) ; 1664 1665 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1666 sf_close (file) ; 1667 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; 1668 1669 unlink (filename) ; 1670 puts ("ok") ; 1671} /* cart_rdwr_test */ 1672 1673/*============================================================================== 1674*/ 1675 1676static void 1677channel_map_test (const char *filename, int filetype) 1678{ SNDFILE *file ; 1679 SF_INFO sfinfo ; 1680 int channel_map_read [4], channel_map_write [4] = 1681 { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, 1682 SF_CHANNEL_MAP_REAR_CENTER 1683 } ; 1684 1685 print_test_name ("channel_map_test", filename) ; 1686 1687 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1688 sfinfo.samplerate = 11025 ; 1689 sfinfo.format = filetype ; 1690 sfinfo.channels = ARRAY_LEN (channel_map_read) ; 1691 1692 switch (filetype & SF_FORMAT_TYPEMASK) 1693 { /* WAVEX and RF64 have a default channel map, even if you don't specify one. */ 1694 case SF_FORMAT_WAVEX : 1695 case SF_FORMAT_RF64 : 1696 /* Write file without channel map. */ 1697 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1698 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1699 sf_close (file) ; 1700 1701 /* Read file making default channel map exists. */ 1702 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1703 exit_if_true ( 1704 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) == SF_FALSE, 1705 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should not have failed.\n\n", __LINE__ 1706 ) ; 1707 check_log_buffer_or_die (file, __LINE__) ; 1708 sf_close (file) ; 1709 break ; 1710 1711 default : 1712 break ; 1713 } ; 1714 1715 /* Write file with a channel map. */ 1716 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1717 exit_if_true ( 1718 sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE, 1719 "\n\nLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ 1720 ) ; 1721 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1722 sf_close (file) ; 1723 1724 /* Read file making sure no channel map exists. */ 1725 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1726 exit_if_true ( 1727 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_TRUE, 1728 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ 1729 ) ; 1730 check_log_buffer_or_die (file, __LINE__) ; 1731 sf_close (file) ; 1732 1733 exit_if_true ( 1734 memcmp (channel_map_read, channel_map_write, sizeof (channel_map_read)) != 0, 1735 "\n\nLine %d : Channel map read does not match channel map written.\n\n", __LINE__ 1736 ) ; 1737 1738 unlink (filename) ; 1739 puts ("ok") ; 1740} /* channel_map_test */ 1741 1742static void 1743raw_needs_endswap_test (const char *filename, int filetype) 1744{ static int subtypes [] = 1745 { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, 1746 SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 1747 } ; 1748 SNDFILE *file ; 1749 SF_INFO sfinfo ; 1750 unsigned k ; 1751 int needs_endswap ; 1752 1753 print_test_name (__func__, filename) ; 1754 1755 for (k = 0 ; k < ARRAY_LEN (subtypes) ; k++) 1756 { 1757 if (filetype == (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF)) 1758 switch (subtypes [k]) 1759 { /* Little endian AIFF does not AFAIK support fl32 and fl64. */ 1760 case SF_FORMAT_FLOAT : 1761 case SF_FORMAT_DOUBLE : 1762 continue ; 1763 default : 1764 break ; 1765 } ; 1766 1767 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1768 sfinfo.samplerate = 11025 ; 1769 sfinfo.format = filetype | subtypes [k] ; 1770 sfinfo.channels = 1 ; 1771 1772 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1773 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; 1774 sf_close (file) ; 1775 1776 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1777 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 1778 1779 needs_endswap = sf_command (file, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0) ; 1780 1781 switch (filetype) 1782 { case SF_FORMAT_WAV : 1783 case SF_FORMAT_WAVEX : 1784 case SF_FORMAT_AIFF | SF_ENDIAN_LITTLE : 1785 exit_if_true (needs_endswap != CPU_IS_BIG_ENDIAN, 1786 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; 1787 break ; 1788 1789 case SF_FORMAT_AIFF : 1790 case SF_FORMAT_WAV | SF_ENDIAN_BIG : 1791 exit_if_true (needs_endswap != CPU_IS_LITTLE_ENDIAN, 1792 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; 1793 break ; 1794 1795 default : 1796 printf ("\n\nLine %d : bad format value %d.\n\n", __LINE__, filetype) ; 1797 exit (1) ; 1798 break ; 1799 } ; 1800 1801 sf_close (file) ; 1802 } ; 1803 1804 unlink (filename) ; 1805 puts ("ok") ; 1806} /* raw_needs_endswap_test */ 1807