command_test.c 63 KB

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