annotate src/libsndfile-1.0.25/tests/utils.tpl @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents c7265573341e
children
rev   line source
Chris@0 1 [+ AutoGen5 template h c +]
Chris@0 2 /*
Chris@0 3 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@0 4 **
Chris@0 5 ** This program is free software; you can redistribute it and/or modify
Chris@0 6 ** it under the terms of the GNU General Public License as published by
Chris@0 7 ** the Free Software Foundation; either version 2 of the License, or
Chris@0 8 ** (at your option) any later version.
Chris@0 9 **
Chris@0 10 ** This program is distributed in the hope that it will be useful,
Chris@0 11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 13 ** GNU General Public License for more details.
Chris@0 14 **
Chris@0 15 ** You should have received a copy of the GNU General Public License
Chris@0 16 ** along with this program; if not, write to the Free Software
Chris@0 17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Chris@0 18 */
Chris@0 19
Chris@0 20 /*
Chris@0 21 ** Utility functions to make writing the test suite easier.
Chris@0 22 **
Chris@0 23 ** The .c and .h files were generated automagically with Autogen from
Chris@0 24 ** the files utils.def and utils.tpl.
Chris@0 25 */
Chris@0 26
Chris@0 27 [+ CASE (suffix) +]
Chris@0 28 [+ == h +]
Chris@0 29
Chris@0 30 #ifdef __cplusplus
Chris@0 31 extern "C" {
Chris@0 32 #endif /* __cplusplus */
Chris@0 33
Chris@0 34 #include <stdint.h>
Chris@0 35 #include <stdarg.h>
Chris@0 36
Chris@0 37 #define SF_COUNT_TO_LONG(x) ((long) (x))
Chris@0 38 #define ARRAY_LEN(x) ((int) (sizeof (x)) / (sizeof ((x) [0])))
Chris@0 39 #define SIGNED_SIZEOF(x) ((int64_t) (sizeof (x)))
Chris@0 40 #define NOT(x) (! (x))
Chris@0 41
Chris@0 42 #define PIPE_INDEX(x) ((x) + 500)
Chris@0 43 #define PIPE_TEST_LEN 12345
Chris@0 44
Chris@0 45
Chris@0 46 [+ FOR float_type
Chris@0 47 +]void gen_windowed_sine_[+ (get "name") +] ([+ (get "name") +] *data, int len, double maximum) ;
Chris@0 48 [+ ENDFOR float_type
Chris@0 49 +]
Chris@0 50
Chris@0 51 void create_short_sndfile (const char *filename, int format, int channels) ;
Chris@0 52
Chris@0 53 void check_file_hash_or_die (const char *filename, uint64_t target_hash, int line_num) ;
Chris@0 54
Chris@0 55 void print_test_name (const char *test, const char *filename) ;
Chris@0 56
Chris@0 57 void dump_data_to_file (const char *filename, const void *data, unsigned int datalen) ;
Chris@0 58
Chris@0 59 void write_mono_file (const char * filename, int format, int srate, float * output, int len) ;
Chris@0 60
Chris@0 61 static inline void
Chris@0 62 exit_if_true (int test, const char *format, ...)
Chris@0 63 { if (test)
Chris@0 64 { va_list argptr ;
Chris@0 65 va_start (argptr, format) ;
Chris@0 66 vprintf (format, argptr) ;
Chris@0 67 va_end (argptr) ;
Chris@0 68 exit (1) ;
Chris@0 69 } ;
Chris@0 70 } /* exit_if_true */
Chris@0 71
Chris@0 72 /*
Chris@0 73 ** Functions for saving two vectors of data in an ascii text file which
Chris@0 74 ** can then be loaded into GNU octave for comparison.
Chris@0 75 */
Chris@0 76
Chris@0 77 [+ FOR io_type
Chris@0 78 +]int oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len) ;
Chris@0 79 [+ ENDFOR io_type
Chris@0 80 +]
Chris@0 81
Chris@0 82 void delete_file (int format, const char *filename) ;
Chris@0 83
Chris@0 84 void count_open_files (void) ;
Chris@0 85 void increment_open_file_count (void) ;
Chris@0 86 void check_open_file_count_or_die (int lineno) ;
Chris@0 87
Chris@0 88 #ifdef SNDFILE_H
Chris@0 89
Chris@0 90 static inline void
Chris@0 91 sf_info_clear (SF_INFO * info)
Chris@0 92 { memset (info, 0, sizeof (SF_INFO)) ;
Chris@0 93 } /* sf_info_clear */
Chris@0 94
Chris@0 95 static inline void
Chris@0 96 sf_info_setup (SF_INFO * info, int format, int samplerate, int channels)
Chris@0 97 { sf_info_clear (info) ;
Chris@0 98
Chris@0 99 info->format = format ;
Chris@0 100 info->samplerate = samplerate ;
Chris@0 101 info->channels = channels ;
Chris@0 102 } /* sf_info_setup */
Chris@0 103
Chris@0 104
Chris@0 105 void dump_log_buffer (SNDFILE *file) ;
Chris@0 106 void check_log_buffer_or_die (SNDFILE *file, int line_num) ;
Chris@0 107 int string_in_log_buffer (SNDFILE *file, const char *s) ;
Chris@0 108 void hexdump_file (const char * filename, sf_count_t offset, sf_count_t length) ;
Chris@0 109
Chris@0 110
Chris@0 111 SNDFILE *test_open_file_or_die
Chris@0 112 (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num) ;
Chris@0 113
Chris@0 114 void test_read_write_position_or_die
Chris@0 115 (SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos) ;
Chris@0 116
Chris@0 117 void test_seek_or_die
Chris@0 118 (SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num) ;
Chris@0 119
Chris@0 120 [+ FOR read_op +]
Chris@0 121 [+ FOR io_type
Chris@0 122 +]void test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die
Chris@0 123 (SNDFILE *file, int pass, [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
Chris@0 124 [+ ENDFOR io_type +][+ ENDFOR read_op +]
Chris@0 125
Chris@0 126 void
Chris@0 127 test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) ;
Chris@0 128
Chris@0 129 [+ FOR write_op +]
Chris@0 130 [+ FOR io_type
Chris@0 131 +]void test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die
Chris@0 132 (SNDFILE *file, int pass, const [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
Chris@0 133 [+ ENDFOR io_type +][+ ENDFOR write_op +]
Chris@0 134
Chris@0 135 void
Chris@0 136 test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num) ;
Chris@0 137
Chris@0 138 [+ FOR io_type
Chris@0 139 +]void compare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *left, const [+ (get "io_element") +] *right, unsigned count, int line_num) ;
Chris@0 140 [+ ENDFOR io_type +]
Chris@0 141
Chris@0 142
Chris@0 143 void gen_lowpass_noise_float (float *data, int len) ;
Chris@0 144
Chris@0 145 sf_count_t file_length (const char * fname) ;
Chris@0 146 sf_count_t file_length_fd (int fd) ;
Chris@0 147
Chris@0 148 #endif
Chris@0 149
Chris@0 150 #ifdef __cplusplus
Chris@0 151 } /* extern "C" */
Chris@0 152 #endif /* __cplusplus */
Chris@0 153
Chris@0 154 [+ == c +]
Chris@0 155
Chris@0 156 #include "sfconfig.h"
Chris@0 157
Chris@0 158 #include <stdio.h>
Chris@0 159 #include <stdlib.h>
Chris@0 160 #include <inttypes.h>
Chris@0 161
Chris@0 162 #if HAVE_UNISTD_H
Chris@0 163 #include <unistd.h>
Chris@0 164 #endif
Chris@0 165
Chris@0 166 #if (HAVE_DECL_S_IRGRP == 0)
Chris@0 167 #include <sf_unistd.h>
Chris@0 168 #endif
Chris@0 169
Chris@0 170 #include <errno.h>
Chris@0 171 #include <string.h>
Chris@0 172 #include <ctype.h>
Chris@0 173 #include <math.h>
Chris@0 174 #include <fcntl.h>
Chris@0 175 #include <sys/stat.h>
Chris@0 176
Chris@0 177 #include <sndfile.h>
Chris@0 178
Chris@0 179 #include "utils.h"
Chris@0 180
Chris@0 181 #ifndef M_PI
Chris@0 182 #define M_PI 3.14159265358979323846264338
Chris@0 183 #endif
Chris@0 184
Chris@0 185 #define LOG_BUFFER_SIZE 2048
Chris@0 186
Chris@0 187 /*
Chris@0 188 ** Neat solution to the Win32/OS2 binary file flage requirement.
Chris@0 189 ** If O_BINARY isn't already defined by the inclusion of the system
Chris@0 190 ** headers, set it to zero.
Chris@0 191 */
Chris@0 192 #ifndef O_BINARY
Chris@0 193 #define O_BINARY 0
Chris@0 194 #endif
Chris@0 195
Chris@0 196 [+ FOR float_type +]
Chris@0 197 void
Chris@0 198 gen_windowed_sine_[+ (get "name") +] ([+ (get "name") +] *data, int len, double maximum)
Chris@0 199 { int k ;
Chris@0 200
Chris@0 201 memset (data, 0, len * sizeof ([+ (get "name") +])) ;
Chris@0 202 /*
Chris@0 203 ** Choose a frequency of 1/32 so that it aligns perfectly with a DFT
Chris@0 204 ** bucket to minimise spreading of energy over more than one bucket.
Chris@0 205 ** Also do not want to make the frequency too high as some of the
Chris@0 206 ** codecs (ie gsm610) have a quite severe high frequency roll off.
Chris@0 207 */
Chris@0 208 len /= 2 ;
Chris@0 209
Chris@0 210 for (k = 0 ; k < len ; k++)
Chris@0 211 { data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ;
Chris@0 212
Chris@0 213 /* Apply Hanning Window. */
Chris@0 214 data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ;
Chris@0 215 }
Chris@0 216
Chris@0 217 return ;
Chris@0 218 } /* gen_windowed_sine_[+ (get "name") +] */
Chris@0 219 [+ ENDFOR float_type +]
Chris@0 220
Chris@0 221 void
Chris@0 222 create_short_sndfile (const char *filename, int format, int channels)
Chris@0 223 { short data [2 * 3 * 4 * 5 * 6 * 7] = { 0, } ;
Chris@0 224 SNDFILE *file ;
Chris@0 225 SF_INFO sfinfo ;
Chris@0 226
Chris@0 227 sfinfo.samplerate = 44100 ;
Chris@0 228 sfinfo.channels = channels ;
Chris@0 229 sfinfo.format = format ;
Chris@0 230
Chris@0 231 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
Chris@0 232 { printf ("Error (%s, %d) : sf_open failed : %s\n", __FILE__, __LINE__, sf_strerror (file)) ;
Chris@0 233 exit (1) ;
Chris@0 234 } ;
Chris@0 235
Chris@0 236 sf_write_short (file, data, ARRAY_LEN (data)) ;
Chris@0 237
Chris@0 238 sf_close (file) ;
Chris@0 239 } /* create_short_sndfile */
Chris@0 240
Chris@0 241 void
Chris@0 242 check_file_hash_or_die (const char *filename, uint64_t target_hash, int line_num)
Chris@0 243 { static unsigned char buf [4096] ;
Chris@0 244 uint64_t cksum ;
Chris@0 245 FILE *file ;
Chris@0 246 int k, read_count ;
Chris@0 247
Chris@0 248 memset (buf, 0, sizeof (buf)) ;
Chris@0 249
Chris@0 250 /* The 'b' in the mode string means binary for Win32. */
Chris@0 251 if ((file = fopen (filename, "rb")) == NULL)
Chris@0 252 { printf ("\n\nLine %d: could not open file '%s'\n\n", line_num, filename) ;
Chris@0 253 exit (1) ;
Chris@0 254 } ;
Chris@0 255
Chris@0 256 cksum = 0 ;
Chris@0 257
Chris@0 258 while ((read_count = fread (buf, 1, sizeof (buf), file)))
Chris@0 259 for (k = 0 ; k < read_count ; k++)
Chris@0 260 cksum = cksum * 511 + buf [k] ;
Chris@0 261
Chris@0 262 fclose (file) ;
Chris@0 263
Chris@0 264 if (target_hash == 0)
Chris@0 265 { printf (" 0x%016" PRIx64 "\n", cksum) ;
Chris@0 266 return ;
Chris@0 267 } ;
Chris@0 268
Chris@0 269 if (cksum != target_hash)
Chris@0 270 { printf ("\n\nLine %d: incorrect hash value 0x%016" PRIx64 " should be 0x%016" PRIx64 ".\n\n", line_num, cksum, target_hash) ;
Chris@0 271 exit (1) ;
Chris@0 272 } ;
Chris@0 273
Chris@0 274 return ;
Chris@0 275 } /* check_file_hash_or_die */
Chris@0 276
Chris@0 277 void
Chris@0 278 print_test_name (const char *test, const char *filename)
Chris@0 279 { int count ;
Chris@0 280
Chris@0 281 if (test == NULL)
Chris@0 282 { printf (__FILE__ ": bad test of filename parameter.\n") ;
Chris@0 283 exit (1) ;
Chris@0 284 } ;
Chris@0 285
Chris@0 286 if (filename == NULL || strlen (filename) == 0)
Chris@0 287 { printf (" %-30s : ", test) ;
Chris@0 288 count = 25 ;
Chris@0 289 }
Chris@0 290 else
Chris@0 291 { printf (" %-30s : %s ", test, filename) ;
Chris@0 292 count = 24 - strlen (filename) ;
Chris@0 293 } ;
Chris@0 294
Chris@0 295 while (count -- > 0)
Chris@0 296 putchar ('.') ;
Chris@0 297 putchar (' ') ;
Chris@0 298
Chris@0 299 fflush (stdout) ;
Chris@0 300 } /* print_test_name */
Chris@0 301
Chris@0 302 void
Chris@0 303 dump_data_to_file (const char *filename, const void *data, unsigned int datalen)
Chris@0 304 { FILE *file ;
Chris@0 305
Chris@0 306 if ((file = fopen (filename, "wb")) == NULL)
Chris@0 307 { printf ("\n\nLine %d : could not open file : %s\n\n", __LINE__, filename) ;
Chris@0 308 exit (1) ;
Chris@0 309 } ;
Chris@0 310
Chris@0 311 if (fwrite (data, 1, datalen, file) != datalen)
Chris@0 312 { printf ("\n\nLine %d : fwrite failed.\n\n", __LINE__) ;
Chris@0 313 exit (1) ;
Chris@0 314 } ;
Chris@0 315
Chris@0 316 fclose (file) ;
Chris@0 317
Chris@0 318 } /* dump_data_to_file */
Chris@0 319
Chris@0 320 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Chris@0 321 */
Chris@0 322
Chris@0 323 static char octfilename [] = "error.dat" ;
Chris@0 324
Chris@0 325 [+ FOR io_type
Chris@0 326 +]int
Chris@0 327 oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len)
Chris@0 328 { FILE *file ;
Chris@0 329 int k ;
Chris@0 330
Chris@0 331 if (! (file = fopen (octfilename, "w")))
Chris@0 332 return 1 ;
Chris@0 333
Chris@0 334 fprintf (file, "# Not created by Octave\n") ;
Chris@0 335
Chris@0 336 fprintf (file, "# name: a\n") ;
Chris@0 337 fprintf (file, "# type: matrix\n") ;
Chris@0 338 fprintf (file, "# rows: %d\n", len) ;
Chris@0 339 fprintf (file, "# columns: 1\n") ;
Chris@0 340
Chris@0 341 for (k = 0 ; k < len ; k++)
Chris@0 342 fprintf (file, [+ (get "format_str") +] "\n", a [k]) ;
Chris@0 343
Chris@0 344 fprintf (file, "# name: b\n") ;
Chris@0 345 fprintf (file, "# type: matrix\n") ;
Chris@0 346 fprintf (file, "# rows: %d\n", len) ;
Chris@0 347 fprintf (file, "# columns: 1\n") ;
Chris@0 348
Chris@0 349 for (k = 0 ; k < len ; k++)
Chris@0 350 fprintf (file, [+ (get "format_str") +] "\n", b [k]) ;
Chris@0 351
Chris@0 352 fclose (file) ;
Chris@0 353 return 0 ;
Chris@0 354 } /* oct_save_[+ (get "io_element") +] */
Chris@0 355 [+ ENDFOR io_type
Chris@0 356 +]
Chris@0 357
Chris@0 358 void
Chris@0 359 check_log_buffer_or_die (SNDFILE *file, int line_num)
Chris@0 360 { static char buffer [LOG_BUFFER_SIZE] ;
Chris@0 361 int count ;
Chris@0 362
Chris@0 363 memset (buffer, 0, sizeof (buffer)) ;
Chris@0 364
Chris@0 365 /* Get the log buffer data. */
Chris@0 366 count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
Chris@0 367
Chris@0 368 if (LOG_BUFFER_SIZE - count < 2)
Chris@0 369 { printf ("\n\nLine %d : Possible long log buffer.\n", line_num) ;
Chris@0 370 exit (1) ;
Chris@0 371 }
Chris@0 372
Chris@0 373 /* Look for "Should" */
Chris@0 374 if (strstr (buffer, "ould"))
Chris@0 375 { printf ("\n\nLine %d : Log buffer contains `ould'. Dumping.\n", line_num) ;
Chris@0 376 puts (buffer) ;
Chris@0 377 exit (1) ;
Chris@0 378 } ;
Chris@0 379
Chris@0 380 /* Look for "**" */
Chris@0 381 if (strstr (buffer, "*"))
Chris@0 382 { printf ("\n\nLine %d : Log buffer contains `*'. Dumping.\n", line_num) ;
Chris@0 383 puts (buffer) ;
Chris@0 384 exit (1) ;
Chris@0 385 } ;
Chris@0 386
Chris@0 387 /* Look for "Should" */
Chris@0 388 if (strstr (buffer, "nknown marker"))
Chris@0 389 { printf ("\n\nLine %d : Log buffer contains `nknown marker'. Dumping.\n", line_num) ;
Chris@0 390 puts (buffer) ;
Chris@0 391 exit (1) ;
Chris@0 392 } ;
Chris@0 393
Chris@0 394 return ;
Chris@0 395 } /* check_log_buffer_or_die */
Chris@0 396
Chris@0 397 int
Chris@0 398 string_in_log_buffer (SNDFILE *file, const char *s)
Chris@0 399 { static char buffer [LOG_BUFFER_SIZE] ;
Chris@0 400 int count ;
Chris@0 401
Chris@0 402 memset (buffer, 0, sizeof (buffer)) ;
Chris@0 403
Chris@0 404 /* Get the log buffer data. */
Chris@0 405 count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
Chris@0 406
Chris@0 407 if (LOG_BUFFER_SIZE - count < 2)
Chris@0 408 { printf ("Possible long log buffer.\n") ;
Chris@0 409 exit (1) ;
Chris@0 410 }
Chris@0 411
Chris@0 412 /* Look for string */
Chris@0 413 return strstr (buffer, s) ? SF_TRUE : SF_FALSE ;
Chris@0 414 } /* string_in_log_buffer */
Chris@0 415
Chris@0 416 void
Chris@0 417 hexdump_file (const char * filename, sf_count_t offset, sf_count_t length)
Chris@0 418 {
Chris@0 419 FILE * file ;
Chris@0 420 char buffer [16] ;
Chris@0 421 int k, m, ch, readcount ;
Chris@0 422
Chris@0 423 if (length > 1000000)
Chris@0 424 { printf ("\n\nError : length (%ld) too long.\n\n", SF_COUNT_TO_LONG (offset)) ;
Chris@0 425 exit (1) ;
Chris@0 426 } ;
Chris@0 427
Chris@0 428 if ((file = fopen (filename, "r")) == NULL)
Chris@0 429 { printf ("\n\nError : hexdump_file (%s) could not open file for read.\n\n", filename) ;
Chris@0 430 exit (1) ;
Chris@0 431 } ;
Chris@0 432
Chris@0 433 if (fseek (file, offset, SEEK_SET) != 0)
Chris@0 434 { printf ("\n\nError : fseek(file, %ld, SEEK_SET) failed : %s\n\n", SF_COUNT_TO_LONG (offset), strerror (errno)) ;
Chris@0 435 exit (1) ;
Chris@0 436 } ;
Chris@0 437
Chris@0 438 puts ("\n\n") ;
Chris@0 439
Chris@0 440 for (k = 0 ; k < length ; k+= sizeof (buffer))
Chris@0 441 { readcount = fread (buffer, 1, sizeof (buffer), file) ;
Chris@0 442
Chris@0 443 printf ("%08lx : ", SF_COUNT_TO_LONG (offset + k)) ;
Chris@0 444
Chris@0 445 for (m = 0 ; m < readcount ; m++)
Chris@0 446 printf ("%02x ", buffer [m] & 0xFF) ;
Chris@0 447
Chris@0 448 for (m = readcount ; m < SIGNED_SIZEOF (buffer) ; m++)
Chris@0 449 printf (" ") ;
Chris@0 450
Chris@0 451 printf (" ") ;
Chris@0 452 for (m = 0 ; m < readcount ; m++)
Chris@0 453 { ch = isprint (buffer [m]) ? buffer [m] : '.' ;
Chris@0 454 putchar (ch) ;
Chris@0 455 } ;
Chris@0 456
Chris@0 457 if (readcount < SIGNED_SIZEOF (buffer))
Chris@0 458 break ;
Chris@0 459
Chris@0 460 putchar ('\n') ;
Chris@0 461 } ;
Chris@0 462
Chris@0 463 puts ("\n") ;
Chris@0 464
Chris@0 465 fclose (file) ;
Chris@0 466 } /* hexdump_file */
Chris@0 467
Chris@0 468 void
Chris@0 469 dump_log_buffer (SNDFILE *file)
Chris@0 470 { static char buffer [LOG_BUFFER_SIZE] ;
Chris@0 471
Chris@0 472 memset (buffer, 0, sizeof (buffer)) ;
Chris@0 473
Chris@0 474 /* Get the log buffer data. */
Chris@0 475 sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
Chris@0 476
Chris@0 477 if (strlen (buffer) < 1)
Chris@0 478 puts ("Log buffer empty.\n") ;
Chris@0 479 else
Chris@0 480 puts (buffer) ;
Chris@0 481
Chris@0 482 return ;
Chris@0 483 } /* dump_log_buffer */
Chris@0 484
Chris@0 485 SNDFILE *
Chris@0 486 test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num)
Chris@0 487 { static int count = 0 ;
Chris@0 488
Chris@0 489 SNDFILE *file ;
Chris@0 490 const char *modestr, *func_name ;
Chris@0 491 int oflags = 0, omode = 0, err ;
Chris@0 492
Chris@0 493 /*
Chris@0 494 ** Need to test both sf_open() and sf_open_fd().
Chris@0 495 ** Do so alternately.
Chris@0 496 */
Chris@0 497 switch (mode)
Chris@0 498 { case SFM_READ :
Chris@0 499 modestr = "SFM_READ" ;
Chris@0 500 oflags = O_RDONLY | O_BINARY ;
Chris@0 501 omode = 0 ;
Chris@0 502 break ;
Chris@0 503
Chris@0 504 case SFM_WRITE :
Chris@0 505 modestr = "SFM_WRITE" ;
Chris@0 506 oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
Chris@0 507 omode = S_IRUSR | S_IWUSR | S_IRGRP ;
Chris@0 508 break ;
Chris@0 509
Chris@0 510 case SFM_RDWR :
Chris@0 511 modestr = "SFM_RDWR" ;
Chris@0 512 oflags = O_RDWR | O_CREAT | O_BINARY ;
Chris@0 513 omode = S_IRUSR | S_IWUSR | S_IRGRP ;
Chris@0 514 break ;
Chris@0 515 default :
Chris@0 516 printf ("\n\nLine %d: Bad mode.\n", line_num) ;
Chris@0 517 fflush (stdout) ;
Chris@0 518 exit (1) ;
Chris@0 519 } ;
Chris@0 520
Chris@0 521 if (OS_IS_WIN32)
Chris@0 522 { /* Windows does not understand and ignores the S_IRGRP flag, but Wine
Chris@0 523 ** gives a run time warning message, so just clear it.
Chris@0 524 */
Chris@0 525 omode &= ~S_IRGRP ;
Chris@0 526 } ;
Chris@0 527
Chris@0 528 if (allow_fd && ((++count) & 1) == 1)
Chris@0 529 { int fd ;
Chris@0 530
Chris@0 531 /* Only use the three argument open() function if omode != 0. */
Chris@0 532 fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ;
Chris@0 533
Chris@0 534 if (fd < 0)
Chris@0 535 { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ;
Chris@0 536 exit (1) ;
Chris@0 537 } ;
Chris@0 538
Chris@0 539 func_name = "sf_open_fd" ;
Chris@0 540 file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ;
Chris@0 541 }
Chris@0 542 else
Chris@0 543 { func_name = "sf_open" ;
Chris@0 544 file = sf_open (filename, mode, sfinfo) ;
Chris@0 545 } ;
Chris@0 546
Chris@0 547 if (file == NULL)
Chris@0 548 { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ;
Chris@0 549 dump_log_buffer (file) ;
Chris@0 550 exit (1) ;
Chris@0 551 } ;
Chris@0 552
Chris@0 553 err = sf_error (file) ;
Chris@0 554 if (err != SF_ERR_NO_ERROR)
Chris@0 555 { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ;
Chris@0 556 dump_log_buffer (file) ;
Chris@0 557 exit (1) ;
Chris@0 558 } ;
Chris@0 559
Chris@0 560 return file ;
Chris@0 561 } /* test_open_file_or_die */
Chris@0 562
Chris@0 563 void
Chris@0 564 test_read_write_position_or_die (SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos)
Chris@0 565 { sf_count_t pos ;
Chris@0 566
Chris@0 567 /* Check the current read position. */
Chris@0 568 if (read_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_READ)) != read_pos)
Chris@0 569 { printf ("\n\nLine %d ", line_num) ;
Chris@0 570 if (pass > 0)
Chris@0 571 printf ("(pass %d): ", pass) ;
Chris@0 572 printf ("Read position (%ld) should be %ld.\n", SF_COUNT_TO_LONG (pos), SF_COUNT_TO_LONG (read_pos)) ;
Chris@0 573 exit (1) ;
Chris@0 574 } ;
Chris@0 575
Chris@0 576 /* Check the current write position. */
Chris@0 577 if (write_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_WRITE)) != write_pos)
Chris@0 578 { printf ("\n\nLine %d", line_num) ;
Chris@0 579 if (pass > 0)
Chris@0 580 printf (" (pass %d)", pass) ;
Chris@0 581 printf (" : Write position (%ld) should be %ld.\n",
Chris@0 582 SF_COUNT_TO_LONG (pos), SF_COUNT_TO_LONG (write_pos)) ;
Chris@0 583 exit (1) ;
Chris@0 584 } ;
Chris@0 585
Chris@0 586 return ;
Chris@0 587 } /* test_read_write_position */
Chris@0 588
Chris@0 589 void
Chris@0 590 test_seek_or_die (SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num)
Chris@0 591 { sf_count_t position ;
Chris@0 592 const char *channel_name, *whence_name ;
Chris@0 593
Chris@0 594 switch (whence)
Chris@0 595 { case SEEK_SET :
Chris@0 596 whence_name = "SEEK_SET" ;
Chris@0 597 break ;
Chris@0 598 case SEEK_CUR :
Chris@0 599 whence_name = "SEEK_CUR" ;
Chris@0 600 break ;
Chris@0 601 case SEEK_END :
Chris@0 602 whence_name = "SEEK_END" ;
Chris@0 603 break ;
Chris@0 604
Chris@0 605 /* SFM_READ */
Chris@0 606 case SEEK_SET | SFM_READ :
Chris@0 607 whence_name = "SFM_READ | SEEK_SET" ;
Chris@0 608 break ;
Chris@0 609 case SEEK_CUR | SFM_READ :
Chris@0 610 whence_name = "SFM_READ | SEEK_CUR" ;
Chris@0 611 break ;
Chris@0 612 case SEEK_END | SFM_READ :
Chris@0 613 whence_name = "SFM_READ | SEEK_END" ;
Chris@0 614 break ;
Chris@0 615
Chris@0 616 /* SFM_WRITE */
Chris@0 617 case SEEK_SET | SFM_WRITE :
Chris@0 618 whence_name = "SFM_WRITE | SEEK_SET" ;
Chris@0 619 break ;
Chris@0 620 case SEEK_CUR | SFM_WRITE :
Chris@0 621 whence_name = "SFM_WRITE | SEEK_CUR" ;
Chris@0 622 break ;
Chris@0 623 case SEEK_END | SFM_WRITE :
Chris@0 624 whence_name = "SFM_WRITE | SEEK_END" ;
Chris@0 625 break ;
Chris@0 626
Chris@0 627 default :
Chris@0 628 printf ("\n\nLine %d: bad whence parameter.\n", line_num) ;
Chris@0 629 exit (1) ;
Chris@0 630 } ;
Chris@0 631
Chris@0 632 channel_name = (channels == 1) ? "Mono" : "Stereo" ;
Chris@0 633
Chris@0 634 if ((position = sf_seek (file, offset, whence)) != new_pos)
Chris@0 635 { printf ("\n\nLine %d : %s : sf_seek (file, %ld, %s) returned %ld (should be %ld).\n\n",
Chris@0 636 line_num, channel_name, SF_COUNT_TO_LONG (offset), whence_name,
Chris@0 637 SF_COUNT_TO_LONG (position), SF_COUNT_TO_LONG (new_pos)) ;
Chris@0 638 exit (1) ;
Chris@0 639 } ;
Chris@0 640
Chris@0 641 } /* test_seek_or_die */
Chris@0 642
Chris@0 643 [+ FOR read_op +]
Chris@0 644 [+ FOR io_type +]
Chris@0 645 void
Chris@0 646 test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die (SNDFILE *file, int pass, [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num)
Chris@0 647 { sf_count_t count ;
Chris@0 648
Chris@0 649 if ((count = sf_[+ (get "op_element") +]_[+ (get "io_element") +] (file, test, [+ (get "count_name") +])) != [+ (get "count_name") +])
Chris@0 650 { printf ("\n\nLine %d", line_num) ;
Chris@0 651 if (pass > 0)
Chris@0 652 printf (" (pass %d)", pass) ;
Chris@0 653 printf (" : sf_[+ (get "op_element") +]_[+ (get "io_element") +] failed with short [+ (get "op_element") +] (%ld => %ld).\n",
Chris@0 654 SF_COUNT_TO_LONG ([+ (get "count_name") +]), SF_COUNT_TO_LONG (count)) ;
Chris@0 655 fflush (stdout) ;
Chris@0 656 puts (sf_strerror (file)) ;
Chris@0 657 exit (1) ;
Chris@0 658 } ;
Chris@0 659
Chris@0 660 return ;
Chris@0 661 } /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
Chris@0 662 [+ ENDFOR io_type +][+ ENDFOR read_op +]
Chris@0 663
Chris@0 664 void
Chris@0 665 test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num)
Chris@0 666 { sf_count_t count ;
Chris@0 667
Chris@0 668 if ((count = sf_read_raw (file, test, items)) != items)
Chris@0 669 { printf ("\n\nLine %d", line_num) ;
Chris@0 670 if (pass > 0)
Chris@0 671 printf (" (pass %d)", pass) ;
Chris@0 672 printf (" : sf_read_raw failed with short read (%ld => %ld).\n",
Chris@0 673 SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
Chris@0 674 fflush (stdout) ;
Chris@0 675 puts (sf_strerror (file)) ;
Chris@0 676 exit (1) ;
Chris@0 677 } ;
Chris@0 678
Chris@0 679 return ;
Chris@0 680 } /* test_read_raw_or_die */
Chris@0 681
Chris@0 682 [+ FOR write_op +]
Chris@0 683 [+ FOR io_type +]
Chris@0 684 void
Chris@0 685 test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die (SNDFILE *file, int pass, const [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num)
Chris@0 686 { sf_count_t count ;
Chris@0 687
Chris@0 688 if ((count = sf_[+ (get "op_element") +]_[+ (get "io_element") +] (file, test, [+ (get "count_name") +])) != [+ (get "count_name") +])
Chris@0 689 { printf ("\n\nLine %d", line_num) ;
Chris@0 690 if (pass > 0)
Chris@0 691 printf (" (pass %d)", pass) ;
Chris@0 692 printf (" : sf_[+ (get "op_element") +]_[+ (get "io_element") +] failed with short [+ (get "op_element") +] (%ld => %ld).\n",
Chris@0 693 SF_COUNT_TO_LONG ([+ (get "count_name") +]), SF_COUNT_TO_LONG (count)) ;
Chris@0 694 fflush (stdout) ;
Chris@0 695 puts (sf_strerror (file)) ;
Chris@0 696 exit (1) ;
Chris@0 697 } ;
Chris@0 698
Chris@0 699 return ;
Chris@0 700 } /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
Chris@0 701 [+ ENDFOR io_type +][+ ENDFOR write_op +]
Chris@0 702
Chris@0 703 void
Chris@0 704 test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num)
Chris@0 705 { sf_count_t count ;
Chris@0 706
Chris@0 707 if ((count = sf_write_raw (file, test, items)) != items)
Chris@0 708 { printf ("\n\nLine %d", line_num) ;
Chris@0 709 if (pass > 0)
Chris@0 710 printf (" (pass %d)", pass) ;
Chris@0 711 printf (" : sf_write_raw failed with short write (%ld => %ld).\n",
Chris@0 712 SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
Chris@0 713 fflush (stdout) ;
Chris@0 714 puts (sf_strerror (file)) ;
Chris@0 715 exit (1) ;
Chris@0 716 } ;
Chris@0 717
Chris@0 718 return ;
Chris@0 719 } /* test_write_raw_or_die */
Chris@0 720
Chris@0 721
Chris@0 722 [+ FOR io_type
Chris@0 723 +]void
Chris@0 724 compare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *left, const [+ (get "io_element") +] *right, unsigned count, int line_num)
Chris@0 725 {
Chris@0 726 unsigned k ;
Chris@0 727
Chris@0 728 for (k = 0 ; k < count ;k++)
Chris@0 729 if (left [k] != right [k])
Chris@0 730 { printf ("\n\nLine %d : Error at index %d, " [+ (get "format_str") +] " should be " [+ (get "format_str") +] ".\n\n", line_num, k, left [k], right [k]) ;
Chris@0 731 exit (1) ;
Chris@0 732 } ;
Chris@0 733
Chris@0 734 return ;
Chris@0 735 } /* compare_[+ (get "io_element") +]_or_die */
Chris@0 736 [+ ENDFOR io_type +]
Chris@0 737
Chris@0 738
Chris@0 739 void
Chris@0 740 delete_file (int format, const char *filename)
Chris@0 741 { char rsrc_name [512], *fname ;
Chris@0 742
Chris@0 743 unlink (filename) ;
Chris@0 744
Chris@0 745 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2)
Chris@0 746 return ;
Chris@0 747
Chris@0 748 /*
Chris@0 749 ** Now try for a resource fork stored as a separate file.
Chris@0 750 ** Grab the un-adulterated filename again.
Chris@0 751 */
Chris@0 752 snprintf (rsrc_name, sizeof (rsrc_name), "%s", filename) ;
Chris@0 753
Chris@0 754 if ((fname = strrchr (rsrc_name, '/')) != NULL)
Chris@0 755 fname ++ ;
Chris@0 756 else if ((fname = strrchr (rsrc_name, '\\')) != NULL)
Chris@0 757 fname ++ ;
Chris@0 758 else
Chris@0 759 fname = rsrc_name ;
Chris@0 760
Chris@0 761 memmove (fname + 2, fname, strlen (fname) + 1) ;
Chris@0 762 fname [0] = '.' ;
Chris@0 763 fname [1] = '_' ;
Chris@0 764
Chris@0 765 unlink (rsrc_name) ;
Chris@0 766 } /* delete_file */
Chris@0 767
Chris@0 768 static int allowed_open_files = -1 ;
Chris@0 769
Chris@0 770 void
Chris@0 771 count_open_files (void)
Chris@0 772 {
Chris@0 773 #if OS_IS_WIN32
Chris@0 774 return ;
Chris@0 775 #else
Chris@0 776 int k, count = 0 ;
Chris@0 777 struct stat statbuf ;
Chris@0 778
Chris@0 779 if (allowed_open_files > 0)
Chris@0 780 return ;
Chris@0 781
Chris@0 782 for (k = 0 ; k < 1024 ; k++)
Chris@0 783 if (fstat (k, &statbuf) == 0)
Chris@0 784 count ++ ;
Chris@0 785
Chris@0 786 allowed_open_files = count ;
Chris@0 787 #endif
Chris@0 788 } /* count_open_files */
Chris@0 789
Chris@0 790 void
Chris@0 791 increment_open_file_count (void)
Chris@0 792 { allowed_open_files ++ ;
Chris@0 793 } /* increment_open_file_count */
Chris@0 794
Chris@0 795 void
Chris@0 796 check_open_file_count_or_die (int lineno)
Chris@0 797 {
Chris@0 798 #if OS_IS_WIN32
Chris@0 799 lineno = 0 ;
Chris@0 800 return ;
Chris@0 801 #else
Chris@0 802 int k, count = 0 ;
Chris@0 803 struct stat statbuf ;
Chris@0 804
Chris@0 805 if (allowed_open_files < 0)
Chris@0 806 count_open_files () ;
Chris@0 807
Chris@0 808 for (k = 0 ; k < 1024 ; k++)
Chris@0 809 if (fstat (k, &statbuf) == 0)
Chris@0 810 count ++ ;
Chris@0 811
Chris@0 812 if (count > allowed_open_files)
Chris@0 813 { printf ("\nLine %d : number of open files (%d) > allowed (%d).\n\n", lineno, count, allowed_open_files) ;
Chris@0 814 exit (1) ;
Chris@0 815 } ;
Chris@0 816 #endif
Chris@0 817 } /* check_open_file_count_or_die */
Chris@0 818
Chris@0 819 void
Chris@0 820 write_mono_file (const char * filename, int format, int srate, float * output, int len)
Chris@0 821 { SNDFILE * file ;
Chris@0 822 SF_INFO sfinfo ;
Chris@0 823
Chris@0 824 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@0 825
Chris@0 826 sfinfo.samplerate = srate ;
Chris@0 827 sfinfo.channels = 1 ;
Chris@0 828 sfinfo.format = format ;
Chris@0 829
Chris@0 830 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
Chris@0 831 { printf ("sf_open (%s) : %s\n", filename, sf_strerror (NULL)) ;
Chris@0 832 exit (1) ;
Chris@0 833 } ;
Chris@0 834
Chris@0 835 sf_write_float (file, output, len) ;
Chris@0 836
Chris@0 837 sf_close (file) ;
Chris@0 838 } /* write_mono_file */
Chris@0 839
Chris@0 840 void
Chris@0 841 gen_lowpass_noise_float (float *data, int len)
Chris@0 842 { int32_t value = 0x1243456 ;
Chris@0 843 double sample, last_val = 0.0 ;
Chris@0 844 int k ;
Chris@0 845
Chris@0 846 for (k = 0 ; k < len ; k++)
Chris@0 847 { /* Not a crypto quality RNG. */
Chris@0 848 value = 11117 * value + 211231 ;
Chris@0 849 value = 11117 * value + 211231 ;
Chris@0 850 value = 11117 * value + 211231 ;
Chris@0 851
Chris@0 852 sample = value / (0x7fffffff * 1.000001) ;
Chris@0 853 sample = 0.2 * sample - 0.9 * last_val ;
Chris@0 854
Chris@0 855 data [k] = last_val = sample ;
Chris@0 856 } ;
Chris@0 857
Chris@0 858 } /* gen_lowpass_noise_float */
Chris@0 859
Chris@0 860
Chris@0 861 /*
Chris@0 862 ** Windows is fucked.
Chris@0 863 ** If a file is opened R/W and data is written to it, then fstat will return
Chris@0 864 ** the correct file length, but stat will return zero.
Chris@0 865 */
Chris@0 866
Chris@0 867 sf_count_t
Chris@0 868 file_length (const char * fname)
Chris@0 869 { struct stat data ;
Chris@0 870
Chris@0 871 if (stat (fname, &data) != 0)
Chris@0 872 return 0 ;
Chris@0 873
Chris@0 874 return (sf_count_t) data.st_size ;
Chris@0 875 } /* file_length */
Chris@0 876
Chris@0 877 sf_count_t
Chris@0 878 file_length_fd (int fd)
Chris@0 879 { struct stat data ;
Chris@0 880
Chris@0 881 memset (&data, 0, sizeof (data)) ;
Chris@0 882 if (fstat (fd, &data) != 0)
Chris@0 883 return 0 ;
Chris@0 884
Chris@0 885 return (sf_count_t) data.st_size ;
Chris@0 886 } /* file_length_fd */
Chris@0 887
Chris@0 888
Chris@0 889 [+ ESAC +]
Chris@0 890