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