Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.25/tests/command_test.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU General Public License as published by | |
6 ** the Free Software Foundation; either version 2 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 | |
19 #include "sfconfig.h" | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <time.h> | |
25 | |
26 #if HAVE_UNISTD_H | |
27 #include <unistd.h> | |
28 #endif | |
29 | |
30 #include <math.h> | |
31 | |
32 #include <sndfile.h> | |
33 | |
34 #include "utils.h" | |
35 | |
36 #define BUFFER_LEN (1<<10) | |
37 #define LOG_BUFFER_SIZE 1024 | |
38 | |
39 static void float_norm_test (const char *filename) ; | |
40 static void double_norm_test (const char *filename) ; | |
41 static void format_tests (void) ; | |
42 static void calc_peak_test (int filetype, const char *filename) ; | |
43 static void truncate_test (const char *filename, int filetype) ; | |
44 static void instrument_test (const char *filename, int filetype) ; | |
45 static void channel_map_test (const char *filename, int filetype) ; | |
46 static void current_sf_info_test (const char *filename) ; | |
47 static void raw_needs_endswap_test (const char *filename, int filetype) ; | |
48 | |
49 static void broadcast_test (const char *filename, int filetype) ; | |
50 static void broadcast_rdwr_test (const char *filename, int filetype) ; | |
51 static void broadcast_coding_history_test (const char *filename) ; | |
52 static void broadcast_coding_history_size (const char *filename) ; | |
53 | |
54 /* Force the start of this buffer to be double aligned. Sparc-solaris will | |
55 ** choke if its not. | |
56 */ | |
57 | |
58 static int int_data [BUFFER_LEN] ; | |
59 static float float_data [BUFFER_LEN] ; | |
60 static double double_data [BUFFER_LEN] ; | |
61 | |
62 int | |
63 main (int argc, char *argv []) | |
64 { int do_all = 0 ; | |
65 int test_count = 0 ; | |
66 | |
67 if (argc != 2) | |
68 { printf ("Usage : %s <test>\n", argv [0]) ; | |
69 printf (" Where <test> is one of the following:\n") ; | |
70 printf (" ver - test sf_command (SFC_GETLIB_VERSION)\n") ; | |
71 printf (" norm - test floating point normalisation\n") ; | |
72 printf (" format - test format string commands\n") ; | |
73 printf (" peak - test peak calculation\n") ; | |
74 printf (" trunc - test file truncation\n") ; | |
75 printf (" inst - test set/get of SF_INSTRUMENT.\n") ; | |
76 printf (" chanmap - test set/get of channel map data..\n") ; | |
77 printf (" bext - test set/get of SF_BROADCAST_INFO.\n") ; | |
78 printf (" bextch - test set/get of SF_BROADCAST_INFO coding_history.\n") ; | |
79 printf (" rawend - test SFC_RAW_NEEDS_ENDSWAP.\n") ; | |
80 printf (" all - perform all tests\n") ; | |
81 exit (1) ; | |
82 } ; | |
83 | |
84 do_all =! strcmp (argv [1], "all") ; | |
85 | |
86 if (do_all || strcmp (argv [1], "ver") == 0) | |
87 { char buffer [128] ; | |
88 | |
89 print_test_name ("version_test", "(none)") ; | |
90 buffer [0] = 0 ; | |
91 sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ; | |
92 if (strlen (buffer) < 1) | |
93 { printf ("Line %d: could not retrieve lib version.\n", __LINE__) ; | |
94 exit (1) ; | |
95 } ; | |
96 puts ("ok") ; | |
97 test_count ++ ; | |
98 } ; | |
99 | |
100 if (do_all || strcmp (argv [1], "norm") == 0) | |
101 { /* Preliminary float/double normalisation tests. More testing | |
102 ** is done in the program 'floating_point_test'. | |
103 */ | |
104 float_norm_test ("float.wav") ; | |
105 double_norm_test ("double.wav") ; | |
106 test_count ++ ; | |
107 } ; | |
108 | |
109 if (do_all || strcmp (argv [1], "peak") == 0) | |
110 { calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw") ; | |
111 calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw") ; | |
112 test_count ++ ; | |
113 } ; | |
114 | |
115 if (do_all || ! strcmp (argv [1], "format")) | |
116 { format_tests () ; | |
117 test_count ++ ; | |
118 } ; | |
119 | |
120 if (do_all || strcmp (argv [1], "trunc") == 0) | |
121 { truncate_test ("truncate.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_32) ; | |
122 truncate_test ("truncate.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16) ; | |
123 test_count ++ ; | |
124 } ; | |
125 | |
126 if (do_all || strcmp (argv [1], "inst") == 0) | |
127 { instrument_test ("instrument.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; | |
128 instrument_test ("instrument.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ; | |
129 /*-instrument_test ("instrument.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16) ;-*/ | |
130 test_count ++ ; | |
131 } ; | |
132 | |
133 if (do_all || strcmp (argv [1], "current_sf_info") == 0) | |
134 { current_sf_info_test ("current.wav") ; | |
135 test_count ++ ; | |
136 } ; | |
137 | |
138 if (do_all || strcmp (argv [1], "bext") == 0) | |
139 { broadcast_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; | |
140 broadcast_rdwr_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; | |
141 | |
142 broadcast_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; | |
143 broadcast_rdwr_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; | |
144 | |
145 broadcast_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; | |
146 broadcast_rdwr_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; | |
147 test_count ++ ; | |
148 } ; | |
149 | |
150 if (do_all || strcmp (argv [1], "bextch") == 0) | |
151 { broadcast_coding_history_test ("coding_history.wav") ; | |
152 broadcast_coding_history_size ("coding_hist_size.wav") ; | |
153 test_count ++ ; | |
154 } ; | |
155 | |
156 if (do_all || strcmp (argv [1], "chanmap") == 0) | |
157 { channel_map_test ("chanmap.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ; | |
158 channel_map_test ("chanmap.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; | |
159 channel_map_test ("chanmap.aifc" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ; | |
160 channel_map_test ("chanmap.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16) ; | |
161 test_count ++ ; | |
162 } ; | |
163 | |
164 if (do_all || strcmp (argv [1], "rawend") == 0) | |
165 { raw_needs_endswap_test ("raw_end.wav", SF_FORMAT_WAV) ; | |
166 raw_needs_endswap_test ("raw_end.wavex", SF_FORMAT_WAVEX) ; | |
167 raw_needs_endswap_test ("raw_end.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ; | |
168 raw_needs_endswap_test ("raw_end.aiff", SF_FORMAT_AIFF) ; | |
169 raw_needs_endswap_test ("raw_end.aiff_le", SF_ENDIAN_LITTLE | SF_FORMAT_AIFF) ; | |
170 test_count ++ ; | |
171 } ; | |
172 | |
173 if (test_count == 0) | |
174 { printf ("Mono : ************************************\n") ; | |
175 printf ("Mono : * No '%s' test defined.\n", argv [1]) ; | |
176 printf ("Mono : ************************************\n") ; | |
177 return 1 ; | |
178 } ; | |
179 | |
180 return 0 ; | |
181 } /* main */ | |
182 | |
183 /*============================================================================================ | |
184 ** Here are the test functions. | |
185 */ | |
186 | |
187 static void | |
188 float_norm_test (const char *filename) | |
189 { SNDFILE *file ; | |
190 SF_INFO sfinfo ; | |
191 unsigned int k ; | |
192 | |
193 print_test_name ("float_norm_test", filename) ; | |
194 | |
195 sfinfo.samplerate = 44100 ; | |
196 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ; | |
197 sfinfo.channels = 1 ; | |
198 sfinfo.frames = BUFFER_LEN ; | |
199 | |
200 /* Create float_data with all values being less than 1.0. */ | |
201 for (k = 0 ; k < BUFFER_LEN / 2 ; k++) | |
202 float_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ; | |
203 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++) | |
204 float_data [k] = (k + 5) ; | |
205 | |
206 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) | |
207 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; | |
208 fflush (stdout) ; | |
209 puts (sf_strerror (NULL)) ; | |
210 exit (1) ; | |
211 } ; | |
212 | |
213 /* Normalisation is on by default so no need to do anything here. */ | |
214 | |
215 if ((k = sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2) | |
216 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
217 exit (1) ; | |
218 } ; | |
219 | |
220 /* Turn normalisation off. */ | |
221 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; | |
222 | |
223 if ((k = sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2) | |
224 { printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
225 exit (1) ; | |
226 } ; | |
227 | |
228 sf_close (file) ; | |
229 | |
230 /* sfinfo struct should still contain correct data. */ | |
231 if (! (file = sf_open (filename, SFM_READ, &sfinfo))) | |
232 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; | |
233 fflush (stdout) ; | |
234 puts (sf_strerror (NULL)) ; | |
235 exit (1) ; | |
236 } ; | |
237 | |
238 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16)) | |
239 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ; | |
240 exit (1) ; | |
241 } ; | |
242 | |
243 if (sfinfo.frames != BUFFER_LEN) | |
244 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ; | |
245 exit (1) ; | |
246 } ; | |
247 | |
248 if (sfinfo.channels != 1) | |
249 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; | |
250 exit (1) ; | |
251 } ; | |
252 | |
253 /* Read float_data and check that it is normalised (ie default). */ | |
254 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) | |
255 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
256 exit (1) ; | |
257 } ; | |
258 | |
259 for (k = 0 ; k < BUFFER_LEN ; k++) | |
260 if (float_data [k] >= 1.0) | |
261 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ; | |
262 exit (1) ; | |
263 } ; | |
264 | |
265 /* Seek to start of file, turn normalisation off, read float_data and check again. */ | |
266 sf_seek (file, 0, SEEK_SET) ; | |
267 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; | |
268 | |
269 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) | |
270 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
271 exit (1) ; | |
272 } ; | |
273 | |
274 for (k = 0 ; k < BUFFER_LEN ; k++) | |
275 if (float_data [k] < 1.0) | |
276 { printf ("\n\nLine %d: float_data [%d] == %f which is less than 1.0\n", __LINE__, k, float_data [k]) ; | |
277 exit (1) ; | |
278 } ; | |
279 | |
280 /* Seek to start of file, turn normalisation on, read float_data and do final check. */ | |
281 sf_seek (file, 0, SEEK_SET) ; | |
282 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE) ; | |
283 | |
284 if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN) | |
285 { printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
286 exit (1) ; | |
287 } ; | |
288 | |
289 for (k = 0 ; k < BUFFER_LEN ; k++) | |
290 if (float_data [k] > 1.0) | |
291 { printf ("\n\nLine %d: float_data [%d] == %f which is greater than 1.0\n", __LINE__, k, float_data [k]) ; | |
292 exit (1) ; | |
293 } ; | |
294 | |
295 | |
296 sf_close (file) ; | |
297 | |
298 unlink (filename) ; | |
299 | |
300 printf ("ok\n") ; | |
301 } /* float_norm_test */ | |
302 | |
303 static void | |
304 double_norm_test (const char *filename) | |
305 { SNDFILE *file ; | |
306 SF_INFO sfinfo ; | |
307 unsigned int k ; | |
308 | |
309 print_test_name ("double_norm_test", filename) ; | |
310 | |
311 sfinfo.samplerate = 44100 ; | |
312 sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ; | |
313 sfinfo.channels = 1 ; | |
314 sfinfo.frames = BUFFER_LEN ; | |
315 | |
316 /* Create double_data with all values being less than 1.0. */ | |
317 for (k = 0 ; k < BUFFER_LEN / 2 ; k++) | |
318 double_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ; | |
319 for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++) | |
320 double_data [k] = (k + 5) ; | |
321 | |
322 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) | |
323 { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; | |
324 fflush (stdout) ; | |
325 puts (sf_strerror (NULL)) ; | |
326 exit (1) ; | |
327 } ; | |
328 | |
329 /* Normailsation is on by default so no need to do anything here. */ | |
330 /*-sf_command (file, "set-norm-double", "true", 0) ;-*/ | |
331 | |
332 if ((k = sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2) | |
333 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
334 exit (1) ; | |
335 } ; | |
336 | |
337 /* Turn normalisation off. */ | |
338 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; | |
339 | |
340 if ((k = sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2) | |
341 { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
342 exit (1) ; | |
343 } ; | |
344 | |
345 sf_close (file) ; | |
346 | |
347 if (! (file = sf_open (filename, SFM_READ, &sfinfo))) | |
348 { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; | |
349 fflush (stdout) ; | |
350 puts (sf_strerror (NULL)) ; | |
351 exit (1) ; | |
352 } ; | |
353 | |
354 if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16)) | |
355 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ; | |
356 exit (1) ; | |
357 } ; | |
358 | |
359 if (sfinfo.frames != BUFFER_LEN) | |
360 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ; | |
361 exit (1) ; | |
362 } ; | |
363 | |
364 if (sfinfo.channels != 1) | |
365 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; | |
366 exit (1) ; | |
367 } ; | |
368 | |
369 /* Read double_data and check that it is normalised (ie default). */ | |
370 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) | |
371 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
372 exit (1) ; | |
373 } ; | |
374 | |
375 for (k = 0 ; k < BUFFER_LEN ; k++) | |
376 if (double_data [k] >= 1.0) | |
377 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; | |
378 exit (1) ; | |
379 } ; | |
380 | |
381 /* Seek to start of file, turn normalisation off, read double_data and check again. */ | |
382 sf_seek (file, 0, SEEK_SET) ; | |
383 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; | |
384 | |
385 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) | |
386 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
387 exit (1) ; | |
388 } ; | |
389 | |
390 for (k = 0 ; k < BUFFER_LEN ; k++) | |
391 if (double_data [k] < 1.0) | |
392 { printf ("\n\nLine %d: double_data [%d] == %f which is less than 1.0\n", __LINE__, k, double_data [k]) ; | |
393 exit (1) ; | |
394 } ; | |
395 | |
396 /* Seek to start of file, turn normalisation on, read double_data and do final check. */ | |
397 sf_seek (file, 0, SEEK_SET) ; | |
398 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ; | |
399 | |
400 if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) | |
401 { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; | |
402 exit (1) ; | |
403 } ; | |
404 | |
405 for (k = 0 ; k < BUFFER_LEN ; k++) | |
406 if (double_data [k] > 1.0) | |
407 { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; | |
408 exit (1) ; | |
409 } ; | |
410 | |
411 | |
412 sf_close (file) ; | |
413 | |
414 unlink (filename) ; | |
415 | |
416 printf ("ok\n") ; | |
417 } /* double_norm_test */ | |
418 | |
419 static void | |
420 format_tests (void) | |
421 { SF_FORMAT_INFO format_info ; | |
422 SF_INFO sfinfo ; | |
423 const char *last_name ; | |
424 int k, count ; | |
425 | |
426 print_test_name ("format_tests", "(null)") ; | |
427 | |
428 /* Clear out SF_INFO struct and set channels > 0. */ | |
429 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
430 sfinfo.channels = 1 ; | |
431 | |
432 /* First test simple formats. */ | |
433 | |
434 sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &count, sizeof (int)) ; | |
435 | |
436 if (count < 0 || count > 30) | |
437 { printf ("Line %d: Weird count.\n", __LINE__) ; | |
438 exit (1) ; | |
439 } ; | |
440 | |
441 format_info.format = 0 ; | |
442 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; | |
443 | |
444 last_name = format_info.name ; | |
445 for (k = 1 ; k < count ; k ++) | |
446 { format_info.format = k ; | |
447 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; | |
448 if (strcmp (last_name, format_info.name) >= 0) | |
449 { printf ("\n\nLine %d: format names out of sequence `%s' < `%s'.\n", __LINE__, last_name, format_info.name) ; | |
450 exit (1) ; | |
451 } ; | |
452 sfinfo.format = format_info.format ; | |
453 | |
454 if (! sf_format_check (&sfinfo)) | |
455 { printf ("\n\nLine %d: sf_format_check failed.\n", __LINE__) ; | |
456 printf (" Name : %s\n", format_info.name) ; | |
457 printf (" Format : 0x%X\n", sfinfo.format) ; | |
458 printf (" Channels : 0x%X\n", sfinfo.channels) ; | |
459 printf (" Sample Rate : 0x%X\n", sfinfo.samplerate) ; | |
460 exit (1) ; | |
461 } ; | |
462 last_name = format_info.name ; | |
463 } ; | |
464 format_info.format = 666 ; | |
465 sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ; | |
466 | |
467 /* Now test major formats. */ | |
468 sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ; | |
469 | |
470 if (count < 0 || count > 30) | |
471 { printf ("Line %d: Weird count.\n", __LINE__) ; | |
472 exit (1) ; | |
473 } ; | |
474 | |
475 format_info.format = 0 ; | |
476 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; | |
477 | |
478 last_name = format_info.name ; | |
479 for (k = 1 ; k < count ; k ++) | |
480 { format_info.format = k ; | |
481 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; | |
482 if (strcmp (last_name, format_info.name) >= 0) | |
483 { printf ("\n\nLine %d: format names out of sequence (%d) `%s' < `%s'.\n", __LINE__, k, last_name, format_info.name) ; | |
484 exit (1) ; | |
485 } ; | |
486 | |
487 last_name = format_info.name ; | |
488 } ; | |
489 format_info.format = 666 ; | |
490 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; | |
491 | |
492 /* Now test subtype formats. */ | |
493 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ; | |
494 | |
495 if (count < 0 || count > 30) | |
496 { printf ("Line %d: Weird count.\n", __LINE__) ; | |
497 exit (1) ; | |
498 } ; | |
499 | |
500 format_info.format = 0 ; | |
501 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; | |
502 | |
503 last_name = format_info.name ; | |
504 for (k = 1 ; k < count ; k ++) | |
505 { format_info.format = k ; | |
506 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; | |
507 } ; | |
508 format_info.format = 666 ; | |
509 sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ; | |
510 | |
511 | |
512 printf ("ok\n") ; | |
513 } /* format_tests */ | |
514 | |
515 static void | |
516 calc_peak_test (int filetype, const char *filename) | |
517 { SNDFILE *file ; | |
518 SF_INFO sfinfo ; | |
519 int k, format ; | |
520 double peak ; | |
521 | |
522 print_test_name ("calc_peak_test", filename) ; | |
523 | |
524 format = (filetype | SF_FORMAT_PCM_16) ; | |
525 | |
526 sfinfo.samplerate = 44100 ; | |
527 sfinfo.format = format ; | |
528 sfinfo.channels = 1 ; | |
529 sfinfo.frames = BUFFER_LEN ; | |
530 | |
531 /* Create double_data with max value of 0.5. */ | |
532 for (k = 0 ; k < BUFFER_LEN ; k++) | |
533 double_data [k] = (k + 1) / (2.0 * BUFFER_LEN) ; | |
534 | |
535 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
536 | |
537 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
538 | |
539 sf_close (file) ; | |
540 | |
541 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
542 | |
543 if (sfinfo.format != format) | |
544 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ; | |
545 exit (1) ; | |
546 } ; | |
547 | |
548 if (sfinfo.frames != BUFFER_LEN) | |
549 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ; | |
550 exit (1) ; | |
551 } ; | |
552 | |
553 if (sfinfo.channels != 1) | |
554 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; | |
555 exit (1) ; | |
556 } ; | |
557 | |
558 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ; | |
559 if (fabs (peak - (1 << 14)) > 1.0) | |
560 { printf ("Line %d : Peak value should be %d (is %f).\n", __LINE__, (1 << 14), peak) ; | |
561 exit (1) ; | |
562 } ; | |
563 | |
564 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ; | |
565 if (fabs (peak - 0.5) > 4e-5) | |
566 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; | |
567 exit (1) ; | |
568 } ; | |
569 | |
570 sf_close (file) ; | |
571 | |
572 format = (filetype | SF_FORMAT_FLOAT) ; | |
573 sfinfo.samplerate = 44100 ; | |
574 sfinfo.format = format ; | |
575 sfinfo.channels = 1 ; | |
576 sfinfo.frames = BUFFER_LEN ; | |
577 | |
578 /* Create double_data with max value of 0.5. */ | |
579 for (k = 0 ; k < BUFFER_LEN ; k++) | |
580 double_data [k] = (k + 1) / (2.0 * BUFFER_LEN) ; | |
581 | |
582 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
583 | |
584 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
585 | |
586 sf_close (file) ; | |
587 | |
588 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
589 | |
590 if (sfinfo.format != format) | |
591 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ; | |
592 exit (1) ; | |
593 } ; | |
594 | |
595 if (sfinfo.frames != BUFFER_LEN) | |
596 { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ; | |
597 exit (1) ; | |
598 } ; | |
599 | |
600 if (sfinfo.channels != 1) | |
601 { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; | |
602 exit (1) ; | |
603 } ; | |
604 | |
605 sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ; | |
606 if (fabs (peak - 0.5) > 1e-5) | |
607 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; | |
608 exit (1) ; | |
609 } ; | |
610 | |
611 sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ; | |
612 if (fabs (peak - 0.5) > 1e-5) | |
613 { printf ("Line %d : Peak value should be %f (is %f).\n", __LINE__, 0.5, peak) ; | |
614 exit (1) ; | |
615 } ; | |
616 | |
617 sf_close (file) ; | |
618 | |
619 unlink (filename) ; | |
620 | |
621 printf ("ok\n") ; | |
622 } /* calc_peak_test */ | |
623 | |
624 static void | |
625 truncate_test (const char *filename, int filetype) | |
626 { SNDFILE *file ; | |
627 SF_INFO sfinfo ; | |
628 sf_count_t len ; | |
629 | |
630 print_test_name ("truncate_test", filename) ; | |
631 | |
632 sfinfo.samplerate = 11025 ; | |
633 sfinfo.format = filetype ; | |
634 sfinfo.channels = 2 ; | |
635 | |
636 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; | |
637 | |
638 test_write_int_or_die (file, 0, int_data, BUFFER_LEN, __LINE__) ; | |
639 | |
640 len = 100 ; | |
641 if (sf_command (file, SFC_FILE_TRUNCATE, &len, sizeof (len))) | |
642 { printf ("Line %d: sf_command (SFC_FILE_TRUNCATE) returned error.\n", __LINE__) ; | |
643 exit (1) ; | |
644 } ; | |
645 | |
646 test_seek_or_die (file, 0, SEEK_CUR, len, 2, __LINE__) ; | |
647 test_seek_or_die (file, 0, SEEK_END, len, 2, __LINE__) ; | |
648 | |
649 sf_close (file) ; | |
650 | |
651 unlink (filename) ; | |
652 puts ("ok") ; | |
653 } /* truncate_test */ | |
654 | |
655 /*------------------------------------------------------------------------------ | |
656 */ | |
657 | |
658 static void | |
659 instrumet_rw_test (const char *filename) | |
660 { SNDFILE *sndfile ; | |
661 SF_INFO sfinfo ; | |
662 SF_INSTRUMENT inst ; | |
663 memset (&sfinfo, 0, sizeof (SF_INFO)) ; | |
664 | |
665 sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; | |
666 | |
667 if (sf_command (sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE) | |
668 { inst.basenote = 22 ; | |
669 | |
670 if (sf_command (sndfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE) | |
671 printf ("Sucess: [%s] updated\n", filename) ; | |
672 else | |
673 printf ("Error: SFC_SET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; | |
674 } | |
675 else | |
676 printf ("Error: SFC_GET_INSTRUMENT on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; | |
677 | |
678 | |
679 if (sf_command (sndfile, SFC_UPDATE_HEADER_NOW, NULL, 0) != 0) | |
680 printf ("Error: SFC_UPDATE_HEADER_NOW on [%s] [%s]\n", filename, sf_strerror (sndfile)) ; | |
681 | |
682 sf_write_sync (sndfile) ; | |
683 sf_close (sndfile) ; | |
684 | |
685 return ; | |
686 } /* instrumet_rw_test */ | |
687 | |
688 static void | |
689 instrument_test (const char *filename, int filetype) | |
690 { static SF_INSTRUMENT write_inst = | |
691 { 2, /* gain */ | |
692 3, /* detune */ | |
693 4, /* basenote */ | |
694 5, 6, /* key low and high */ | |
695 7, 8, /* velocity low and high */ | |
696 2, /* loop_count */ | |
697 { { 801, 2, 3, 0 }, | |
698 { 801, 3, 4, 0 }, | |
699 } | |
700 } ; | |
701 SF_INSTRUMENT read_inst ; | |
702 SNDFILE *file ; | |
703 SF_INFO sfinfo ; | |
704 | |
705 print_test_name ("instrument_test", filename) ; | |
706 | |
707 sfinfo.samplerate = 11025 ; | |
708 sfinfo.format = filetype ; | |
709 sfinfo.channels = 1 ; | |
710 | |
711 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
712 if (sf_command (file, SFC_SET_INSTRUMENT, &write_inst, sizeof (write_inst)) == SF_FALSE) | |
713 { printf ("\n\nLine %d : sf_command (SFC_SET_INSTRUMENT) failed.\n\n", __LINE__) ; | |
714 exit (1) ; | |
715 } ; | |
716 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
717 sf_close (file) ; | |
718 | |
719 memset (&read_inst, 0, sizeof (read_inst)) ; | |
720 | |
721 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
722 if (sf_command (file, SFC_GET_INSTRUMENT, &read_inst, sizeof (read_inst)) == SF_FALSE) | |
723 { printf ("\n\nLine %d : sf_command (SFC_GET_INSTRUMENT) failed.\n\n", __LINE__) ; | |
724 exit (1) ; | |
725 return ; | |
726 } ; | |
727 check_log_buffer_or_die (file, __LINE__) ; | |
728 sf_close (file) ; | |
729 | |
730 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV) | |
731 { /* | |
732 ** For all the fields that WAV doesn't support, modify the | |
733 ** write_inst struct to hold the default value that the WAV | |
734 ** module should hold. | |
735 */ | |
736 write_inst.detune = 0 ; | |
737 write_inst.key_lo = write_inst.velocity_lo = 0 ; | |
738 write_inst.key_hi = write_inst.velocity_hi = 127 ; | |
739 write_inst.gain = 1 ; | |
740 } ; | |
741 | |
742 if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI) | |
743 { /* | |
744 ** For all the fields that XI doesn't support, modify the | |
745 ** write_inst struct to hold the default value that the XI | |
746 ** module should hold. | |
747 */ | |
748 write_inst.basenote = 0 ; | |
749 write_inst.detune = 0 ; | |
750 write_inst.key_lo = write_inst.velocity_lo = 0 ; | |
751 write_inst.key_hi = write_inst.velocity_hi = 127 ; | |
752 write_inst.gain = 1 ; | |
753 } ; | |
754 | |
755 if (memcmp (&write_inst, &read_inst, sizeof (write_inst)) != 0) | |
756 { printf ("\n\nLine %d : instrument comparison failed.\n\n", __LINE__) ; | |
757 printf ("W Base Note : %u\n" | |
758 " Detune : %u\n" | |
759 " Low Note : %u\tHigh Note : %u\n" | |
760 " Low Vel. : %u\tHigh Vel. : %u\n" | |
761 " Gain : %d\tCount : %d\n" | |
762 " mode : %d\n" | |
763 " start : %d\tend : %d\tcount :%d\n" | |
764 " mode : %d\n" | |
765 " start : %d\tend : %d\tcount :%d\n\n", | |
766 write_inst.basenote, | |
767 write_inst.detune, | |
768 write_inst.key_lo, write_inst.key_hi, | |
769 write_inst.velocity_lo, write_inst.velocity_hi, | |
770 write_inst.gain, write_inst.loop_count, | |
771 write_inst.loops [0].mode, write_inst.loops [0].start, | |
772 write_inst.loops [0].end, write_inst.loops [0].count, | |
773 write_inst.loops [1].mode, write_inst.loops [1].start, | |
774 write_inst.loops [1].end, write_inst.loops [1].count) ; | |
775 printf ("R Base Note : %u\n" | |
776 " Detune : %u\n" | |
777 " Low Note : %u\tHigh Note : %u\n" | |
778 " Low Vel. : %u\tHigh Vel. : %u\n" | |
779 " Gain : %d\tCount : %d\n" | |
780 " mode : %d\n" | |
781 " start : %d\tend : %d\tcount :%d\n" | |
782 " mode : %d\n" | |
783 " start : %d\tend : %d\tcount :%d\n\n", | |
784 read_inst.basenote, | |
785 read_inst.detune, | |
786 read_inst.key_lo, read_inst.key_hi, | |
787 read_inst.velocity_lo, read_inst.velocity_hi, | |
788 read_inst.gain, read_inst.loop_count, | |
789 read_inst.loops [0].mode, read_inst.loops [0].start, | |
790 read_inst.loops [0].end, read_inst.loops [0].count, | |
791 read_inst.loops [1].mode, read_inst.loops [1].start, | |
792 read_inst.loops [1].end, read_inst.loops [1].count) ; | |
793 | |
794 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI) | |
795 exit (1) ; | |
796 } ; | |
797 | |
798 if (0) instrumet_rw_test (filename) ; | |
799 | |
800 unlink (filename) ; | |
801 puts ("ok") ; | |
802 } /* instrument_test */ | |
803 | |
804 static void | |
805 current_sf_info_test (const char *filename) | |
806 { SNDFILE *outfile, *infile ; | |
807 SF_INFO outinfo, ininfo ; | |
808 | |
809 print_test_name ("current_sf_info_test", filename) ; | |
810 | |
811 outinfo.samplerate = 44100 ; | |
812 outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; | |
813 outinfo.channels = 1 ; | |
814 outinfo.frames = 0 ; | |
815 | |
816 outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ; | |
817 sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ; | |
818 | |
819 exit_if_true (outinfo.frames != 0, | |
820 "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__ | |
821 ) ; | |
822 | |
823 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; | |
824 sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ; | |
825 | |
826 exit_if_true (outinfo.frames != BUFFER_LEN, | |
827 "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, | |
828 SF_COUNT_TO_LONG (outinfo.frames), BUFFER_LEN | |
829 ) ; | |
830 | |
831 /* Read file making sure no channel map exists. */ | |
832 memset (&ininfo, 0, sizeof (ininfo)) ; | |
833 infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ; | |
834 | |
835 test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; | |
836 | |
837 sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ; | |
838 | |
839 exit_if_true (ininfo.frames != BUFFER_LEN, | |
840 "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, | |
841 SF_COUNT_TO_LONG (ininfo.frames), BUFFER_LEN | |
842 ) ; | |
843 | |
844 sf_close (outfile) ; | |
845 sf_close (infile) ; | |
846 | |
847 unlink (filename) ; | |
848 puts ("ok") ; | |
849 } /* current_sf_info_test */ | |
850 | |
851 static void | |
852 broadcast_test (const char *filename, int filetype) | |
853 { static SF_BROADCAST_INFO bc_write, bc_read ; | |
854 SNDFILE *file ; | |
855 SF_INFO sfinfo ; | |
856 int errors = 0 ; | |
857 | |
858 print_test_name ("broadcast_test", filename) ; | |
859 | |
860 sfinfo.samplerate = 11025 ; | |
861 sfinfo.format = filetype ; | |
862 sfinfo.channels = 1 ; | |
863 | |
864 memset (&bc_write, 0, sizeof (bc_write)) ; | |
865 | |
866 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; | |
867 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; | |
868 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; | |
869 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; | |
870 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; | |
871 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; | |
872 bc_write.coding_history_size = 0 ; | |
873 | |
874 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
875 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) | |
876 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
877 exit (1) ; | |
878 } ; | |
879 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
880 sf_close (file) ; | |
881 | |
882 memset (&bc_read, 0, sizeof (bc_read)) ; | |
883 | |
884 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
885 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) | |
886 { printf ("\n\nLine %d : sf_command (SFC_GET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
887 exit (1) ; | |
888 return ; | |
889 } ; | |
890 check_log_buffer_or_die (file, __LINE__) ; | |
891 sf_close (file) ; | |
892 | |
893 if (bc_read.version != 1) | |
894 { printf ("\n\nLine %d : Read bad version number %d.\n\n", __LINE__, bc_read.version) ; | |
895 exit (1) ; | |
896 return ; | |
897 } ; | |
898 | |
899 bc_read.version = bc_write.version = 0 ; | |
900 | |
901 if (memcmp (bc_write.description, bc_read.description, sizeof (bc_write.description)) != 0) | |
902 { printf ("\n\nLine %d : description mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.description, bc_read.description) ; | |
903 errors ++ ; | |
904 } ; | |
905 | |
906 if (memcmp (bc_write.originator, bc_read.originator, sizeof (bc_write.originator)) != 0) | |
907 { printf ("\n\nLine %d : originator mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator, bc_read.originator) ; | |
908 errors ++ ; | |
909 } ; | |
910 | |
911 if (memcmp (bc_write.originator_reference, bc_read.originator_reference, sizeof (bc_write.originator_reference)) != 0) | |
912 { printf ("\n\nLine %d : originator_reference mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.originator_reference, bc_read.originator_reference) ; | |
913 errors ++ ; | |
914 } ; | |
915 | |
916 if (memcmp (bc_write.origination_date, bc_read.origination_date, sizeof (bc_write.origination_date)) != 0) | |
917 { printf ("\n\nLine %d : origination_date mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_date, bc_read.origination_date) ; | |
918 errors ++ ; | |
919 } ; | |
920 | |
921 if (memcmp (bc_write.origination_time, bc_read.origination_time, sizeof (bc_write.origination_time)) != 0) | |
922 { printf ("\n\nLine %d : origination_time mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.origination_time, bc_read.origination_time) ; | |
923 errors ++ ; | |
924 } ; | |
925 | |
926 if (memcmp (bc_write.umid, bc_read.umid, sizeof (bc_write.umid)) != 0) | |
927 { printf ("\n\nLine %d : umid mismatch :\n\twrite : '%s'\n\tread : '%s'\n\n", __LINE__, bc_write.umid, bc_read.umid) ; | |
928 errors ++ ; | |
929 } ; | |
930 | |
931 if (errors) | |
932 exit (1) ; | |
933 | |
934 unlink (filename) ; | |
935 puts ("ok") ; | |
936 } /* broadcast_test */ | |
937 | |
938 static void | |
939 broadcast_rdwr_test (const char *filename, int filetype) | |
940 { SF_BROADCAST_INFO binfo ; | |
941 SNDFILE *file ; | |
942 SF_INFO sfinfo ; | |
943 sf_count_t frames ; | |
944 | |
945 print_test_name (__func__, filename) ; | |
946 | |
947 create_short_sndfile (filename, filetype, 2) ; | |
948 | |
949 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
950 memset (&binfo, 0, sizeof (binfo)) ; | |
951 | |
952 snprintf (binfo.description, sizeof (binfo.description), "Test description") ; | |
953 snprintf (binfo.originator, sizeof (binfo.originator), "Test originator") ; | |
954 snprintf (binfo.originator_reference, sizeof (binfo.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; | |
955 snprintf (binfo.origination_date, sizeof (binfo.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; | |
956 snprintf (binfo.origination_time, sizeof (binfo.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; | |
957 snprintf (binfo.umid, sizeof (binfo.umid), "Some umid") ; | |
958 binfo.coding_history_size = 0 ; | |
959 | |
960 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; | |
961 frames = sfinfo.frames ; | |
962 if (sf_command (file, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) != SF_FALSE) | |
963 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) should have failed but didn't.\n\n", __LINE__) ; | |
964 exit (1) ; | |
965 } ; | |
966 sf_close (file) ; | |
967 | |
968 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
969 sf_close (file) ; | |
970 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %lld should be %lld.\n", __LINE__, sfinfo.frames, frames) ; | |
971 | |
972 unlink (filename) ; | |
973 puts ("ok") ; | |
974 } /* broadcast_rdwr_test */ | |
975 | |
976 static void | |
977 check_coding_history_newlines (const char *filename) | |
978 { static SF_BROADCAST_INFO bc_write, bc_read ; | |
979 SNDFILE *file ; | |
980 SF_INFO sfinfo ; | |
981 unsigned k ; | |
982 | |
983 sfinfo.samplerate = 22050 ; | |
984 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; | |
985 sfinfo.channels = 1 ; | |
986 | |
987 memset (&bc_write, 0, sizeof (bc_write)) ; | |
988 | |
989 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; | |
990 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; | |
991 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; | |
992 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; | |
993 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; | |
994 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; | |
995 bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "This has\nUnix\nand\rMac OS9\rline endings.\nLast line") ; ; | |
996 | |
997 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
998 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) | |
999 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1000 exit (1) ; | |
1001 } ; | |
1002 | |
1003 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1004 sf_close (file) ; | |
1005 | |
1006 memset (&bc_read, 0, sizeof (bc_read)) ; | |
1007 | |
1008 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1009 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) | |
1010 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1011 exit (1) ; | |
1012 } ; | |
1013 check_log_buffer_or_die (file, __LINE__) ; | |
1014 sf_close (file) ; | |
1015 | |
1016 if (bc_read.coding_history_size == 0) | |
1017 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ; | |
1018 exit (1) ; | |
1019 } ; | |
1020 | |
1021 if (strstr (bc_read.coding_history, "Last line") == NULL) | |
1022 { printf ("\n\nLine %d : coding history truncated.\n\n", __LINE__) ; | |
1023 exit (1) ; | |
1024 } ; | |
1025 | |
1026 for (k = 1 ; k < bc_read.coding_history_size ; k++) | |
1027 { if (bc_read.coding_history [k] == '\n' && bc_read.coding_history [k - 1] != '\r') | |
1028 { printf ("\n\nLine %d : '\\n' without '\\r' before.\n\n", __LINE__) ; | |
1029 exit (1) ; | |
1030 } ; | |
1031 | |
1032 if (bc_read.coding_history [k] == '\r' && bc_read.coding_history [k + 1] != '\n') | |
1033 { printf ("\n\nLine %d : '\\r' without '\\n' after.\n\n", __LINE__) ; | |
1034 exit (1) ; | |
1035 } ; | |
1036 | |
1037 if (bc_read.coding_history [k] == 0 && k < bc_read.coding_history_size - 1) | |
1038 { printf ("\n\nLine %d : '\\0' within coding history at index %d of %d.\n\n", __LINE__, k, bc_read.coding_history_size) ; | |
1039 exit (1) ; | |
1040 } ; | |
1041 } ; | |
1042 | |
1043 return ; | |
1044 } /* check_coding_history_newlines */ | |
1045 | |
1046 static void | |
1047 broadcast_coding_history_test (const char *filename) | |
1048 { static SF_BROADCAST_INFO bc_write, bc_read ; | |
1049 SNDFILE *file ; | |
1050 SF_INFO sfinfo ; | |
1051 const char *default_history = "A=PCM,F=22050,W=16,M=mono" ; | |
1052 const char *supplied_history = | |
1053 "A=PCM,F=44100,W=24,M=mono,T=other\r\n" | |
1054 "A=PCM,F=22050,W=16,M=mono,T=yet_another\r\n" ; | |
1055 | |
1056 print_test_name ("broadcast_coding_history_test", filename) ; | |
1057 | |
1058 sfinfo.samplerate = 22050 ; | |
1059 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; | |
1060 sfinfo.channels = 1 ; | |
1061 | |
1062 memset (&bc_write, 0, sizeof (bc_write)) ; | |
1063 | |
1064 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; | |
1065 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; | |
1066 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; | |
1067 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; | |
1068 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; | |
1069 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; | |
1070 /* Coding history will be filled in by the library. */ | |
1071 bc_write.coding_history_size = 0 ; | |
1072 | |
1073 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1074 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) | |
1075 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1076 exit (1) ; | |
1077 } ; | |
1078 | |
1079 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1080 sf_close (file) ; | |
1081 | |
1082 memset (&bc_read, 0, sizeof (bc_read)) ; | |
1083 | |
1084 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1085 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) | |
1086 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1087 exit (1) ; | |
1088 } ; | |
1089 check_log_buffer_or_die (file, __LINE__) ; | |
1090 sf_close (file) ; | |
1091 | |
1092 if (bc_read.coding_history_size == 0) | |
1093 { printf ("\n\nLine %d : missing coding history.\n\n", __LINE__) ; | |
1094 exit (1) ; | |
1095 } ; | |
1096 | |
1097 if (bc_read.coding_history_size < strlen (default_history) || memcmp (bc_read.coding_history, default_history, strlen (default_history)) != 0) | |
1098 { printf ("\n\n" | |
1099 "Line %d : unexpected coding history '%.*s',\n" | |
1100 " should be '%s'\n\n", __LINE__, bc_read.coding_history_size, bc_read.coding_history, default_history) ; | |
1101 exit (1) ; | |
1102 } ; | |
1103 | |
1104 bc_write.coding_history_size = strlen (supplied_history) ; | |
1105 bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "%s", supplied_history) ; | |
1106 | |
1107 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1108 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) | |
1109 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1110 exit (1) ; | |
1111 } ; | |
1112 | |
1113 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1114 sf_close (file) ; | |
1115 | |
1116 memset (&bc_read, 0, sizeof (bc_read)) ; | |
1117 | |
1118 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1119 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) | |
1120 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1121 exit (1) ; | |
1122 } ; | |
1123 | |
1124 check_log_buffer_or_die (file, __LINE__) ; | |
1125 sf_close (file) ; | |
1126 | |
1127 if (strstr (bc_read.coding_history, supplied_history) != bc_read.coding_history) | |
1128 { printf ("\n\nLine %d : unexpected coding history :\n" | |
1129 "----------------------------------------------------\n%s" | |
1130 "----------------------------------------------------\n" | |
1131 "should be this :\n" | |
1132 "----------------------------------------------------\n%s" | |
1133 "----------------------------------------------------\n" | |
1134 "with one more line at the end.\n\n", | |
1135 __LINE__, bc_read.coding_history, supplied_history) ; | |
1136 exit (1) ; | |
1137 } ; | |
1138 | |
1139 check_coding_history_newlines (filename) ; | |
1140 | |
1141 unlink (filename) ; | |
1142 puts ("ok") ; | |
1143 } /* broadcast_coding_history_test */ | |
1144 | |
1145 /*============================================================================== | |
1146 */ | |
1147 | |
1148 static void | |
1149 broadcast_coding_history_size (const char *filename) | |
1150 { /* SF_BROADCAST_INFO struct with coding_history field of 1024 bytes. */ | |
1151 static SF_BROADCAST_INFO_VAR (1024) bc_write ; | |
1152 static SF_BROADCAST_INFO_VAR (1024) bc_read ; | |
1153 SNDFILE *file ; | |
1154 SF_INFO sfinfo ; | |
1155 int k ; | |
1156 | |
1157 print_test_name (__func__, filename) ; | |
1158 | |
1159 sfinfo.samplerate = 22050 ; | |
1160 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; | |
1161 sfinfo.channels = 1 ; | |
1162 | |
1163 memset (&bc_write, 0, sizeof (bc_write)) ; | |
1164 | |
1165 snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; | |
1166 snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; | |
1167 snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; | |
1168 snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; | |
1169 snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; | |
1170 snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; | |
1171 bc_write.coding_history_size = 0 ; | |
1172 | |
1173 for (k = 0 ; bc_write.coding_history_size < 512 ; k++) | |
1174 { snprintf (bc_write.coding_history + bc_write.coding_history_size, | |
1175 sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4d\n", k) ; | |
1176 bc_write.coding_history_size = strlen (bc_write.coding_history) ; | |
1177 } ; | |
1178 | |
1179 exit_if_true (bc_write.coding_history_size < 512, | |
1180 "\n\nLine %d : bc_write.coding_history_size (%d) should be > 512.\n\n", __LINE__, bc_write.coding_history_size) ; | |
1181 | |
1182 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1183 if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) | |
1184 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1185 exit (1) ; | |
1186 } ; | |
1187 | |
1188 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1189 sf_close (file) ; | |
1190 | |
1191 memset (&bc_read, 0, sizeof (bc_read)) ; | |
1192 | |
1193 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1194 if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) | |
1195 { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; | |
1196 exit (1) ; | |
1197 } ; | |
1198 check_log_buffer_or_die (file, __LINE__) ; | |
1199 sf_close (file) ; | |
1200 | |
1201 exit_if_true (bc_read.coding_history_size < 512, | |
1202 "\n\nLine %d : unexpected coding history size %d (should be > 512).\n\n", __LINE__, bc_read.coding_history_size) ; | |
1203 | |
1204 exit_if_true (strstr (bc_read.coding_history, "libsndfile") == NULL, | |
1205 "\n\nLine %d : coding history incomplete (should contain 'libsndfile').\n\n", __LINE__) ; | |
1206 | |
1207 unlink (filename) ; | |
1208 puts ("ok") ; | |
1209 } /* broadcast_coding_history_size */ | |
1210 | |
1211 /*============================================================================== | |
1212 */ | |
1213 | |
1214 static void | |
1215 channel_map_test (const char *filename, int filetype) | |
1216 { SNDFILE *file ; | |
1217 SF_INFO sfinfo ; | |
1218 int channel_map_read [4], channel_map_write [4] = | |
1219 { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, | |
1220 SF_CHANNEL_MAP_REAR_CENTER | |
1221 } ; | |
1222 | |
1223 print_test_name ("channel_map_test", filename) ; | |
1224 | |
1225 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
1226 sfinfo.samplerate = 11025 ; | |
1227 sfinfo.format = filetype ; | |
1228 sfinfo.channels = ARRAY_LEN (channel_map_read) ; | |
1229 | |
1230 switch (filetype & SF_FORMAT_TYPEMASK) | |
1231 { /* WAVEX and RF64 have a default channel map, even if you don't specify one. */ | |
1232 case SF_FORMAT_WAVEX : | |
1233 case SF_FORMAT_RF64 : | |
1234 /* Write file without channel map. */ | |
1235 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1236 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1237 sf_close (file) ; | |
1238 | |
1239 /* Read file making default channel map exists. */ | |
1240 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1241 exit_if_true ( | |
1242 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) == SF_FALSE, | |
1243 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should not have failed.\n\n", __LINE__ | |
1244 ) ; | |
1245 check_log_buffer_or_die (file, __LINE__) ; | |
1246 sf_close (file) ; | |
1247 break ; | |
1248 | |
1249 default : | |
1250 break ; | |
1251 } ; | |
1252 | |
1253 /* Write file with a channel map. */ | |
1254 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1255 exit_if_true ( | |
1256 sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE, | |
1257 "\n\nLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ | |
1258 ) ; | |
1259 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1260 sf_close (file) ; | |
1261 | |
1262 /* Read file making sure no channel map exists. */ | |
1263 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1264 exit_if_true ( | |
1265 sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_TRUE, | |
1266 "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ | |
1267 ) ; | |
1268 check_log_buffer_or_die (file, __LINE__) ; | |
1269 sf_close (file) ; | |
1270 | |
1271 exit_if_true ( | |
1272 memcmp (channel_map_read, channel_map_write, sizeof (channel_map_read)) != 0, | |
1273 "\n\nLine %d : Channel map read does not match channel map written.\n\n", __LINE__ | |
1274 ) ; | |
1275 | |
1276 unlink (filename) ; | |
1277 puts ("ok") ; | |
1278 } /* channel_map_test */ | |
1279 | |
1280 static void | |
1281 raw_needs_endswap_test (const char *filename, int filetype) | |
1282 { static int subtypes [] = | |
1283 { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, | |
1284 SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 | |
1285 } ; | |
1286 SNDFILE *file ; | |
1287 SF_INFO sfinfo ; | |
1288 unsigned k ; | |
1289 int needs_endswap ; | |
1290 | |
1291 print_test_name (__func__, filename) ; | |
1292 | |
1293 for (k = 0 ; k < ARRAY_LEN (subtypes) ; k++) | |
1294 { | |
1295 if (filetype == (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF)) | |
1296 switch (subtypes [k]) | |
1297 { /* Little endian AIFF does not AFAIK support fl32 and fl64. */ | |
1298 case SF_FORMAT_FLOAT : | |
1299 case SF_FORMAT_DOUBLE : | |
1300 continue ; | |
1301 default : | |
1302 break ; | |
1303 } ; | |
1304 | |
1305 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
1306 sfinfo.samplerate = 11025 ; | |
1307 sfinfo.format = filetype | subtypes [k] ; | |
1308 sfinfo.channels = 1 ; | |
1309 | |
1310 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; | |
1311 test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; | |
1312 sf_close (file) ; | |
1313 | |
1314 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
1315 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; | |
1316 | |
1317 needs_endswap = sf_command (file, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0) ; | |
1318 | |
1319 switch (filetype) | |
1320 { case SF_FORMAT_WAV : | |
1321 case SF_FORMAT_WAVEX : | |
1322 case SF_FORMAT_AIFF | SF_ENDIAN_LITTLE : | |
1323 exit_if_true (needs_endswap != CPU_IS_BIG_ENDIAN, | |
1324 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; | |
1325 break ; | |
1326 | |
1327 case SF_FORMAT_AIFF : | |
1328 case SF_FORMAT_WAV | SF_ENDIAN_BIG : | |
1329 exit_if_true (needs_endswap != CPU_IS_LITTLE_ENDIAN, | |
1330 "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; | |
1331 break ; | |
1332 | |
1333 default : | |
1334 printf ("\n\nLine %d : bad format value %d.\n\n", __LINE__, filetype) ; | |
1335 exit (1) ; | |
1336 break ; | |
1337 } ; | |
1338 | |
1339 sf_close (file) ; | |
1340 } ; | |
1341 | |
1342 unlink (filename) ; | |
1343 puts ("ok") ; | |
1344 } /* raw_needs_endswap_test */ |