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