comparison src/libsndfile-1.0.27/tests/string_test.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) 2003-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 #include "sfconfig.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include <inttypes.h>
26
27 #if HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30
31 #include <sndfile.h>
32
33 #include "utils.h"
34
35 #define BUFFER_LEN (1 << 10)
36 #define LOG_BUFFER_SIZE 1024
37
38 static void string_start_test (const char *filename, int typemajor) ;
39 static void string_start_end_test (const char *filename, int typemajor) ;
40 static void string_multi_set_test (const char *filename, int typemajor) ;
41 static void string_rdwr_test (const char *filename, int typemajor) ;
42 static void string_short_rdwr_test (const char *filename, int typemajor) ;
43 static void string_rdwr_grow_test (const char *filename, int typemajor) ;
44 static void string_header_update (const char *filename, int typemajor) ;
45
46 static void software_string_test (const char *filename) ;
47
48 static int str_count (const char * haystack, const char * needle) ;
49
50 int
51 main (int argc, char *argv [])
52 { int do_all = 0 ;
53 int test_count = 0 ;
54
55 if (argc != 2)
56 { printf ("Usage : %s <test>\n", argv [0]) ;
57 printf (" Where <test> is one of the following:\n") ;
58 printf (" wav - test adding strings to WAV files\n") ;
59 printf (" aiff - test adding strings to AIFF files\n") ;
60 printf (" flac - test adding strings to FLAC files\n") ;
61 printf (" ogg - test adding strings to OGG files\n") ;
62 printf (" all - perform all tests\n") ;
63 exit (1) ;
64 } ;
65
66 do_all = ! strcmp (argv [1], "all") ;
67
68 if (do_all || ! strcmp (argv [1], "wav"))
69 { string_start_end_test ("strings.wav", SF_FORMAT_WAV) ;
70 string_multi_set_test ("multi.wav", SF_FORMAT_WAV) ;
71 string_rdwr_test ("rdwr.wav", SF_FORMAT_WAV) ;
72 string_short_rdwr_test ("short_rdwr.wav", SF_FORMAT_WAV) ;
73 string_rdwr_grow_test ("rdwr_grow.wav", SF_FORMAT_WAV) ;
74 string_header_update ("header_update.wav", SF_FORMAT_WAV) ;
75
76 string_start_end_test ("strings.wavex", SF_FORMAT_WAVEX) ;
77 string_multi_set_test ("multi.wavex", SF_FORMAT_WAVEX) ;
78 string_rdwr_test ("rdwr.wavex", SF_FORMAT_WAVEX) ;
79 string_short_rdwr_test ("short_rdwr.wavex", SF_FORMAT_WAVEX) ;
80
81 string_start_end_test ("strings.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
82 string_multi_set_test ("multi.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
83 string_rdwr_test ("rdwr.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
84 string_short_rdwr_test ("short_rdwr.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
85
86 software_string_test ("software_string.wav") ;
87 test_count++ ;
88 } ;
89
90 if (do_all || ! strcmp (argv [1], "aiff"))
91 { string_start_test ("strings.aiff", SF_FORMAT_AIFF) ;
92 string_start_end_test ("strings.aiff", SF_FORMAT_AIFF) ;
93 /*
94 TODO : Fix src/aiff.c so these tests pass.
95 string_multi_set_test ("multi.aiff", SF_FORMAT_AIFF) ;
96 string_rdwr_test ("rdwr.aiff", SF_FORMAT_AIFF) ;
97 string_short_rdwr_test ("short_rdwr.aiff", SF_FORMAT_AIFF) ;
98 string_rdwr_grow_test ("rdwr_grow.aiff", SF_FORMAT_AIFF) ;
99 string_header_update ("header_update.aiff", SF_FORMAT_AIFF) ;
100 */
101
102 test_count++ ;
103 } ;
104
105 if (do_all || ! strcmp (argv [1], "flac"))
106 { if (HAVE_EXTERNAL_XIPH_LIBS)
107 string_start_test ("strings.flac", SF_FORMAT_FLAC) ;
108 else
109 puts (" No FLAC tests because FLAC support was not compiled in.") ;
110 test_count++ ;
111 } ;
112
113 if (do_all || ! strcmp (argv [1], "ogg"))
114 { if (HAVE_EXTERNAL_XIPH_LIBS)
115 string_start_test ("vorbis.oga", SF_FORMAT_OGG) ;
116 else
117 puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
118 test_count++ ;
119 } ;
120
121 if (do_all || ! strcmp (argv [1], "caf"))
122 { string_start_test ("strings.caf", SF_FORMAT_CAF) ;
123 string_start_end_test ("strings.caf", SF_FORMAT_CAF) ;
124 string_multi_set_test ("multi.caf", SF_FORMAT_CAF) ;
125 /*
126 TODO : Fix src/caf.c so these tests pass.
127 string_rdwr_test ("rdwr.caf", SF_FORMAT_CAF) ;
128 string_short_rdwr_test ("short_rdwr.caf", SF_FORMAT_CAF) ;
129 string_header_update ("header_update.caf", SF_FORMAT_CAF) ;
130 */
131 test_count++ ;
132 } ;
133
134 if (do_all || ! strcmp (argv [1], "rf64"))
135 { string_start_test ("strings.rf64", SF_FORMAT_RF64) ;
136 string_start_end_test ("strings.rf64", SF_FORMAT_RF64) ;
137 string_multi_set_test ("multi.rf64", SF_FORMAT_RF64) ;
138 /*
139 TODO : Fix src/rf64.c so these tests pass.
140 string_rdwr_test ("rdwr.rf64", SF_FORMAT_RF64) ;
141 string_short_rdwr_test ("short_rdwr.rf64", SF_FORMAT_RF64) ;
142 string_header_update ("header_update.rf64", SF_FORMAT_RF64) ;
143 */
144 test_count++ ;
145 } ;
146
147 if (do_all || ! strcmp (argv [1], "w64"))
148 { puts ("\n\n **** String test not working yet for W64 format. ****\n") ;
149 /*
150 string_start_test ("strings.w64", SF_FORMAT_W64) ;
151 string_start_end_test ("strings.w64", SF_FORMAT_W64) ;
152 string_multi_set_test ("multi.w64", SF_FORMAT_W64) ;
153 string_rdwr_test ("rdwr.w64", SF_FORMAT_W64) ;
154 string_short_rdwr_test ("short_rdwr.w64", SF_FORMAT_W64) ;
155 string_header_update ("header_update.w64", SF_FORMAT_W64) ;
156 */
157 test_count++ ;
158 } ;
159
160 if (test_count == 0)
161 { printf ("Mono : ************************************\n") ;
162 printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
163 printf ("Mono : ************************************\n") ;
164 return 1 ;
165 } ;
166
167 return 0 ;
168 } /* main */
169
170
171 /*============================================================================================
172 ** Here are the test functions.
173 */
174
175 static const char
176 software [] = "software (libsndfile-X.Y.Z)",
177 artist [] = "The Artist",
178 copyright [] = "Copyright (c) 2001 Artist",
179 comment [] = "Comment goes here!!!",
180 date [] = "2001/01/27",
181 album [] = "The Album",
182 license [] = "The license",
183 title [] = "This is the title",
184 long_title [] = "This is a very long and very boring title for this file",
185 long_artist [] = "The artist who kept on changing its name",
186 genre [] = "The genre",
187 trackno [] = "Track three" ;
188
189
190 static short data_out [BUFFER_LEN] ;
191
192 static void
193 string_start_end_test (const char *filename, int typemajor)
194 { const char *cptr ;
195 SNDFILE *file ;
196 SF_INFO sfinfo ;
197 int errors = 0 ;
198
199 print_test_name ("string_start_end_test", filename) ;
200
201 memset (&sfinfo, 0, sizeof (sfinfo)) ;
202 sfinfo.samplerate = 44100 ;
203 sfinfo.channels = 1 ;
204 sfinfo.frames = 0 ;
205 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
206
207 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
208
209 /* Write stuff at start of file. */
210 sf_set_string (file, SF_STR_TITLE, filename) ;
211 sf_set_string (file, SF_STR_SOFTWARE, software) ;
212 sf_set_string (file, SF_STR_ARTIST, artist) ;
213 sf_set_string (file, SF_STR_GENRE, genre) ;
214 sf_set_string (file, SF_STR_TRACKNUMBER, trackno) ;
215
216 /* Write data to file. */
217 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
218 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
219
220 /* Write more stuff at end of file. */
221 sf_set_string (file, SF_STR_COPYRIGHT, copyright) ;
222 sf_set_string (file, SF_STR_COMMENT, comment) ;
223 sf_set_string (file, SF_STR_DATE, date) ;
224 sf_set_string (file, SF_STR_ALBUM, album) ;
225 sf_set_string (file, SF_STR_LICENSE, license) ;
226
227 sf_close (file) ;
228
229 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
230
231 check_log_buffer_or_die (file, __LINE__) ;
232
233 if (sfinfo.frames != BUFFER_LEN)
234 { printf ("***** Bad frame count %d (should be %d)\n\n", (int) sfinfo.frames, BUFFER_LEN) ;
235 errors ++ ;
236 } ;
237
238 cptr = sf_get_string (file, SF_STR_TITLE) ;
239 if (cptr == NULL || strcmp (filename, cptr) != 0)
240 { if (errors++ == 0)
241 puts ("\n") ;
242 printf (" Bad filename : %s\n", cptr) ;
243 } ;
244
245 cptr = sf_get_string (file, SF_STR_COPYRIGHT) ;
246 if (cptr == NULL || strcmp (copyright, cptr) != 0)
247 { if (errors++ == 0)
248 puts ("\n") ;
249 printf (" Bad copyright : %s\n", cptr) ;
250 } ;
251
252 cptr = sf_get_string (file, SF_STR_SOFTWARE) ;
253 if (cptr == NULL || strstr (cptr, software) != cptr)
254 { if (errors++ == 0)
255 puts ("\n") ;
256 printf (" Bad software : %s\n", cptr) ;
257 } ;
258
259 if (str_count (cptr, "libsndfile") != 1)
260 { if (errors++ == 0)
261 puts ("\n") ;
262 printf (" Bad software : %s\n", cptr) ;
263 } ;
264
265 cptr = sf_get_string (file, SF_STR_ARTIST) ;
266 if (cptr == NULL || strcmp (artist, cptr) != 0)
267 { if (errors++ == 0)
268 puts ("\n") ;
269 printf (" Bad artist : %s\n", cptr) ;
270 } ;
271
272 cptr = sf_get_string (file, SF_STR_COMMENT) ;
273 if (cptr == NULL || strcmp (comment, cptr) != 0)
274 { if (errors++ == 0)
275 puts ("\n") ;
276 printf (" Bad comment : %s\n", cptr) ;
277 } ;
278
279 if (typemajor != SF_FORMAT_AIFF)
280 { cptr = sf_get_string (file, SF_STR_DATE) ;
281 if (cptr == NULL || strcmp (date, cptr) != 0)
282 { if (errors++ == 0)
283 puts ("\n") ;
284 printf (" Bad date : %s\n", cptr) ;
285 } ;
286
287 cptr = sf_get_string (file, SF_STR_GENRE) ;
288 if (cptr == NULL || strcmp (genre, cptr) != 0)
289 { if (errors++ == 0)
290 puts ("\n") ;
291 printf (" Bad genre : %s\n", cptr) ;
292 } ;
293 } ;
294
295 switch (typemajor)
296 { case SF_FORMAT_AIFF :
297 case SF_FORMAT_WAV :
298 case SF_FORMAT_WAVEX :
299 case SF_ENDIAN_BIG | SF_FORMAT_WAV :
300 case SF_FORMAT_RF64 :
301 /* These formats do not support the following. */
302 break ;
303
304 default :
305 cptr = sf_get_string (file, SF_STR_ALBUM) ;
306 if (cptr == NULL || strcmp (album, cptr) != 0)
307 { if (errors++ == 0)
308 puts ("\n") ;
309 printf (" Bad album : %s\n", cptr) ;
310 } ;
311
312 cptr = sf_get_string (file, SF_STR_LICENSE) ;
313 if (cptr == NULL || strcmp (license, cptr) != 0)
314 { if (errors++ == 0)
315 puts ("\n") ;
316 printf (" Bad license : %s\n", cptr) ;
317 } ;
318
319 cptr = sf_get_string (file, SF_STR_TRACKNUMBER) ;
320 if (cptr == NULL || strcmp (trackno, cptr) != 0)
321 { if (errors++ == 0)
322 puts ("\n") ;
323 printf (" Bad track no. : %s\n", cptr) ;
324 } ;
325 break ;
326 } ;
327
328 if (errors > 0)
329 { printf ("\n*** Error count : %d ***\n\n", errors) ;
330 dump_log_buffer (file) ;
331 exit (1) ;
332 } ;
333
334 sf_close (file) ;
335 unlink (filename) ;
336
337 puts ("ok") ;
338 } /* string_start_end_test */
339
340 static void
341 string_start_test (const char *filename, int typemajor)
342 { const char *cptr ;
343 SNDFILE *file ;
344 SF_INFO sfinfo ;
345 int errors = 0 ;
346
347 print_test_name ("string_start_test", filename) ;
348
349 memset (&sfinfo, 0, sizeof (sfinfo)) ;
350 sfinfo.samplerate = 44100 ;
351 sfinfo.channels = 1 ;
352 sfinfo.frames = 0 ;
353
354 switch (typemajor)
355 { case SF_FORMAT_OGG :
356 sfinfo.format = typemajor | SF_FORMAT_VORBIS ;
357 break ;
358
359 default :
360 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
361 break ;
362 } ;
363
364 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
365
366 /* Write stuff at start of file. */
367 sf_set_string (file, SF_STR_TITLE, filename) ;
368 sf_set_string (file, SF_STR_SOFTWARE, software) ;
369 sf_set_string (file, SF_STR_ARTIST, artist) ;
370 sf_set_string (file, SF_STR_COPYRIGHT, copyright) ;
371 sf_set_string (file, SF_STR_COMMENT, comment) ;
372 sf_set_string (file, SF_STR_DATE, date) ;
373 sf_set_string (file, SF_STR_ALBUM, album) ;
374 sf_set_string (file, SF_STR_LICENSE, license) ;
375
376 /* Write data to file. */
377 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
378
379 sf_close (file) ;
380
381 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
382
383 check_log_buffer_or_die (file, __LINE__) ;
384
385 if (sfinfo.frames != BUFFER_LEN)
386 { printf ("***** Bad frame count %d (should be %d)\n\n", (int) sfinfo.frames, BUFFER_LEN) ;
387 errors ++ ;
388 } ;
389
390 cptr = sf_get_string (file, SF_STR_TITLE) ;
391 if (cptr == NULL || strcmp (filename, cptr) != 0)
392 { if (errors++ == 0)
393 puts ("\n") ;
394 printf (" Bad filename : %s\n", cptr) ;
395 } ;
396
397 cptr = sf_get_string (file, SF_STR_COPYRIGHT) ;
398 if (cptr == NULL || strcmp (copyright, cptr) != 0)
399 { if (errors++ == 0)
400 puts ("\n") ;
401 printf (" Bad copyright : %s\n", cptr) ;
402 } ;
403
404 cptr = sf_get_string (file, SF_STR_SOFTWARE) ;
405 if (cptr == NULL || strstr (cptr, software) != cptr)
406 { if (errors++ == 0)
407 puts ("\n") ;
408 printf (" Bad software : %s\n", cptr) ;
409 } ;
410
411 if (cptr && str_count (cptr, "libsndfile") != 1)
412 { if (errors++ == 0)
413 puts ("\n") ;
414 printf (" Bad software : %s\n", cptr) ;
415 } ;
416
417 cptr = sf_get_string (file, SF_STR_ARTIST) ;
418 if (cptr == NULL || strcmp (artist, cptr) != 0)
419 { if (errors++ == 0)
420 puts ("\n") ;
421 printf (" Bad artist : %s\n", cptr) ;
422 } ;
423
424 cptr = sf_get_string (file, SF_STR_COMMENT) ;
425 if (cptr == NULL || strcmp (comment, cptr) != 0)
426 { if (errors++ == 0)
427 puts ("\n") ;
428 printf (" Bad comment : %s\n", cptr) ;
429 } ;
430
431 if (typemajor != SF_FORMAT_AIFF)
432 { cptr = sf_get_string (file, SF_STR_DATE) ;
433 if (cptr == NULL || strcmp (date, cptr) != 0)
434 { if (errors++ == 0)
435 puts ("\n") ;
436 printf (" Bad date : %s\n", cptr) ;
437 } ;
438 } ;
439
440 if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF)
441 { cptr = sf_get_string (file, SF_STR_ALBUM) ;
442 if (cptr == NULL || strcmp (album, cptr) != 0)
443 { if (errors++ == 0)
444 puts ("\n") ;
445 printf (" Bad album : %s\n", cptr) ;
446 } ;
447 } ;
448
449 if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF && typemajor != SF_FORMAT_RF64)
450 { cptr = sf_get_string (file, SF_STR_LICENSE) ;
451 if (cptr == NULL || strcmp (license, cptr) != 0)
452 { if (errors++ == 0)
453 puts ("\n") ;
454 printf (" Bad license : %s\n", cptr) ;
455 } ;
456 } ;
457
458 if (errors > 0)
459 { printf ("\n*** Error count : %d ***\n\n", errors) ;
460 dump_log_buffer (file) ;
461 exit (1) ;
462 } ;
463
464 sf_close (file) ;
465 unlink (filename) ;
466
467 puts ("ok") ;
468 } /* string_start_test */
469
470 static void
471 string_multi_set_test (const char *filename, int typemajor)
472 { static const char
473 new_software [] = "new software (libsndfile-X.Y.Z)",
474 new_copyright [] = "Copyright (c) 2001 New Artist",
475 new_artist [] = "The New Artist",
476 new_title [] = "This is the new title" ;
477
478 static char buffer [2048] ;
479 SNDFILE *file ;
480 SF_INFO sfinfo ;
481 int count ;
482
483 print_test_name (__func__, filename) ;
484
485 memset (&sfinfo, 0, sizeof (sfinfo)) ;
486 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
487 sfinfo.samplerate = 44100 ;
488 sfinfo.channels = 1 ;
489 sfinfo.frames = 0 ;
490
491 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
492
493 /* Write stuff at start of file. */
494 sf_set_string (file, SF_STR_TITLE, title) ;
495 sf_set_string (file, SF_STR_SOFTWARE, software) ;
496 sf_set_string (file, SF_STR_ARTIST, artist) ;
497
498 /* Write data to file. */
499 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
500
501 /* Write it all again. */
502
503 sf_set_string (file, SF_STR_TITLE, new_title) ;
504 sf_set_string (file, SF_STR_SOFTWARE, new_software) ;
505 sf_set_string (file, SF_STR_ARTIST, new_artist) ;
506
507 sf_set_string (file, SF_STR_COPYRIGHT, copyright) ;
508 sf_set_string (file, SF_STR_COMMENT, comment) ;
509 sf_set_string (file, SF_STR_DATE, date) ;
510 sf_set_string (file, SF_STR_ALBUM, album) ;
511 sf_set_string (file, SF_STR_LICENSE, license) ;
512 sf_set_string (file, SF_STR_COPYRIGHT, new_copyright) ;
513 sf_set_string (file, SF_STR_COMMENT, comment) ;
514 sf_set_string (file, SF_STR_DATE, date) ;
515 sf_set_string (file, SF_STR_ALBUM, album) ;
516 sf_set_string (file, SF_STR_LICENSE, license) ;
517
518 sf_close (file) ;
519
520 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
521 sf_command (file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ;
522 sf_close (file) ;
523
524 count = str_count (buffer, new_title) ;
525 exit_if_true (count < 1, "\n\nLine %d : Could not find new_title in :\n%s\n", __LINE__, buffer) ;
526 exit_if_true (count > 1, "\n\nLine %d : new_title appears %d times in :\n\n%s\n", __LINE__, count, buffer) ;
527
528 count = str_count (buffer, software) ;
529 exit_if_true (count < 1, "\n\nLine %d : Could not find new_software in :\n%s\n", __LINE__, buffer) ;
530 exit_if_true (count > 1, "\n\nLine %d : new_software appears %d times in :\n\n%s\n", __LINE__, count, buffer) ;
531
532 count = str_count (buffer, new_artist) ;
533 exit_if_true (count < 1, "\n\nLine %d : Could not find new_artist in :\n%s\n", __LINE__, buffer) ;
534 exit_if_true (count > 1, "\n\nLine %d : new_artist appears %d times in :\n\n%s\n", __LINE__, count, buffer) ;
535
536 count = str_count (buffer, new_copyright) ;
537 exit_if_true (count < 1, "\n\nLine %d : Could not find new_copyright in :\n%s\n", __LINE__, buffer) ;
538 exit_if_true (count > 1, "\n\nLine %d : new_copyright appears %d times in :\n\n%s\n", __LINE__, count, buffer) ;
539
540 unlink (filename) ;
541
542 puts ("ok") ;
543 } /* string_multi_set_test */
544
545 static void
546 string_rdwr_test (const char *filename, int typemajor)
547 { SNDFILE *file ;
548 SF_INFO sfinfo ;
549 sf_count_t frames ;
550 const char * str ;
551
552 print_test_name (__func__, filename) ;
553 create_short_sndfile (filename, typemajor | SF_FORMAT_PCM_16, 2) ;
554
555 memset (&sfinfo, 0, sizeof (sfinfo)) ;
556 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
557 frames = sfinfo.frames ;
558 sf_set_string (file, SF_STR_TITLE, title) ;
559 sf_close (file) ;
560
561 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
562 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
563 str = sf_get_string (file, SF_STR_TITLE) ;
564 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
565 exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
566 sf_close (file) ;
567
568 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
569 frames = sfinfo.frames ;
570 sf_set_string (file, SF_STR_TITLE, title) ;
571 sf_close (file) ;
572
573 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
574 str = sf_get_string (file, SF_STR_TITLE) ;
575 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
576 sf_set_string (file, SF_STR_ARTIST, artist) ;
577 sf_close (file) ;
578
579 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
580
581 str = sf_get_string (file, SF_STR_ARTIST) ;
582 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_ARTIST string is NULL.\n", __LINE__) ;
583 exit_if_true (strcmp (str, artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ;
584
585 str = sf_get_string (file, SF_STR_TITLE) ;
586 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
587 exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
588
589 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
590
591 sf_close (file) ;
592 unlink (filename) ;
593
594 puts ("ok") ;
595 } /* string_rdwr_test */
596
597 static void
598 string_short_rdwr_test (const char *filename, int typemajor)
599 { SNDFILE *file ;
600 SF_INFO sfinfo ;
601 sf_count_t frames = BUFFER_LEN ;
602 const char * str ;
603
604 print_test_name (__func__, filename) ;
605
606 memset (&sfinfo, 0, sizeof (sfinfo)) ;
607 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
608 sfinfo.samplerate = 44100 ;
609 sfinfo.channels = 1 ;
610 sfinfo.frames = 0 ;
611
612 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
613
614 /* Write data to file. */
615 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
616
617 sf_set_string (file, SF_STR_TITLE, long_title) ;
618 sf_set_string (file, SF_STR_ARTIST, long_artist) ;
619 sf_close (file) ;
620
621 /* Open the file RDWR. */
622 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
623 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
624 str = sf_get_string (file, SF_STR_TITLE) ;
625 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
626 exit_if_true (strcmp (str, long_title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
627 str = sf_get_string (file, SF_STR_ARTIST) ;
628 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
629 exit_if_true (strcmp (str, long_artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ;
630
631 /* Change title and artist. */
632 sf_set_string (file, SF_STR_TITLE, title) ;
633 sf_set_string (file, SF_STR_ARTIST, artist) ;
634
635 sf_close (file) ;
636
637 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
638
639 check_log_buffer_or_die (file, __LINE__) ;
640
641 str = sf_get_string (file, SF_STR_TITLE) ;
642 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
643 exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
644
645 str = sf_get_string (file, SF_STR_ARTIST) ;
646 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_ARTIST string is NULL.\n", __LINE__) ;
647 exit_if_true (strcmp (str, artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ;
648
649 sf_close (file) ;
650 unlink (filename) ;
651
652 puts ("ok") ;
653 } /* string_short_rdwr_test */
654
655 static int
656 str_count (const char * haystack, const char * needle)
657 { int count = 0 ;
658
659 while ((haystack = strstr (haystack, needle)) != NULL)
660 { count ++ ;
661 haystack ++ ;
662 } ;
663
664 return count ;
665 } /* str_count */
666
667 #define MIN(a, b) ((a) < (b) ? (a) : (b))
668
669 static void
670 software_string_test (const char *filename)
671 { size_t k ;
672
673 print_test_name (__func__, filename) ;
674
675 for (k = 0 ; k < 50 ; k++)
676 { const char *result ;
677 char sfname [64] = "" ;
678 SNDFILE *file ;
679 SF_INFO info ;
680
681 sf_info_setup (&info, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 44100, 1) ;
682 file = test_open_file_or_die (filename, SFM_WRITE, &info, SF_TRUE, __LINE__) ;
683
684 snprintf (sfname, MIN (k, sizeof (sfname)), "%s", "abcdefghijklmnopqrestvwxyz0123456789abcdefghijklmnopqrestvwxyz") ;
685
686 exit_if_true (sf_set_string (file, SF_STR_SOFTWARE, sfname),
687 "\n\nLine %d : sf_set_string (f, SF_STR_SOFTWARE, '%s') failed : %s\n", __LINE__, sfname, sf_strerror (file)) ;
688
689 sf_close (file) ;
690
691 file = test_open_file_or_die (filename, SFM_READ, &info, SF_TRUE, __LINE__) ;
692 result = sf_get_string (file, SF_STR_SOFTWARE) ;
693
694 exit_if_true (result == NULL, "\n\nLine %d : sf_get_string (file, SF_STR_SOFTWARE) returned NULL.\n\n", __LINE__) ;
695
696 exit_if_true (strstr (result, sfname) != result,
697 "\n\nLine %d : Can't fine string '%s' in '%s'\n\n", __LINE__, sfname, result) ;
698 sf_close (file) ;
699 } ;
700
701 unlink (filename) ;
702 puts ("ok") ;
703 } /* software_string_test */
704
705
706 static void
707 string_rdwr_grow_test (const char *filename, int typemajor)
708 { SNDFILE *file ;
709 SF_INFO sfinfo ;
710 sf_count_t frames ;
711 const char * str ;
712
713 print_test_name (__func__, filename) ;
714
715 /* Create a file that contains some strings. Then open the file in RDWR mode and
716 grow the file by writing more audio data to it. Check that the audio data has
717 been added to the file, and that the strings are still there. */
718
719 /* Create a short file that contains a string. */
720 memset (&sfinfo, 0, sizeof (sfinfo)) ;
721 sfinfo.samplerate = 44100 ;
722 sfinfo.channels = 2 ;
723 sfinfo.frames = 0 ;
724 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
725
726 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
727 /* Write data to file. */
728 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
729
730 /* Write some strings at end of file. */
731 sf_set_string (file, SF_STR_TITLE , title) ;
732 sf_set_string (file, SF_STR_COMMENT, comment) ;
733 sf_close (file) ;
734
735
736 /* Now open file again in SFM_RDWR mode and write more audio data to it. */
737 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
738 /* Write more data to file. */
739 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
740 sf_close (file) ;
741
742
743 /* Now open file again. It should now contain two BUFFER_LEN's worth of frames and the strings. */
744 frames = 2 * BUFFER_LEN / sfinfo.channels ;
745 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
746 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
747
748 /* Check the strings */
749 str = sf_get_string (file, SF_STR_TITLE) ;
750 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
751 exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
752
753 str = sf_get_string (file, SF_STR_COMMENT) ;
754 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_COMMENT string is NULL.\n", __LINE__) ;
755 exit_if_true (strcmp (str, comment) != 0, "\n\nLine %d : SF_STR_COMMENT doesn't match what was written.\n", __LINE__) ;
756
757 sf_close (file) ;
758 unlink (filename) ;
759
760 puts ("ok") ;
761 } /* string_rdwr_grow_test */
762
763 static void
764 string_header_update (const char *filename, int typemajor)
765 { SNDFILE *file , *file1 ;
766 SF_INFO sfinfo , sfinfo1 ;
767 sf_count_t frames ;
768 const char * str ;
769 const int GROW_BUFFER_AMOUNT = 4 ; /* this should be less than half the size of the string header */
770
771 print_test_name (__func__, filename) ;
772
773 /* Create a short file. */
774 memset (&sfinfo, 0, sizeof (sfinfo)) ;
775 sfinfo.samplerate = 44100 ;
776 sfinfo.channels = 2 ;
777 sfinfo.frames = 0 ;
778 sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
779
780 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
781 test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
782 sf_set_string (file, SF_STR_TITLE, long_title) ;
783 sf_close (file) ;
784
785
786 /* Check that SFC_UPDATE_HEADER_NOW correctly calculates datalength. */
787 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
788 /* Write a very small amount of new audio data that doesn't completely overwrite the existing header. */
789 test_write_short_or_die (file, 0, data_out, GROW_BUFFER_AMOUNT, __LINE__) ;
790
791 /* Update the header without closing the file. */
792 sf_command (file, SFC_UPDATE_HEADER_NOW, NULL, 0) ;
793
794 /* The file should now contain BUFFER_LEN + GROW_BUFFER_AMOUNT frames.
795 Open a second handle to the file and check the reported length. */
796 memset (&sfinfo1, 0, sizeof (sfinfo1)) ;
797 file1 = test_open_file_or_die (filename, SFM_READ, &sfinfo1, SF_TRUE, __LINE__) ;
798
799 frames = (BUFFER_LEN + GROW_BUFFER_AMOUNT) / sfinfo.channels ;
800 exit_if_true (frames != sfinfo1.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo1.frames, frames) ;
801
802 /* The strings are probably not readable by the second soundfile handle because write_tailer has not yet been called.
803 It's a design decision whether SFC_UPDATE_HEADER_NOW should write the tailer. I think it's fine that it doesn't. */
804
805 sf_close (file1) ;
806 sf_close (file) ;
807
808
809 /* Check that sf_close correctly calculates datalength. */
810 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
811 /* Write a very small amount of new audio data that doesn't completely overwrite the existing header. */
812 test_write_short_or_die (file, 0, data_out, GROW_BUFFER_AMOUNT, __LINE__) ;
813 sf_close (file) ;
814
815
816 /* Open file again and verify data and string. */
817 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
818 frames = (BUFFER_LEN + 2*GROW_BUFFER_AMOUNT) / sfinfo.channels ;
819 exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ;
820 str = sf_get_string (file, SF_STR_TITLE) ;
821 exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ;
822 exit_if_true (strcmp (str, long_title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ;
823 sf_close (file) ;
824 unlink (filename) ;
825 puts ("ok") ;
826 } /* string_header_update */