string_test.c 26 KB

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