Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.27/tests/utils.c @ 40:1df64224f5ac
Current libsndfile source
author | Chris Cannam |
---|---|
date | Tue, 18 Oct 2016 13:22:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
39:7ddb4fc30dac | 40:1df64224f5ac |
---|---|
1 /* | |
2 ** Copyright (C) 2002-2016 Erik de Castro Lopo <erikd@mega-nerd.com> | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU General Public License as published by | |
6 ** the Free Software Foundation; either version 2 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 | |
19 /* | |
20 ** Utility functions to make writing the test suite easier. | |
21 ** | |
22 ** The .c and .h files were generated automagically with Autogen from | |
23 ** the files utils.def and utils.tpl. | |
24 */ | |
25 | |
26 | |
27 | |
28 #include "sfconfig.h" | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <inttypes.h> | |
33 | |
34 #if HAVE_UNISTD_H | |
35 #include <unistd.h> | |
36 #endif | |
37 | |
38 #if (HAVE_DECL_S_IRGRP == 0) | |
39 #include <sf_unistd.h> | |
40 #endif | |
41 | |
42 #include <errno.h> | |
43 #include <string.h> | |
44 #include <ctype.h> | |
45 #include <math.h> | |
46 #include <fcntl.h> | |
47 #include <sys/stat.h> | |
48 | |
49 #include <sndfile.h> | |
50 | |
51 #include "utils.h" | |
52 | |
53 #ifndef M_PI | |
54 #define M_PI 3.14159265358979323846264338 | |
55 #endif | |
56 | |
57 #define LOG_BUFFER_SIZE 2048 | |
58 | |
59 /* | |
60 ** Neat solution to the Win32/OS2 binary file flage requirement. | |
61 ** If O_BINARY isn't already defined by the inclusion of the system | |
62 ** headers, set it to zero. | |
63 */ | |
64 #ifndef O_BINARY | |
65 #define O_BINARY 0 | |
66 #endif | |
67 | |
68 | |
69 void | |
70 gen_windowed_sine_float (float *data, int len, double maximum) | |
71 { int k ; | |
72 | |
73 memset (data, 0, len * sizeof (float)) ; | |
74 | |
75 len = (5 * len) / 6 ; | |
76 | |
77 for (k = 0 ; k < len ; k++) | |
78 { data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ; | |
79 | |
80 /* Apply Hanning Window. */ | |
81 data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ; | |
82 } | |
83 | |
84 return ; | |
85 } /* gen_windowed_sine_float */ | |
86 | |
87 void | |
88 gen_windowed_sine_double (double *data, int len, double maximum) | |
89 { int k ; | |
90 | |
91 memset (data, 0, len * sizeof (double)) ; | |
92 | |
93 len = (5 * len) / 6 ; | |
94 | |
95 for (k = 0 ; k < len ; k++) | |
96 { data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ; | |
97 | |
98 /* Apply Hanning Window. */ | |
99 data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ; | |
100 } | |
101 | |
102 return ; | |
103 } /* gen_windowed_sine_double */ | |
104 | |
105 | |
106 void | |
107 create_short_sndfile (const char *filename, int format, int channels) | |
108 { short data [2 * 3 * 4 * 5 * 6 * 7] = { 0, } ; | |
109 SNDFILE *file ; | |
110 SF_INFO sfinfo ; | |
111 | |
112 sfinfo.samplerate = 44100 ; | |
113 sfinfo.channels = channels ; | |
114 sfinfo.format = format ; | |
115 | |
116 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) | |
117 { printf ("Error (%s, %d) : sf_open failed : %s\n", __FILE__, __LINE__, sf_strerror (file)) ; | |
118 exit (1) ; | |
119 } ; | |
120 | |
121 sf_write_short (file, data, ARRAY_LEN (data)) ; | |
122 | |
123 sf_close (file) ; | |
124 } /* create_short_sndfile */ | |
125 | |
126 void | |
127 check_file_hash_or_die (const char *filename, uint64_t target_hash, int line_num) | |
128 { static unsigned char buf [4096] ; | |
129 uint64_t cksum ; | |
130 FILE *file ; | |
131 int k, read_count ; | |
132 | |
133 memset (buf, 0, sizeof (buf)) ; | |
134 | |
135 /* The 'b' in the mode string means binary for Win32. */ | |
136 if ((file = fopen (filename, "rb")) == NULL) | |
137 { printf ("\n\nLine %d: could not open file '%s'\n\n", line_num, filename) ; | |
138 exit (1) ; | |
139 } ; | |
140 | |
141 cksum = 0 ; | |
142 | |
143 while ((read_count = fread (buf, 1, sizeof (buf), file))) | |
144 for (k = 0 ; k < read_count ; k++) | |
145 cksum = (cksum * 511 + buf [k]) & 0xfffffffffffff ; | |
146 | |
147 fclose (file) ; | |
148 | |
149 if (target_hash == 0) | |
150 { printf (" 0x%" PRIx64 "\n", cksum) ; | |
151 return ; | |
152 } ; | |
153 | |
154 if (cksum != target_hash) | |
155 { printf ("\n\nLine %d: incorrect hash value 0x%" PRIx64 " should be 0x%" PRIx64 ".\n\n", line_num, cksum, target_hash) ; | |
156 exit (1) ; | |
157 } ; | |
158 | |
159 return ; | |
160 } /* check_file_hash_or_die */ | |
161 | |
162 void | |
163 print_test_name (const char *test, const char *filename) | |
164 { int count ; | |
165 | |
166 if (test == NULL) | |
167 { printf (__FILE__ ": bad test of filename parameter.\n") ; | |
168 exit (1) ; | |
169 } ; | |
170 | |
171 if (filename == NULL || strlen (filename) == 0) | |
172 { printf (" %-30s : ", test) ; | |
173 count = 25 ; | |
174 } | |
175 else | |
176 { printf (" %-30s : %s ", test, filename) ; | |
177 count = 24 - strlen (filename) ; | |
178 } ; | |
179 | |
180 while (count -- > 0) | |
181 putchar ('.') ; | |
182 putchar (' ') ; | |
183 | |
184 fflush (stdout) ; | |
185 } /* print_test_name */ | |
186 | |
187 void | |
188 dump_data_to_file (const char *filename, const void *data, unsigned int datalen) | |
189 { FILE *file ; | |
190 | |
191 if ((file = fopen (filename, "wb")) == NULL) | |
192 { printf ("\n\nLine %d : could not open file : %s\n\n", __LINE__, filename) ; | |
193 exit (1) ; | |
194 } ; | |
195 | |
196 if (fwrite (data, 1, datalen, file) != datalen) | |
197 { printf ("\n\nLine %d : fwrite failed.\n\n", __LINE__) ; | |
198 exit (1) ; | |
199 } ; | |
200 | |
201 fclose (file) ; | |
202 | |
203 } /* dump_data_to_file */ | |
204 | |
205 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
206 */ | |
207 | |
208 static char octfilename [] = "error.dat" ; | |
209 | |
210 int | |
211 oct_save_short (const short *a, const short *b, int len) | |
212 { FILE *file ; | |
213 int k ; | |
214 | |
215 if (! (file = fopen (octfilename, "w"))) | |
216 return 1 ; | |
217 | |
218 fprintf (file, "# Not created by Octave\n") ; | |
219 | |
220 fprintf (file, "# name: a\n") ; | |
221 fprintf (file, "# type: matrix\n") ; | |
222 fprintf (file, "# rows: %d\n", len) ; | |
223 fprintf (file, "# columns: 1\n") ; | |
224 | |
225 for (k = 0 ; k < len ; k++) | |
226 fprintf (file, "% d" "\n", a [k]) ; | |
227 | |
228 fprintf (file, "# name: b\n") ; | |
229 fprintf (file, "# type: matrix\n") ; | |
230 fprintf (file, "# rows: %d\n", len) ; | |
231 fprintf (file, "# columns: 1\n") ; | |
232 | |
233 for (k = 0 ; k < len ; k++) | |
234 fprintf (file, "% d" "\n", b [k]) ; | |
235 | |
236 fclose (file) ; | |
237 return 0 ; | |
238 } /* oct_save_short */ | |
239 int | |
240 oct_save_int (const int *a, const int *b, int len) | |
241 { FILE *file ; | |
242 int k ; | |
243 | |
244 if (! (file = fopen (octfilename, "w"))) | |
245 return 1 ; | |
246 | |
247 fprintf (file, "# Not created by Octave\n") ; | |
248 | |
249 fprintf (file, "# name: a\n") ; | |
250 fprintf (file, "# type: matrix\n") ; | |
251 fprintf (file, "# rows: %d\n", len) ; | |
252 fprintf (file, "# columns: 1\n") ; | |
253 | |
254 for (k = 0 ; k < len ; k++) | |
255 fprintf (file, "% d" "\n", a [k]) ; | |
256 | |
257 fprintf (file, "# name: b\n") ; | |
258 fprintf (file, "# type: matrix\n") ; | |
259 fprintf (file, "# rows: %d\n", len) ; | |
260 fprintf (file, "# columns: 1\n") ; | |
261 | |
262 for (k = 0 ; k < len ; k++) | |
263 fprintf (file, "% d" "\n", b [k]) ; | |
264 | |
265 fclose (file) ; | |
266 return 0 ; | |
267 } /* oct_save_int */ | |
268 int | |
269 oct_save_float (const float *a, const float *b, int len) | |
270 { FILE *file ; | |
271 int k ; | |
272 | |
273 if (! (file = fopen (octfilename, "w"))) | |
274 return 1 ; | |
275 | |
276 fprintf (file, "# Not created by Octave\n") ; | |
277 | |
278 fprintf (file, "# name: a\n") ; | |
279 fprintf (file, "# type: matrix\n") ; | |
280 fprintf (file, "# rows: %d\n", len) ; | |
281 fprintf (file, "# columns: 1\n") ; | |
282 | |
283 for (k = 0 ; k < len ; k++) | |
284 fprintf (file, "% g" "\n", a [k]) ; | |
285 | |
286 fprintf (file, "# name: b\n") ; | |
287 fprintf (file, "# type: matrix\n") ; | |
288 fprintf (file, "# rows: %d\n", len) ; | |
289 fprintf (file, "# columns: 1\n") ; | |
290 | |
291 for (k = 0 ; k < len ; k++) | |
292 fprintf (file, "% g" "\n", b [k]) ; | |
293 | |
294 fclose (file) ; | |
295 return 0 ; | |
296 } /* oct_save_float */ | |
297 int | |
298 oct_save_double (const double *a, const double *b, int len) | |
299 { FILE *file ; | |
300 int k ; | |
301 | |
302 if (! (file = fopen (octfilename, "w"))) | |
303 return 1 ; | |
304 | |
305 fprintf (file, "# Not created by Octave\n") ; | |
306 | |
307 fprintf (file, "# name: a\n") ; | |
308 fprintf (file, "# type: matrix\n") ; | |
309 fprintf (file, "# rows: %d\n", len) ; | |
310 fprintf (file, "# columns: 1\n") ; | |
311 | |
312 for (k = 0 ; k < len ; k++) | |
313 fprintf (file, "% g" "\n", a [k]) ; | |
314 | |
315 fprintf (file, "# name: b\n") ; | |
316 fprintf (file, "# type: matrix\n") ; | |
317 fprintf (file, "# rows: %d\n", len) ; | |
318 fprintf (file, "# columns: 1\n") ; | |
319 | |
320 for (k = 0 ; k < len ; k++) | |
321 fprintf (file, "% g" "\n", b [k]) ; | |
322 | |
323 fclose (file) ; | |
324 return 0 ; | |
325 } /* oct_save_double */ | |
326 | |
327 | |
328 void | |
329 check_log_buffer_or_die (SNDFILE *file, int line_num) | |
330 { static char buffer [LOG_BUFFER_SIZE] ; | |
331 int count ; | |
332 | |
333 memset (buffer, 0, sizeof (buffer)) ; | |
334 | |
335 /* Get the log buffer data. */ | |
336 count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ; | |
337 | |
338 if (LOG_BUFFER_SIZE - count < 2) | |
339 { printf ("\n\nLine %d : Possible long log buffer.\n", line_num) ; | |
340 exit (1) ; | |
341 } | |
342 | |
343 /* Look for "Should" */ | |
344 if (strstr (buffer, "ould")) | |
345 { printf ("\n\nLine %d : Log buffer contains `ould'. Dumping.\n", line_num) ; | |
346 puts (buffer) ; | |
347 exit (1) ; | |
348 } ; | |
349 | |
350 /* Look for "**" */ | |
351 if (strstr (buffer, "*")) | |
352 { printf ("\n\nLine %d : Log buffer contains `*'. Dumping.\n", line_num) ; | |
353 puts (buffer) ; | |
354 exit (1) ; | |
355 } ; | |
356 | |
357 /* Look for "Should" */ | |
358 if (strstr (buffer, "nknown marker")) | |
359 { printf ("\n\nLine %d : Log buffer contains `nknown marker'. Dumping.\n", line_num) ; | |
360 puts (buffer) ; | |
361 exit (1) ; | |
362 } ; | |
363 | |
364 return ; | |
365 } /* check_log_buffer_or_die */ | |
366 | |
367 int | |
368 string_in_log_buffer (SNDFILE *file, const char *s) | |
369 { static char buffer [LOG_BUFFER_SIZE] ; | |
370 int count ; | |
371 | |
372 memset (buffer, 0, sizeof (buffer)) ; | |
373 | |
374 /* Get the log buffer data. */ | |
375 count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ; | |
376 | |
377 if (LOG_BUFFER_SIZE - count < 2) | |
378 { printf ("Possible long log buffer.\n") ; | |
379 exit (1) ; | |
380 } | |
381 | |
382 /* Look for string */ | |
383 return strstr (buffer, s) ? SF_TRUE : SF_FALSE ; | |
384 } /* string_in_log_buffer */ | |
385 | |
386 void | |
387 hexdump_file (const char * filename, sf_count_t offset, sf_count_t length) | |
388 { | |
389 FILE * file ; | |
390 char buffer [16] ; | |
391 int k, m, ch, readcount ; | |
392 | |
393 if (length > 1000000) | |
394 { printf ("\n\nError : length (%" PRId64 ") too long.\n\n", offset) ; | |
395 exit (1) ; | |
396 } ; | |
397 | |
398 if ((file = fopen (filename, "r")) == NULL) | |
399 { printf ("\n\nError : hexdump_file (%s) could not open file for read.\n\n", filename) ; | |
400 exit (1) ; | |
401 } ; | |
402 | |
403 if (fseek (file, offset, SEEK_SET) != 0) | |
404 { printf ("\n\nError : fseek(file, %" PRId64 ", SEEK_SET) failed : %s\n\n", offset, strerror (errno)) ; | |
405 exit (1) ; | |
406 } ; | |
407 | |
408 puts ("\n\n") ; | |
409 | |
410 for (k = 0 ; k < length ; k+= sizeof (buffer)) | |
411 { readcount = fread (buffer, 1, sizeof (buffer), file) ; | |
412 | |
413 printf ("%08" PRIx64 " : ", offset + k) ; | |
414 | |
415 for (m = 0 ; m < readcount ; m++) | |
416 printf ("%02x ", buffer [m] & 0xFF) ; | |
417 | |
418 for (m = readcount ; m < SIGNED_SIZEOF (buffer) ; m++) | |
419 printf (" ") ; | |
420 | |
421 printf (" ") ; | |
422 for (m = 0 ; m < readcount ; m++) | |
423 { ch = isprint (buffer [m]) ? buffer [m] : '.' ; | |
424 putchar (ch) ; | |
425 } ; | |
426 | |
427 if (readcount < SIGNED_SIZEOF (buffer)) | |
428 break ; | |
429 | |
430 putchar ('\n') ; | |
431 } ; | |
432 | |
433 puts ("\n") ; | |
434 | |
435 fclose (file) ; | |
436 } /* hexdump_file */ | |
437 | |
438 void | |
439 dump_log_buffer (SNDFILE *file) | |
440 { static char buffer [LOG_BUFFER_SIZE] ; | |
441 | |
442 memset (buffer, 0, sizeof (buffer)) ; | |
443 | |
444 /* Get the log buffer data. */ | |
445 sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ; | |
446 | |
447 if (strlen (buffer) < 1) | |
448 puts ("Log buffer empty.\n") ; | |
449 else | |
450 puts (buffer) ; | |
451 | |
452 return ; | |
453 } /* dump_log_buffer */ | |
454 | |
455 void | |
456 test_sf_format_or_die (const SF_INFO *info, int line_num) | |
457 { int res ; | |
458 | |
459 if ((res = sf_format_check (info)) != 1) | |
460 { printf ("\n\nLine %d : sf_format_check returned error (%d)\n\n", line_num,res) ; | |
461 exit (1) ; | |
462 } ; | |
463 | |
464 return ; | |
465 } /* test_sf_format_or_die */ | |
466 | |
467 SNDFILE * | |
468 test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num) | |
469 { static int count = 0 ; | |
470 | |
471 SNDFILE *file ; | |
472 const char *modestr, *func_name ; | |
473 int oflags = 0, omode = 0, err ; | |
474 | |
475 /* | |
476 ** Need to test both sf_open() and sf_open_fd(). | |
477 ** Do so alternately. | |
478 */ | |
479 switch (mode) | |
480 { case SFM_READ : | |
481 modestr = "SFM_READ" ; | |
482 oflags = O_RDONLY | O_BINARY ; | |
483 omode = 0 ; | |
484 break ; | |
485 | |
486 case SFM_WRITE : | |
487 modestr = "SFM_WRITE" ; | |
488 oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ; | |
489 omode = S_IRUSR | S_IWUSR | S_IRGRP ; | |
490 break ; | |
491 | |
492 case SFM_RDWR : | |
493 modestr = "SFM_RDWR" ; | |
494 oflags = O_RDWR | O_CREAT | O_BINARY ; | |
495 omode = S_IRUSR | S_IWUSR | S_IRGRP ; | |
496 break ; | |
497 default : | |
498 printf ("\n\nLine %d: Bad mode.\n", line_num) ; | |
499 fflush (stdout) ; | |
500 exit (1) ; | |
501 } ; | |
502 | |
503 if (OS_IS_WIN32) | |
504 { /* Windows does not understand and ignores the S_IRGRP flag, but Wine | |
505 ** gives a run time warning message, so just clear it. | |
506 */ | |
507 omode &= ~S_IRGRP ; | |
508 } ; | |
509 | |
510 if (allow_fd && ((++count) & 1) == 1) | |
511 { int fd ; | |
512 | |
513 /* Only use the three argument open() function if omode != 0. */ | |
514 fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ; | |
515 | |
516 if (fd < 0) | |
517 { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ; | |
518 exit (1) ; | |
519 } ; | |
520 | |
521 func_name = "sf_open_fd" ; | |
522 file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ; | |
523 } | |
524 else | |
525 { func_name = "sf_open" ; | |
526 file = sf_open (filename, mode, sfinfo) ; | |
527 } ; | |
528 | |
529 if (file == NULL) | |
530 { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ; | |
531 dump_log_buffer (file) ; | |
532 exit (1) ; | |
533 } ; | |
534 | |
535 err = sf_error (file) ; | |
536 if (err != SF_ERR_NO_ERROR) | |
537 { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ; | |
538 dump_log_buffer (file) ; | |
539 exit (1) ; | |
540 } ; | |
541 | |
542 return file ; | |
543 } /* test_open_file_or_die */ | |
544 | |
545 void | |
546 test_read_write_position_or_die (SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos) | |
547 { sf_count_t pos ; | |
548 | |
549 /* Check the current read position. */ | |
550 if (read_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_READ)) != read_pos) | |
551 { printf ("\n\nLine %d ", line_num) ; | |
552 if (pass > 0) | |
553 printf ("(pass %d): ", pass) ; | |
554 printf ("Read position (%" PRId64 ") should be %" PRId64 ".\n", pos, read_pos) ; | |
555 exit (1) ; | |
556 } ; | |
557 | |
558 /* Check the current write position. */ | |
559 if (write_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_WRITE)) != write_pos) | |
560 { printf ("\n\nLine %d", line_num) ; | |
561 if (pass > 0) | |
562 printf (" (pass %d)", pass) ; | |
563 printf (" : Write position (%" PRId64 ") should be %" PRId64 ".\n", pos, write_pos) ; | |
564 exit (1) ; | |
565 } ; | |
566 | |
567 return ; | |
568 } /* test_read_write_position */ | |
569 | |
570 void | |
571 test_seek_or_die (SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num) | |
572 { sf_count_t position ; | |
573 const char *channel_name, *whence_name ; | |
574 | |
575 switch (whence) | |
576 { case SEEK_SET : | |
577 whence_name = "SEEK_SET" ; | |
578 break ; | |
579 case SEEK_CUR : | |
580 whence_name = "SEEK_CUR" ; | |
581 break ; | |
582 case SEEK_END : | |
583 whence_name = "SEEK_END" ; | |
584 break ; | |
585 | |
586 /* SFM_READ */ | |
587 case SEEK_SET | SFM_READ : | |
588 whence_name = "SFM_READ | SEEK_SET" ; | |
589 break ; | |
590 case SEEK_CUR | SFM_READ : | |
591 whence_name = "SFM_READ | SEEK_CUR" ; | |
592 break ; | |
593 case SEEK_END | SFM_READ : | |
594 whence_name = "SFM_READ | SEEK_END" ; | |
595 break ; | |
596 | |
597 /* SFM_WRITE */ | |
598 case SEEK_SET | SFM_WRITE : | |
599 whence_name = "SFM_WRITE | SEEK_SET" ; | |
600 break ; | |
601 case SEEK_CUR | SFM_WRITE : | |
602 whence_name = "SFM_WRITE | SEEK_CUR" ; | |
603 break ; | |
604 case SEEK_END | SFM_WRITE : | |
605 whence_name = "SFM_WRITE | SEEK_END" ; | |
606 break ; | |
607 | |
608 default : | |
609 printf ("\n\nLine %d: bad whence parameter.\n", line_num) ; | |
610 exit (1) ; | |
611 } ; | |
612 | |
613 channel_name = (channels == 1) ? "Mono" : "Stereo" ; | |
614 | |
615 if ((position = sf_seek (file, offset, whence)) != new_pos) | |
616 { printf ("\n\nLine %d : %s : sf_seek (file, %" PRId64 ", %s) returned %" PRId64 " (should be %" PRId64 ").\n\n", | |
617 line_num, channel_name, offset, whence_name, position, new_pos) ; | |
618 exit (1) ; | |
619 } ; | |
620 | |
621 } /* test_seek_or_die */ | |
622 | |
623 | |
624 | |
625 void | |
626 test_read_short_or_die (SNDFILE *file, int pass, short *test, sf_count_t items, int line_num) | |
627 { sf_count_t count ; | |
628 | |
629 if ((count = sf_read_short (file, test, items)) != items) | |
630 { printf ("\n\nLine %d", line_num) ; | |
631 if (pass > 0) | |
632 printf (" (pass %d)", pass) ; | |
633 printf (" : sf_read_short failed with short read (%" PRId64 " => %" PRId64 ").\n", | |
634 items, count) ; | |
635 fflush (stdout) ; | |
636 puts (sf_strerror (file)) ; | |
637 exit (1) ; | |
638 } ; | |
639 | |
640 return ; | |
641 } /* test_read_short_or_die */ | |
642 | |
643 void | |
644 test_read_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t items, int line_num) | |
645 { sf_count_t count ; | |
646 | |
647 if ((count = sf_read_int (file, test, items)) != items) | |
648 { printf ("\n\nLine %d", line_num) ; | |
649 if (pass > 0) | |
650 printf (" (pass %d)", pass) ; | |
651 printf (" : sf_read_int failed with short read (%" PRId64 " => %" PRId64 ").\n", | |
652 items, count) ; | |
653 fflush (stdout) ; | |
654 puts (sf_strerror (file)) ; | |
655 exit (1) ; | |
656 } ; | |
657 | |
658 return ; | |
659 } /* test_read_int_or_die */ | |
660 | |
661 void | |
662 test_read_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t items, int line_num) | |
663 { sf_count_t count ; | |
664 | |
665 if ((count = sf_read_float (file, test, items)) != items) | |
666 { printf ("\n\nLine %d", line_num) ; | |
667 if (pass > 0) | |
668 printf (" (pass %d)", pass) ; | |
669 printf (" : sf_read_float failed with short read (%" PRId64 " => %" PRId64 ").\n", | |
670 items, count) ; | |
671 fflush (stdout) ; | |
672 puts (sf_strerror (file)) ; | |
673 exit (1) ; | |
674 } ; | |
675 | |
676 return ; | |
677 } /* test_read_float_or_die */ | |
678 | |
679 void | |
680 test_read_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t items, int line_num) | |
681 { sf_count_t count ; | |
682 | |
683 if ((count = sf_read_double (file, test, items)) != items) | |
684 { printf ("\n\nLine %d", line_num) ; | |
685 if (pass > 0) | |
686 printf (" (pass %d)", pass) ; | |
687 printf (" : sf_read_double failed with short read (%" PRId64 " => %" PRId64 ").\n", | |
688 items, count) ; | |
689 fflush (stdout) ; | |
690 puts (sf_strerror (file)) ; | |
691 exit (1) ; | |
692 } ; | |
693 | |
694 return ; | |
695 } /* test_read_double_or_die */ | |
696 | |
697 | |
698 void | |
699 test_readf_short_or_die (SNDFILE *file, int pass, short *test, sf_count_t frames, int line_num) | |
700 { sf_count_t count ; | |
701 | |
702 if ((count = sf_readf_short (file, test, frames)) != frames) | |
703 { printf ("\n\nLine %d", line_num) ; | |
704 if (pass > 0) | |
705 printf (" (pass %d)", pass) ; | |
706 printf (" : sf_readf_short failed with short readf (%" PRId64 " => %" PRId64 ").\n", | |
707 frames, count) ; | |
708 fflush (stdout) ; | |
709 puts (sf_strerror (file)) ; | |
710 exit (1) ; | |
711 } ; | |
712 | |
713 return ; | |
714 } /* test_readf_short_or_die */ | |
715 | |
716 void | |
717 test_readf_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t frames, int line_num) | |
718 { sf_count_t count ; | |
719 | |
720 if ((count = sf_readf_int (file, test, frames)) != frames) | |
721 { printf ("\n\nLine %d", line_num) ; | |
722 if (pass > 0) | |
723 printf (" (pass %d)", pass) ; | |
724 printf (" : sf_readf_int failed with short readf (%" PRId64 " => %" PRId64 ").\n", | |
725 frames, count) ; | |
726 fflush (stdout) ; | |
727 puts (sf_strerror (file)) ; | |
728 exit (1) ; | |
729 } ; | |
730 | |
731 return ; | |
732 } /* test_readf_int_or_die */ | |
733 | |
734 void | |
735 test_readf_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t frames, int line_num) | |
736 { sf_count_t count ; | |
737 | |
738 if ((count = sf_readf_float (file, test, frames)) != frames) | |
739 { printf ("\n\nLine %d", line_num) ; | |
740 if (pass > 0) | |
741 printf (" (pass %d)", pass) ; | |
742 printf (" : sf_readf_float failed with short readf (%" PRId64 " => %" PRId64 ").\n", | |
743 frames, count) ; | |
744 fflush (stdout) ; | |
745 puts (sf_strerror (file)) ; | |
746 exit (1) ; | |
747 } ; | |
748 | |
749 return ; | |
750 } /* test_readf_float_or_die */ | |
751 | |
752 void | |
753 test_readf_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t frames, int line_num) | |
754 { sf_count_t count ; | |
755 | |
756 if ((count = sf_readf_double (file, test, frames)) != frames) | |
757 { printf ("\n\nLine %d", line_num) ; | |
758 if (pass > 0) | |
759 printf (" (pass %d)", pass) ; | |
760 printf (" : sf_readf_double failed with short readf (%" PRId64 " => %" PRId64 ").\n", | |
761 frames, count) ; | |
762 fflush (stdout) ; | |
763 puts (sf_strerror (file)) ; | |
764 exit (1) ; | |
765 } ; | |
766 | |
767 return ; | |
768 } /* test_readf_double_or_die */ | |
769 | |
770 | |
771 void | |
772 test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) | |
773 { sf_count_t count ; | |
774 | |
775 if ((count = sf_read_raw (file, test, items)) != items) | |
776 { printf ("\n\nLine %d", line_num) ; | |
777 if (pass > 0) | |
778 printf (" (pass %d)", pass) ; | |
779 printf (" : sf_read_raw failed with short read (%" PRId64 " => %" PRId64 ").\n", items, count) ; | |
780 fflush (stdout) ; | |
781 puts (sf_strerror (file)) ; | |
782 exit (1) ; | |
783 } ; | |
784 | |
785 return ; | |
786 } /* test_read_raw_or_die */ | |
787 | |
788 | |
789 | |
790 void | |
791 test_write_short_or_die (SNDFILE *file, int pass, const short *test, sf_count_t items, int line_num) | |
792 { sf_count_t count ; | |
793 | |
794 if ((count = sf_write_short (file, test, items)) != items) | |
795 { printf ("\n\nLine %d", line_num) ; | |
796 if (pass > 0) | |
797 printf (" (pass %d)", pass) ; | |
798 printf (" : sf_write_short failed with short write (%" PRId64 " => %" PRId64 ").\n", | |
799 items, count) ; | |
800 fflush (stdout) ; | |
801 puts (sf_strerror (file)) ; | |
802 exit (1) ; | |
803 } ; | |
804 | |
805 return ; | |
806 } /* test_write_short_or_die */ | |
807 | |
808 void | |
809 test_write_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t items, int line_num) | |
810 { sf_count_t count ; | |
811 | |
812 if ((count = sf_write_int (file, test, items)) != items) | |
813 { printf ("\n\nLine %d", line_num) ; | |
814 if (pass > 0) | |
815 printf (" (pass %d)", pass) ; | |
816 printf (" : sf_write_int failed with short write (%" PRId64 " => %" PRId64 ").\n", | |
817 items, count) ; | |
818 fflush (stdout) ; | |
819 puts (sf_strerror (file)) ; | |
820 exit (1) ; | |
821 } ; | |
822 | |
823 return ; | |
824 } /* test_write_int_or_die */ | |
825 | |
826 void | |
827 test_write_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t items, int line_num) | |
828 { sf_count_t count ; | |
829 | |
830 if ((count = sf_write_float (file, test, items)) != items) | |
831 { printf ("\n\nLine %d", line_num) ; | |
832 if (pass > 0) | |
833 printf (" (pass %d)", pass) ; | |
834 printf (" : sf_write_float failed with short write (%" PRId64 " => %" PRId64 ").\n", | |
835 items, count) ; | |
836 fflush (stdout) ; | |
837 puts (sf_strerror (file)) ; | |
838 exit (1) ; | |
839 } ; | |
840 | |
841 return ; | |
842 } /* test_write_float_or_die */ | |
843 | |
844 void | |
845 test_write_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t items, int line_num) | |
846 { sf_count_t count ; | |
847 | |
848 if ((count = sf_write_double (file, test, items)) != items) | |
849 { printf ("\n\nLine %d", line_num) ; | |
850 if (pass > 0) | |
851 printf (" (pass %d)", pass) ; | |
852 printf (" : sf_write_double failed with short write (%" PRId64 " => %" PRId64 ").\n", | |
853 items, count) ; | |
854 fflush (stdout) ; | |
855 puts (sf_strerror (file)) ; | |
856 exit (1) ; | |
857 } ; | |
858 | |
859 return ; | |
860 } /* test_write_double_or_die */ | |
861 | |
862 | |
863 void | |
864 test_writef_short_or_die (SNDFILE *file, int pass, const short *test, sf_count_t frames, int line_num) | |
865 { sf_count_t count ; | |
866 | |
867 if ((count = sf_writef_short (file, test, frames)) != frames) | |
868 { printf ("\n\nLine %d", line_num) ; | |
869 if (pass > 0) | |
870 printf (" (pass %d)", pass) ; | |
871 printf (" : sf_writef_short failed with short writef (%" PRId64 " => %" PRId64 ").\n", | |
872 frames, count) ; | |
873 fflush (stdout) ; | |
874 puts (sf_strerror (file)) ; | |
875 exit (1) ; | |
876 } ; | |
877 | |
878 return ; | |
879 } /* test_writef_short_or_die */ | |
880 | |
881 void | |
882 test_writef_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t frames, int line_num) | |
883 { sf_count_t count ; | |
884 | |
885 if ((count = sf_writef_int (file, test, frames)) != frames) | |
886 { printf ("\n\nLine %d", line_num) ; | |
887 if (pass > 0) | |
888 printf (" (pass %d)", pass) ; | |
889 printf (" : sf_writef_int failed with short writef (%" PRId64 " => %" PRId64 ").\n", | |
890 frames, count) ; | |
891 fflush (stdout) ; | |
892 puts (sf_strerror (file)) ; | |
893 exit (1) ; | |
894 } ; | |
895 | |
896 return ; | |
897 } /* test_writef_int_or_die */ | |
898 | |
899 void | |
900 test_writef_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t frames, int line_num) | |
901 { sf_count_t count ; | |
902 | |
903 if ((count = sf_writef_float (file, test, frames)) != frames) | |
904 { printf ("\n\nLine %d", line_num) ; | |
905 if (pass > 0) | |
906 printf (" (pass %d)", pass) ; | |
907 printf (" : sf_writef_float failed with short writef (%" PRId64 " => %" PRId64 ").\n", | |
908 frames, count) ; | |
909 fflush (stdout) ; | |
910 puts (sf_strerror (file)) ; | |
911 exit (1) ; | |
912 } ; | |
913 | |
914 return ; | |
915 } /* test_writef_float_or_die */ | |
916 | |
917 void | |
918 test_writef_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t frames, int line_num) | |
919 { sf_count_t count ; | |
920 | |
921 if ((count = sf_writef_double (file, test, frames)) != frames) | |
922 { printf ("\n\nLine %d", line_num) ; | |
923 if (pass > 0) | |
924 printf (" (pass %d)", pass) ; | |
925 printf (" : sf_writef_double failed with short writef (%" PRId64 " => %" PRId64 ").\n", | |
926 frames, count) ; | |
927 fflush (stdout) ; | |
928 puts (sf_strerror (file)) ; | |
929 exit (1) ; | |
930 } ; | |
931 | |
932 return ; | |
933 } /* test_writef_double_or_die */ | |
934 | |
935 | |
936 void | |
937 test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num) | |
938 { sf_count_t count ; | |
939 | |
940 if ((count = sf_write_raw (file, test, items)) != items) | |
941 { printf ("\n\nLine %d", line_num) ; | |
942 if (pass > 0) | |
943 printf (" (pass %d)", pass) ; | |
944 printf (" : sf_write_raw failed with short write (%" PRId64 " => %" PRId64 ").\n", items, count) ; | |
945 fflush (stdout) ; | |
946 puts (sf_strerror (file)) ; | |
947 exit (1) ; | |
948 } ; | |
949 | |
950 return ; | |
951 } /* test_write_raw_or_die */ | |
952 | |
953 | |
954 void | |
955 compare_short_or_die (const short *expected, const short *actual, unsigned count, int line_num) | |
956 { | |
957 unsigned k ; | |
958 | |
959 for (k = 0 ; k < count ; k++) | |
960 if (expected [k] != actual [k]) | |
961 { printf ("\n\nLine %d : Error at index %d, got " "% d" ", should be " "% d" ".\n\n", line_num, k, actual [k], expected [k]) ; | |
962 exit (1) ; | |
963 } ; | |
964 | |
965 return ; | |
966 } /* compare_short_or_die */ | |
967 void | |
968 compare_int_or_die (const int *expected, const int *actual, unsigned count, int line_num) | |
969 { | |
970 unsigned k ; | |
971 | |
972 for (k = 0 ; k < count ; k++) | |
973 if (expected [k] != actual [k]) | |
974 { printf ("\n\nLine %d : Error at index %d, got " "% d" ", should be " "% d" ".\n\n", line_num, k, actual [k], expected [k]) ; | |
975 exit (1) ; | |
976 } ; | |
977 | |
978 return ; | |
979 } /* compare_int_or_die */ | |
980 void | |
981 compare_float_or_die (const float *expected, const float *actual, unsigned count, int line_num) | |
982 { | |
983 unsigned k ; | |
984 | |
985 for (k = 0 ; k < count ; k++) | |
986 if (expected [k] != actual [k]) | |
987 { printf ("\n\nLine %d : Error at index %d, got " "% g" ", should be " "% g" ".\n\n", line_num, k, actual [k], expected [k]) ; | |
988 exit (1) ; | |
989 } ; | |
990 | |
991 return ; | |
992 } /* compare_float_or_die */ | |
993 void | |
994 compare_double_or_die (const double *expected, const double *actual, unsigned count, int line_num) | |
995 { | |
996 unsigned k ; | |
997 | |
998 for (k = 0 ; k < count ; k++) | |
999 if (expected [k] != actual [k]) | |
1000 { printf ("\n\nLine %d : Error at index %d, got " "% g" ", should be " "% g" ".\n\n", line_num, k, actual [k], expected [k]) ; | |
1001 exit (1) ; | |
1002 } ; | |
1003 | |
1004 return ; | |
1005 } /* compare_double_or_die */ | |
1006 | |
1007 | |
1008 | |
1009 void | |
1010 delete_file (int format, const char *filename) | |
1011 { char rsrc_name [512], *fname ; | |
1012 | |
1013 unlink (filename) ; | |
1014 | |
1015 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2) | |
1016 return ; | |
1017 | |
1018 /* | |
1019 ** Now try for a resource fork stored as a separate file. | |
1020 ** Grab the un-adulterated filename again. | |
1021 */ | |
1022 snprintf (rsrc_name, sizeof (rsrc_name), "%s", filename) ; | |
1023 | |
1024 if ((fname = strrchr (rsrc_name, '/')) != NULL) | |
1025 fname ++ ; | |
1026 else if ((fname = strrchr (rsrc_name, '\\')) != NULL) | |
1027 fname ++ ; | |
1028 else | |
1029 fname = rsrc_name ; | |
1030 | |
1031 memmove (fname + 2, fname, strlen (fname) + 1) ; | |
1032 fname [0] = '.' ; | |
1033 fname [1] = '_' ; | |
1034 | |
1035 unlink (rsrc_name) ; | |
1036 } /* delete_file */ | |
1037 | |
1038 static int allowed_open_files = -1 ; | |
1039 | |
1040 void | |
1041 count_open_files (void) | |
1042 { | |
1043 #if OS_IS_WIN32 | |
1044 return ; | |
1045 #else | |
1046 int k, count = 0 ; | |
1047 struct stat statbuf ; | |
1048 | |
1049 if (allowed_open_files > 0) | |
1050 return ; | |
1051 | |
1052 for (k = 0 ; k < 1024 ; k++) | |
1053 if (fstat (k, &statbuf) == 0) | |
1054 count ++ ; | |
1055 | |
1056 allowed_open_files = count ; | |
1057 #endif | |
1058 } /* count_open_files */ | |
1059 | |
1060 void | |
1061 increment_open_file_count (void) | |
1062 { allowed_open_files ++ ; | |
1063 } /* increment_open_file_count */ | |
1064 | |
1065 void | |
1066 check_open_file_count_or_die (int lineno) | |
1067 { | |
1068 #if OS_IS_WIN32 | |
1069 (void) lineno ; | |
1070 return ; | |
1071 #else | |
1072 int k, count = 0 ; | |
1073 struct stat statbuf ; | |
1074 | |
1075 if (allowed_open_files < 0) | |
1076 count_open_files () ; | |
1077 | |
1078 for (k = 0 ; k < 1024 ; k++) | |
1079 if (fstat (k, &statbuf) == 0) | |
1080 count ++ ; | |
1081 | |
1082 if (count > allowed_open_files) | |
1083 { printf ("\nLine %d : number of open files (%d) > allowed (%d).\n\n", lineno, count, allowed_open_files) ; | |
1084 exit (1) ; | |
1085 } ; | |
1086 #endif | |
1087 } /* check_open_file_count_or_die */ | |
1088 | |
1089 void | |
1090 write_mono_file (const char * filename, int format, int srate, float * output, int len) | |
1091 { SNDFILE * file ; | |
1092 SF_INFO sfinfo ; | |
1093 | |
1094 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
1095 | |
1096 sfinfo.samplerate = srate ; | |
1097 sfinfo.channels = 1 ; | |
1098 sfinfo.format = format ; | |
1099 | |
1100 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) | |
1101 { printf ("sf_open (%s) : %s\n", filename, sf_strerror (NULL)) ; | |
1102 exit (1) ; | |
1103 } ; | |
1104 | |
1105 sf_write_float (file, output, len) ; | |
1106 | |
1107 sf_close (file) ; | |
1108 } /* write_mono_file */ | |
1109 | |
1110 void | |
1111 gen_lowpass_signal_float (float *data, int len) | |
1112 { int64_t value = 0x1243456 ; | |
1113 double sample, last_val = 0.0 ; | |
1114 int k ; | |
1115 | |
1116 for (k = 0 ; k < len ; k++) | |
1117 { /* Not a crypto quality RNG. */ | |
1118 value = (11117 * value + 211231) & 0xffffffff ; | |
1119 value = (11117 * value + 211231) & 0xffffffff ; | |
1120 value = (11117 * value + 211231) & 0xffffffff ; | |
1121 | |
1122 sample = value / (0x7fffffff * 1.000001) ; | |
1123 sample = 0.2 * sample - 0.9 * last_val ; | |
1124 | |
1125 last_val = sample ; | |
1126 | |
1127 data [k] = 0.5 * (sample + sin (2.0 * k * M_PI * 1.0 / 32.0)) ; | |
1128 } ; | |
1129 | |
1130 } /* gen_lowpass_signal_float */ | |
1131 | |
1132 | |
1133 /* | |
1134 ** Windows is fucked. | |
1135 ** If a file is opened R/W and data is written to it, then fstat will return | |
1136 ** the correct file length, but stat will return zero. | |
1137 */ | |
1138 | |
1139 sf_count_t | |
1140 file_length (const char * fname) | |
1141 { struct stat data ; | |
1142 | |
1143 if (stat (fname, &data) != 0) | |
1144 return 0 ; | |
1145 | |
1146 return (sf_count_t) data.st_size ; | |
1147 } /* file_length */ | |
1148 | |
1149 sf_count_t | |
1150 file_length_fd (int fd) | |
1151 { struct stat data ; | |
1152 | |
1153 memset (&data, 0, sizeof (data)) ; | |
1154 if (fstat (fd, &data) != 0) | |
1155 return 0 ; | |
1156 | |
1157 return (sf_count_t) data.st_size ; | |
1158 } /* file_length_fd */ | |
1159 | |
1160 | |
1161 | |
1162 |