command_test.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:46k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2001-2009 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 <time.h>
  23. #if HAVE_UNISTD_H
  24. #include <unistd.h>
  25. #endif
  26. #include <math.h>
  27. #include <sndfile.h>
  28. #include "utils.h"
  29. #define BUFFER_LEN (1<<10)
  30. #define LOG_BUFFER_SIZE 1024
  31. static void float_norm_test (const char *filename) ;
  32. static void double_norm_test (const char *filename) ;
  33. static void format_tests (void) ;
  34. static void calc_peak_test (int filetype, const char *filename) ;
  35. static void truncate_test (const char *filename, int filetype) ;
  36. static void instrument_test (const char *filename, int filetype) ;
  37. static void channel_map_test (const char *filename, int filetype) ;
  38. static void current_sf_info_test (const char *filename) ;
  39. static void raw_needs_endswap_test (const char *filename, int filetype) ;
  40. static void broadcast_test (const char *filename, int filetype) ;
  41. static void broadcast_rdwr_test (const char *filename, int filetype) ;
  42. static void broadcast_coding_history_test (const char *filename) ;
  43. static void broadcast_coding_history_size (const char *filename) ;
  44. /* Force the start of this buffer to be double aligned. Sparc-solaris will
  45. ** choke if its not.
  46. */
  47. static int int_data [BUFFER_LEN] ;
  48. static float float_data [BUFFER_LEN] ;
  49. static double double_data [BUFFER_LEN] ;
  50. int
  51. main (int argc, char *argv [])
  52. { int do_all = 0 ;
  53. int test_count = 0 ;
  54. if (argc != 2)
  55. { printf ("Usage : %s <test>n", argv [0]) ;
  56. printf ("    Where <test> is one of the following:n") ;
  57. printf ("           ver     - test sf_command (SFC_GETLIB_VERSION)n") ;
  58. printf ("           norm    - test floating point normalisationn") ;
  59. printf ("           format  - test format string commandsn") ;
  60. printf ("           peak    - test peak calculationn") ;
  61. printf ("           trunc   - test file truncationn") ;
  62. printf ("           inst    - test set/get of SF_INSTRUMENT.n") ;
  63. printf ("           chanmap - test set/get of channel map data..n") ;
  64. printf ("           bext    - test set/get of SF_BROADCAST_INFO.n") ;
  65. printf ("           bextch  - test set/get of SF_BROADCAST_INFO coding_history.n") ;
  66. printf ("           rawend  - test SFC_RAW_NEEDS_ENDSWAP.n") ;
  67. printf ("           all     - perform all testsn") ;
  68. exit (1) ;
  69. } ;
  70. do_all =! strcmp (argv [1], "all") ;
  71. if (do_all || strcmp (argv [1], "ver") == 0)
  72. { char buffer [128] ;
  73. print_test_name ("version_test", "(none)") ;
  74. buffer [0] = 0 ;
  75. sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
  76. if (strlen (buffer) < 1)
  77. { printf ("Line %d: could not retrieve lib version.n", __LINE__) ;
  78. exit (1) ;
  79. } ;
  80. puts ("ok") ;
  81. test_count ++ ;
  82. } ;
  83. if (do_all || strcmp (argv [1], "norm") == 0)
  84. { /* Preliminary float/double normalisation tests. More testing
  85. ** is done in the program 'floating_point_test'.
  86. */
  87. float_norm_test ("float.wav") ;
  88. double_norm_test ("double.wav") ;
  89. test_count ++ ;
  90. } ;
  91. if (do_all || strcmp (argv [1], "peak") == 0)
  92. { calc_peak_test (SF_ENDIAN_BIG | SF_FORMAT_RAW, "be-peak.raw") ;
  93. calc_peak_test (SF_ENDIAN_LITTLE | SF_FORMAT_RAW, "le-peak.raw") ;
  94. test_count ++ ;
  95. } ;
  96. if (do_all || ! strcmp (argv [1], "format"))
  97. { format_tests () ;
  98. test_count ++ ;
  99. } ;
  100. if (do_all || strcmp (argv [1], "trunc") == 0)
  101. { truncate_test ("truncate.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_32) ;
  102. truncate_test ("truncate.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16) ;
  103. test_count ++ ;
  104. } ;
  105. if (do_all || strcmp (argv [1], "inst") == 0)
  106. { instrument_test ("instrument.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
  107. instrument_test ("instrument.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ;
  108. /*-instrument_test ("instrument.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16) ;-*/
  109. test_count ++ ;
  110. } ;
  111. if (do_all || strcmp (argv [1], "current_sf_info") == 0)
  112. { current_sf_info_test ("current.wav") ;
  113. test_count ++ ;
  114. } ;
  115. if (do_all || strcmp (argv [1], "bext") == 0)
  116. { broadcast_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
  117. broadcast_rdwr_test ("broadcast.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
  118. broadcast_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
  119. broadcast_rdwr_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
  120. broadcast_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
  121. broadcast_rdwr_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
  122. test_count ++ ;
  123. } ;
  124. if (do_all || strcmp (argv [1], "bextch") == 0)
  125. { broadcast_coding_history_test ("coding_history.wav") ;
  126. broadcast_coding_history_size ("coding_hist_size.wav") ;
  127. test_count ++ ;
  128. } ;
  129. if (do_all || strcmp (argv [1], "chanmap") == 0)
  130. { channel_map_test ("chanmap.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
  131. channel_map_test ("chanmap.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
  132. channel_map_test ("chanmap.aifc" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
  133. channel_map_test ("chanmap.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16) ;
  134. test_count ++ ;
  135. } ;
  136. if (do_all || strcmp (argv [1], "rawend") == 0)
  137. { raw_needs_endswap_test ("raw_end.wav", SF_FORMAT_WAV) ;
  138. raw_needs_endswap_test ("raw_end.wavex", SF_FORMAT_WAVEX) ;
  139. raw_needs_endswap_test ("raw_end.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
  140. raw_needs_endswap_test ("raw_end.aiff", SF_FORMAT_AIFF) ;
  141. raw_needs_endswap_test ("raw_end.aiff_le", SF_ENDIAN_LITTLE | SF_FORMAT_AIFF) ;
  142. test_count ++ ;
  143. } ;
  144. if (test_count == 0)
  145. { printf ("Mono : ************************************n") ;
  146. printf ("Mono : *  No '%s' test defined.n", argv [1]) ;
  147. printf ("Mono : ************************************n") ;
  148. return 1 ;
  149. } ;
  150. return 0 ;
  151. } /* main */
  152. /*============================================================================================
  153. ** Here are the test functions.
  154. */
  155. static void
  156. float_norm_test (const char *filename)
  157. { SNDFILE *file ;
  158. SF_INFO sfinfo ;
  159. unsigned int k ;
  160. print_test_name ("float_norm_test", filename) ;
  161. sfinfo.samplerate = 44100 ;
  162. sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ;
  163. sfinfo.channels = 1 ;
  164. sfinfo.frames = BUFFER_LEN ;
  165. /* Create float_data with all values being less than 1.0. */
  166. for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
  167. float_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ;
  168. for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++)
  169. float_data [k] = (k + 5) ;
  170. if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
  171. { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ;
  172. fflush (stdout) ;
  173. puts (sf_strerror (NULL)) ;
  174. exit (1) ;
  175. } ;
  176. /* Normalisation is on by default so no need to do anything here. */
  177. if ((k = sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
  178. { printf ("Line %d: sf_write_float failed with short write (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  179. exit (1) ;
  180. } ;
  181. /* Turn normalisation off. */
  182. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  183. if ((k = sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
  184. { printf ("Line %d: sf_write_float failed with short write (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  185. exit (1) ;
  186. } ;
  187. sf_close (file) ;
  188. /* sfinfo struct should still contain correct data. */
  189. if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
  190. { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ;
  191. fflush (stdout) ;
  192. puts (sf_strerror (NULL)) ;
  193. exit (1) ;
  194. } ;
  195. if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16))
  196. { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ;
  197. exit (1) ;
  198. } ;
  199. if (sfinfo.frames != BUFFER_LEN)
  200. { printf ("nnLine %d: Incorrect number of.frames in file. (%d => %ld)n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  201. exit (1) ;
  202. } ;
  203. if (sfinfo.channels != 1)
  204. { printf ("Line %d: Incorrect number of channels in file.n", __LINE__) ;
  205. exit (1) ;
  206. } ;
  207. /* Read float_data and check that it is normalised (ie default). */
  208. if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
  209. { printf ("nnLine %d: sf_read_float failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  210. exit (1) ;
  211. } ;
  212. for (k = 0 ; k < BUFFER_LEN ; k++)
  213. if (float_data [k] >= 1.0)
  214. { printf ("nnLine %d: float_data [%d] == %f which is greater than 1.0n", __LINE__, k, float_data [k]) ;
  215. exit (1) ;
  216. } ;
  217. /* Seek to start of file, turn normalisation off, read float_data and check again. */
  218. sf_seek (file, 0, SEEK_SET) ;
  219. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  220. if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
  221. { printf ("nnLine %d: sf_read_float failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  222. exit (1) ;
  223. } ;
  224. for (k = 0 ; k < BUFFER_LEN ; k++)
  225. if (float_data [k] < 1.0)
  226. { printf ("nnLine %d: float_data [%d] == %f which is less than 1.0n", __LINE__, k, float_data [k]) ;
  227. exit (1) ;
  228. } ;
  229. /* Seek to start of file, turn normalisation on, read float_data and do final check. */
  230. sf_seek (file, 0, SEEK_SET) ;
  231. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE) ;
  232. if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
  233. { printf ("nnLine %d: sf_read_float failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  234. exit (1) ;
  235. } ;
  236. for (k = 0 ; k < BUFFER_LEN ; k++)
  237. if (float_data [k] > 1.0)
  238. { printf ("nnLine %d: float_data [%d] == %f which is greater than 1.0n", __LINE__, k, float_data [k]) ;
  239. exit (1) ;
  240. } ;
  241. sf_close (file) ;
  242. unlink (filename) ;
  243. printf ("okn") ;
  244. } /* float_norm_test */
  245. static void
  246. double_norm_test (const char *filename)
  247. { SNDFILE *file ;
  248. SF_INFO sfinfo ;
  249. unsigned int k ;
  250. print_test_name ("double_norm_test", filename) ;
  251. sfinfo.samplerate = 44100 ;
  252. sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ;
  253. sfinfo.channels = 1 ;
  254. sfinfo.frames = BUFFER_LEN ;
  255. /* Create double_data with all values being less than 1.0. */
  256. for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
  257. double_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ;
  258. for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++)
  259. double_data [k] = (k + 5) ;
  260. if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
  261. { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ;
  262. fflush (stdout) ;
  263. puts (sf_strerror (NULL)) ;
  264. exit (1) ;
  265. } ;
  266. /* Normailsation is on by default so no need to do anything here. */
  267. /*-sf_command (file, "set-norm-double", "true", 0) ;-*/
  268. if ((k = sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
  269. { printf ("Line %d: sf_write_double failed with short write (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  270. exit (1) ;
  271. } ;
  272. /* Turn normalisation off. */
  273. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  274. if ((k = sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
  275. { printf ("Line %d: sf_write_double failed with short write (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  276. exit (1) ;
  277. } ;
  278. sf_close (file) ;
  279. if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
  280. { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ;
  281. fflush (stdout) ;
  282. puts (sf_strerror (NULL)) ;
  283. exit (1) ;
  284. } ;
  285. if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16))
  286. { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ;
  287. exit (1) ;
  288. } ;
  289. if (sfinfo.frames != BUFFER_LEN)
  290. { printf ("nnLine %d: Incorrect number of.frames in file. (%d => %ld)n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  291. exit (1) ;
  292. } ;
  293. if (sfinfo.channels != 1)
  294. { printf ("Line %d: Incorrect number of channels in file.n", __LINE__) ;
  295. exit (1) ;
  296. } ;
  297. /* Read double_data and check that it is normalised (ie default). */
  298. if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
  299. { printf ("nnLine %d: sf_read_double failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  300. exit (1) ;
  301. } ;
  302. for (k = 0 ; k < BUFFER_LEN ; k++)
  303. if (double_data [k] >= 1.0)
  304. { printf ("nnLine %d: double_data [%d] == %f which is greater than 1.0n", __LINE__, k, double_data [k]) ;
  305. exit (1) ;
  306. } ;
  307. /* Seek to start of file, turn normalisation off, read double_data and check again. */
  308. sf_seek (file, 0, SEEK_SET) ;
  309. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  310. if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
  311. { printf ("nnLine %d: sf_read_double failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  312. exit (1) ;
  313. } ;
  314. for (k = 0 ; k < BUFFER_LEN ; k++)
  315. if (double_data [k] < 1.0)
  316. { printf ("nnLine %d: double_data [%d] == %f which is less than 1.0n", __LINE__, k, double_data [k]) ;
  317. exit (1) ;
  318. } ;
  319. /* Seek to start of file, turn normalisation on, read double_data and do final check. */
  320. sf_seek (file, 0, SEEK_SET) ;
  321. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ;
  322. if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
  323. { printf ("nnLine %d: sf_read_double failed with short read (%d ->%d)n", __LINE__, BUFFER_LEN, k) ;
  324. exit (1) ;
  325. } ;
  326. for (k = 0 ; k < BUFFER_LEN ; k++)
  327. if (double_data [k] > 1.0)
  328. { printf ("nnLine %d: double_data [%d] == %f which is greater than 1.0n", __LINE__, k, double_data [k]) ;
  329. exit (1) ;
  330. } ;
  331. sf_close (file) ;
  332. unlink (filename) ;
  333. printf ("okn") ;
  334. } /* double_norm_test */
  335. static void
  336. format_tests (void)
  337. { SF_FORMAT_INFO format_info ;
  338. SF_INFO sfinfo ;
  339. const char *last_name ;
  340. int  k, count ;
  341. print_test_name ("format_tests", "(null)") ;
  342. /* Clear out SF_INFO struct and set channels > 0. */
  343. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  344. sfinfo.channels = 1 ;
  345. /* First test simple formats. */
  346. sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &count, sizeof (int)) ;
  347. if (count < 0 || count > 30)
  348. { printf ("Line %d: Weird count.n", __LINE__) ;
  349. exit (1) ;
  350. } ;
  351. format_info.format = 0 ;
  352. sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
  353. last_name = format_info.name ;
  354. for (k = 1 ; k < count ; k ++)
  355. { format_info.format = k ;
  356. sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
  357. if (strcmp (last_name, format_info.name) >= 0)
  358. { printf ("nnLine %d: format names out of sequence `%s' < `%s'.n", __LINE__, last_name, format_info.name) ;
  359. exit (1) ;
  360. } ;
  361. sfinfo.format = format_info.format ;
  362. if (! sf_format_check (&sfinfo))
  363. { printf ("nnLine %d: sf_format_check failed.n", __LINE__) ;
  364. printf ("        Name : %sn", format_info.name) ;
  365. printf ("        Format      : 0x%Xn", sfinfo.format) ;
  366. printf ("        Channels    : 0x%Xn", sfinfo.channels) ;
  367. printf ("        Sample Rate : 0x%Xn", sfinfo.samplerate) ;
  368. exit (1) ;
  369. } ;
  370. last_name = format_info.name ;
  371. } ;
  372. format_info.format = 666 ;
  373. sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &format_info, sizeof (format_info)) ;
  374. /* Now test major formats. */
  375. sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ;
  376. if (count < 0 || count > 30)
  377. { printf ("Line %d: Weird count.n", __LINE__) ;
  378. exit (1) ;
  379. } ;
  380. format_info.format = 0 ;
  381. sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
  382. last_name = format_info.name ;
  383. for (k = 1 ; k < count ; k ++)
  384. { format_info.format = k ;
  385. sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
  386. if (strcmp (last_name, format_info.name) >= 0)
  387. { printf ("nnLine %d: format names out of sequence (%d) `%s' < `%s'.n", __LINE__, k, last_name, format_info.name) ;
  388. exit (1) ;
  389. } ;
  390. last_name = format_info.name ;
  391. } ;
  392. format_info.format = 666 ;
  393. sf_command (NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ;
  394. /* Now test subtype formats. */
  395. sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ;
  396. if (count < 0 || count > 30)
  397. { printf ("Line %d: Weird count.n", __LINE__) ;
  398. exit (1) ;
  399. } ;
  400. format_info.format = 0 ;
  401. sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
  402. last_name = format_info.name ;
  403. for (k = 1 ; k < count ; k ++)
  404. { format_info.format = k ;
  405. sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
  406. } ;
  407. format_info.format = 666 ;
  408. sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)) ;
  409. printf ("okn") ;
  410. } /* format_tests */
  411. static void
  412. calc_peak_test (int filetype, const char *filename)
  413. { SNDFILE *file ;
  414. SF_INFO sfinfo ;
  415. int k, format ;
  416. double peak ;
  417. print_test_name ("calc_peak_test", filename) ;
  418. format = (filetype | SF_FORMAT_PCM_16) ;
  419. sfinfo.samplerate = 44100 ;
  420. sfinfo.format = format ;
  421. sfinfo.channels = 1 ;
  422. sfinfo.frames = BUFFER_LEN ;
  423. /* Create double_data with max value of 0.5. */
  424. for (k = 0 ; k < BUFFER_LEN ; k++)
  425. double_data [k] = (k + 1) / (2.0 * BUFFER_LEN) ;
  426. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  427. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  428. sf_close (file) ;
  429. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  430. if (sfinfo.format != format)
  431. { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  432. exit (1) ;
  433. } ;
  434. if (sfinfo.frames != BUFFER_LEN)
  435. { printf ("nnLine %d: Incorrect number of.frames in file. (%d => %ld)n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  436. exit (1) ;
  437. } ;
  438. if (sfinfo.channels != 1)
  439. { printf ("Line %d: Incorrect number of channels in file.n", __LINE__) ;
  440. exit (1) ;
  441. } ;
  442. sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ;
  443. if (fabs (peak - (1 << 14)) > 1.0)
  444. { printf ("Line %d : Peak value should be %d (is %f).n", __LINE__, (1 << 14), peak) ;
  445. exit (1) ;
  446. } ;
  447. sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ;
  448. if (fabs (peak - 0.5) > 4e-5)
  449. { printf ("Line %d : Peak value should be %f (is %f).n", __LINE__, 0.5, peak) ;
  450. exit (1) ;
  451. } ;
  452. sf_close (file) ;
  453. format = (filetype | SF_FORMAT_FLOAT) ;
  454. sfinfo.samplerate = 44100 ;
  455. sfinfo.format = format ;
  456. sfinfo.channels = 1 ;
  457. sfinfo.frames = BUFFER_LEN ;
  458. /* Create double_data with max value of 0.5. */
  459. for (k = 0 ; k < BUFFER_LEN ; k++)
  460. double_data [k] = (k + 1) / (2.0 * BUFFER_LEN) ;
  461. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  462. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  463. sf_close (file) ;
  464. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  465. if (sfinfo.format != format)
  466. { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  467. exit (1) ;
  468. } ;
  469. if (sfinfo.frames != BUFFER_LEN)
  470. { printf ("nnLine %d: Incorrect number of.frames in file. (%d => %ld)n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  471. exit (1) ;
  472. } ;
  473. if (sfinfo.channels != 1)
  474. { printf ("Line %d: Incorrect number of channels in file.n", __LINE__) ;
  475. exit (1) ;
  476. } ;
  477. sf_command (file, SFC_CALC_SIGNAL_MAX, &peak, sizeof (peak)) ;
  478. if (fabs (peak - 0.5) > 1e-5)
  479. { printf ("Line %d : Peak value should be %f (is %f).n", __LINE__, 0.5, peak) ;
  480. exit (1) ;
  481. } ;
  482. sf_command (file, SFC_CALC_NORM_SIGNAL_MAX, &peak, sizeof (peak)) ;
  483. if (fabs (peak - 0.5) > 1e-5)
  484. { printf ("Line %d : Peak value should be %f (is %f).n", __LINE__, 0.5, peak) ;
  485. exit (1) ;
  486. } ;
  487. sf_close (file) ;
  488. unlink (filename) ;
  489. printf ("okn") ;
  490. } /* calc_peak_test */
  491. static void
  492. truncate_test (const char *filename, int filetype)
  493. { SNDFILE  *file ;
  494. SF_INFO sfinfo ;
  495. sf_count_t len ;
  496. print_test_name ("truncate_test", filename) ;
  497. sfinfo.samplerate = 11025 ;
  498. sfinfo.format = filetype ;
  499. sfinfo.channels = 2 ;
  500. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
  501. test_write_int_or_die (file, 0, int_data, BUFFER_LEN, __LINE__) ;
  502. len = 100 ;
  503. if (sf_command (file, SFC_FILE_TRUNCATE, &len, sizeof (len)))
  504. { printf ("Line %d: sf_command (SFC_FILE_TRUNCATE) returned error.n", __LINE__) ;
  505. exit (1) ;
  506. } ;
  507. test_seek_or_die (file, 0, SEEK_CUR, len, 2, __LINE__) ;
  508. test_seek_or_die (file, 0, SEEK_END, len, 2, __LINE__) ;
  509. sf_close (file) ;
  510. unlink (filename) ;
  511. puts ("ok") ;
  512. } /* truncate_test */
  513. /*------------------------------------------------------------------------------
  514. */
  515. static void
  516. instrumet_rw_test (const char *filename)
  517. { SNDFILE *sndfile ;
  518. SF_INFO sfinfo ;
  519. SF_INSTRUMENT inst ;
  520. memset (&sfinfo, 0, sizeof (SF_INFO)) ;
  521. sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ;
  522. if (sf_command (sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
  523. { inst.basenote = 22 ;
  524. if (sf_command (sndfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
  525. printf ("Sucess: [%s] updatedn", filename) ;
  526. else
  527. printf ("Error: SFC_SET_INSTRUMENT on [%s] [%s]n", filename, sf_strerror (sndfile)) ;
  528. }
  529. else
  530. printf ("Error: SFC_GET_INSTRUMENT on [%s] [%s]n", filename, sf_strerror (sndfile)) ;
  531. if (sf_command (sndfile, SFC_UPDATE_HEADER_NOW, NULL, 0) != 0)
  532. printf ("Error: SFC_UPDATE_HEADER_NOW on [%s] [%s]n", filename, sf_strerror (sndfile)) ;
  533. sf_write_sync (sndfile) ;
  534. sf_close (sndfile) ;
  535. return ;
  536. } /* instrumet_rw_test */
  537. static void
  538. instrument_test (const char *filename, int filetype)
  539. { static SF_INSTRUMENT write_inst =
  540. { 2, /* gain */
  541. 3,  /* detune */
  542. 4,  /* basenote */
  543. 5, 6, /* key low and high */
  544. 7, 8, /* velocity low and high */
  545. 2, /* loop_count */
  546. { { 801, 2, 3, 0 },
  547. { 801, 3, 4, 0 },
  548. }
  549. } ;
  550. SF_INSTRUMENT read_inst ;
  551. SNDFILE  *file ;
  552. SF_INFO  sfinfo ;
  553. print_test_name ("instrument_test", filename) ;
  554. sfinfo.samplerate = 11025 ;
  555. sfinfo.format = filetype ;
  556. sfinfo.channels = 1 ;
  557. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  558. if (sf_command (file, SFC_SET_INSTRUMENT, &write_inst, sizeof (write_inst)) == SF_FALSE)
  559. { printf ("nnLine %d : sf_command (SFC_SET_INSTRUMENT) failed.nn", __LINE__) ;
  560. exit (1) ;
  561. } ;
  562. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  563. sf_close (file) ;
  564. memset (&read_inst, 0, sizeof (read_inst)) ;
  565. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  566. if (sf_command (file, SFC_GET_INSTRUMENT, &read_inst, sizeof (read_inst)) == SF_FALSE)
  567. { printf ("nnLine %d : sf_command (SFC_GET_INSTRUMENT) failed.nn", __LINE__) ;
  568. exit (1) ;
  569. return ;
  570. } ;
  571. check_log_buffer_or_die (file, __LINE__) ;
  572. sf_close (file) ;
  573. if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
  574. { /*
  575. ** For all the fields that WAV doesn't support, modify the
  576. ** write_inst struct to hold the default value that the WAV
  577. ** module should hold.
  578. */
  579. write_inst.detune = 0 ;
  580. write_inst.key_lo = write_inst.velocity_lo = 0 ;
  581. write_inst.key_hi = write_inst.velocity_hi = 127 ;
  582. write_inst.gain = 1 ;
  583. } ;
  584. if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI)
  585. { /*
  586. ** For all the fields that XI doesn't support, modify the
  587. ** write_inst struct to hold the default value that the XI
  588. ** module should hold.
  589. */
  590. write_inst.basenote = 0 ;
  591. write_inst.detune = 0 ;
  592. write_inst.key_lo = write_inst.velocity_lo = 0 ;
  593. write_inst.key_hi = write_inst.velocity_hi = 127 ;
  594. write_inst.gain = 1 ;
  595. } ;
  596. if (memcmp (&write_inst, &read_inst, sizeof (write_inst)) != 0)
  597. { printf ("nnLine %d : instrument comparison failed.nn", __LINE__) ;
  598. printf ("W  Base Note : %un"
  599. "   Detune    : %un"
  600. "   Low  Note : %utHigh Note : %un"
  601. "   Low  Vel. : %utHigh Vel. : %un"
  602. "   Gain      : %dtCount     : %dn"
  603. "   mode      : %dn"
  604. "   start     : %dtend       : %dtcount  :%dn"
  605. "   mode      : %dn"
  606. "   start     : %dtend       : %dtcount  :%dnn",
  607. write_inst.basenote,
  608. write_inst.detune,
  609. write_inst.key_lo, write_inst.key_hi,
  610. write_inst.velocity_lo, write_inst.velocity_hi,
  611. write_inst.gain, write_inst.loop_count,
  612. write_inst.loops [0].mode, write_inst.loops [0].start,
  613. write_inst.loops [0].end, write_inst.loops [0].count,
  614. write_inst.loops [1].mode, write_inst.loops [1].start,
  615. write_inst.loops [1].end, write_inst.loops [1].count) ;
  616. printf ("R  Base Note : %un"
  617. "   Detune    : %un"
  618. "   Low  Note : %utHigh Note : %un"
  619. "   Low  Vel. : %utHigh Vel. : %un"
  620. "   Gain      : %dtCount     : %dn"
  621. "   mode      : %dn"
  622. "   start     : %dtend       : %dtcount  :%dn"
  623. "   mode      : %dn"
  624. "   start     : %dtend       : %dtcount  :%dnn",
  625. read_inst.basenote,
  626. read_inst.detune,
  627. read_inst.key_lo, read_inst.key_hi,
  628. read_inst.velocity_lo, read_inst.velocity_hi,
  629. read_inst.gain, read_inst.loop_count,
  630. read_inst.loops [0].mode, read_inst.loops [0].start,
  631. read_inst.loops [0].end, read_inst.loops [0].count,
  632. read_inst.loops [1].mode, read_inst.loops [1].start,
  633. read_inst.loops [1].end, read_inst.loops [1].count) ;
  634. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI)
  635. exit (1) ;
  636. } ;
  637. if (0) instrumet_rw_test (filename) ;
  638. unlink (filename) ;
  639. puts ("ok") ;
  640. } /* instrument_test */
  641. static void
  642. current_sf_info_test (const char *filename)
  643. { SNDFILE *outfile, *infile ;
  644. SF_INFO outinfo, ininfo ;
  645. sf_count_t last_count ;
  646. print_test_name ("current_sf_info_test", filename) ;
  647. outinfo.samplerate = 44100 ;
  648. outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
  649. outinfo.channels = 1 ;
  650. outinfo.frames = 0 ;
  651. outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ;
  652. sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ;
  653. exit_if_true (outinfo.frames != 0,
  654. "nnLine %d : Initial sfinfo.frames is not zero.nn", __LINE__
  655. ) ;
  656. test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
  657. sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ;
  658. exit_if_true (outinfo.frames != BUFFER_LEN,
  659. "nnLine %d : Initial sfinfo.frames (%ld) should be %d.nn", __LINE__,
  660. SF_COUNT_TO_LONG (outinfo.frames), BUFFER_LEN
  661. ) ;
  662. /* Read file making sure no channel map exists. */
  663. memset (&ininfo, 0, sizeof (ininfo)) ;
  664. infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ;
  665. last_count = ininfo.frames ;
  666. test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
  667. sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ;
  668. exit_if_true (ininfo.frames != BUFFER_LEN,
  669. "nnLine %d : Initial sfinfo.frames (%ld) should be %d.nn", __LINE__,
  670. SF_COUNT_TO_LONG (ininfo.frames), BUFFER_LEN
  671. ) ;
  672. sf_close (outfile) ;
  673. sf_close (infile) ;
  674. unlink (filename) ;
  675. puts ("ok") ;
  676. } /* current_sf_info_test */
  677. static void
  678. broadcast_test (const char *filename, int filetype)
  679. { static SF_BROADCAST_INFO bc_write, bc_read ;
  680. SNDFILE  *file ;
  681. SF_INFO  sfinfo ;
  682. int errors = 0 ;
  683. print_test_name ("broadcast_test", filename) ;
  684. sfinfo.samplerate = 11025 ;
  685. sfinfo.format = filetype ;
  686. sfinfo.channels = 1 ;
  687. memset (&bc_write, 0, sizeof (bc_write)) ;
  688. snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
  689. snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
  690. snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
  691. snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
  692. snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
  693. snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
  694. bc_write.coding_history_size = 0 ;
  695. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  696. if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
  697. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  698. exit (1) ;
  699. } ;
  700. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  701. sf_close (file) ;
  702. memset (&bc_read, 0, sizeof (bc_read)) ;
  703. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  704. if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
  705. { printf ("nnLine %d : sf_command (SFC_GET_BROADCAST_INFO) failed.nn", __LINE__) ;
  706. exit (1) ;
  707. return ;
  708. } ;
  709. check_log_buffer_or_die (file, __LINE__) ;
  710. sf_close (file) ;
  711. if (bc_read.version != 1)
  712. { printf ("nnLine %d : Read bad version number %d.nn", __LINE__, bc_read.version) ;
  713. exit (1) ;
  714. return ;
  715. } ;
  716. bc_read.version = bc_write.version = 0 ;
  717. if (memcmp (bc_write.description, bc_read.description, sizeof (bc_write.description)) != 0)
  718. { printf ("nnLine %d : description mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.description, bc_read.description) ;
  719. errors ++ ;
  720. } ;
  721. if (memcmp (bc_write.originator, bc_read.originator, sizeof (bc_write.originator)) != 0)
  722. { printf ("nnLine %d : originator mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.originator, bc_read.originator) ;
  723. errors ++ ;
  724. } ;
  725. if (memcmp (bc_write.originator_reference, bc_read.originator_reference, sizeof (bc_write.originator_reference)) != 0)
  726. { printf ("nnLine %d : originator_reference mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.originator_reference, bc_read.originator_reference) ;
  727. errors ++ ;
  728. } ;
  729. if (memcmp (bc_write.origination_date, bc_read.origination_date, sizeof (bc_write.origination_date)) != 0)
  730. { printf ("nnLine %d : origination_date mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.origination_date, bc_read.origination_date) ;
  731. errors ++ ;
  732. } ;
  733. if (memcmp (bc_write.origination_time, bc_read.origination_time, sizeof (bc_write.origination_time)) != 0)
  734. { printf ("nnLine %d : origination_time mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.origination_time, bc_read.origination_time) ;
  735. errors ++ ;
  736. } ;
  737. if (memcmp (bc_write.umid, bc_read.umid, sizeof (bc_write.umid)) != 0)
  738. { printf ("nnLine %d : umid mismatch :ntwrite : '%s'ntread  : '%s'nn", __LINE__, bc_write.umid, bc_read.umid) ;
  739. errors ++ ;
  740. } ;
  741. if (errors)
  742. exit (1) ;
  743. unlink (filename) ;
  744. puts ("ok") ;
  745. } /* broadcast_test */
  746. static void
  747. broadcast_rdwr_test (const char *filename, int filetype)
  748. { SF_BROADCAST_INFO binfo ;
  749. SNDFILE *file ;
  750. SF_INFO sfinfo ;
  751. sf_count_t frames ;
  752. print_test_name (__func__, filename) ;
  753. create_short_sndfile (filename, filetype, 2) ;
  754. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  755. memset (&binfo, 0, sizeof (binfo)) ;
  756. snprintf (binfo.description, sizeof (binfo.description), "Test description") ;
  757. snprintf (binfo.originator, sizeof (binfo.originator), "Test originator") ;
  758. snprintf (binfo.originator_reference, sizeof (binfo.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
  759. snprintf (binfo.origination_date, sizeof (binfo.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
  760. snprintf (binfo.origination_time, sizeof (binfo.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
  761. snprintf (binfo.umid, sizeof (binfo.umid), "Some umid") ;
  762. binfo.coding_history_size = 0 ;
  763. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
  764. frames = sfinfo.frames ;
  765. if (sf_command (file, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) != SF_FALSE)
  766. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) should have failed but didn't.nn", __LINE__) ;
  767. exit (1) ;
  768. } ;
  769. sf_close (file) ;
  770. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  771. sf_close (file) ;
  772. exit_if_true (frames != sfinfo.frames, "nnLine %d : Frame count %lld should be %lld.n", __LINE__, sfinfo.frames, frames) ;
  773. unlink (filename) ;
  774. puts ("ok") ;
  775. } /* broadcast_rdwr_test */
  776. static void
  777. check_coding_history_newlines (const char *filename)
  778. { static SF_BROADCAST_INFO bc_write, bc_read ;
  779. SNDFILE  *file ;
  780. SF_INFO  sfinfo ;
  781. unsigned k ;
  782. sfinfo.samplerate = 22050 ;
  783. sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
  784. sfinfo.channels = 1 ;
  785. memset (&bc_write, 0, sizeof (bc_write)) ;
  786. snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
  787. snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
  788. snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
  789. snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
  790. snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
  791. snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
  792. bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "This hasnUnixnandrMac OS9rline endings.nLast line") ; ;
  793. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  794. if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
  795. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  796. exit (1) ;
  797. } ;
  798. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  799. sf_close (file) ;
  800. memset (&bc_read, 0, sizeof (bc_read)) ;
  801. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  802. if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
  803. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  804. exit (1) ;
  805. } ;
  806. check_log_buffer_or_die (file, __LINE__) ;
  807. sf_close (file) ;
  808. if (bc_read.coding_history_size == 0)
  809. { printf ("nnLine %d : missing coding history.nn", __LINE__) ;
  810. exit (1) ;
  811. } ;
  812. if (strstr (bc_read.coding_history, "Last line") == NULL)
  813. { printf ("nnLine %d : coding history truncated.nn", __LINE__) ;
  814. exit (1) ;
  815. } ;
  816. for (k = 1 ; k < bc_read.coding_history_size ; k++)
  817. { if (bc_read.coding_history [k] == 'n' && bc_read.coding_history [k - 1] != 'r')
  818. { printf ("nnLine %d : '\n' without '\r' before.nn", __LINE__) ;
  819. exit (1) ;
  820. } ;
  821. if (bc_read.coding_history [k] == 'r' && bc_read.coding_history [k + 1] != 'n')
  822. { printf ("nnLine %d : '\r' without '\n' after.nn", __LINE__) ;
  823. exit (1) ;
  824. } ;
  825. if (bc_read.coding_history [k] == 0 && k < bc_read.coding_history_size - 1)
  826. { printf ("nnLine %d : '\0' within coding history at index %d of %d.nn", __LINE__, k, bc_read.coding_history_size) ;
  827. exit (1) ;
  828. } ;
  829. } ;
  830. return ;
  831. } /* check_coding_history_newlines */
  832. static void
  833. broadcast_coding_history_test (const char *filename)
  834. { static SF_BROADCAST_INFO bc_write, bc_read ;
  835. SNDFILE  *file ;
  836. SF_INFO  sfinfo ;
  837. const char *default_history = "A=PCM,F=22050,W=16,M=mono" ;
  838. const char *supplied_history =
  839. "A=PCM,F=44100,W=24,M=mono,T=otherrn"
  840. "A=PCM,F=22050,W=16,M=mono,T=yet_anotherrn" ;
  841. print_test_name ("broadcast_coding_history_test", filename) ;
  842. sfinfo.samplerate = 22050 ;
  843. sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
  844. sfinfo.channels = 1 ;
  845. memset (&bc_write, 0, sizeof (bc_write)) ;
  846. snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
  847. snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
  848. snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
  849. snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
  850. snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
  851. snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
  852. /* Coding history will be filled in by the library. */
  853. bc_write.coding_history_size = 0 ;
  854. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  855. if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
  856. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  857. exit (1) ;
  858. } ;
  859. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  860. sf_close (file) ;
  861. memset (&bc_read, 0, sizeof (bc_read)) ;
  862. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  863. if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
  864. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  865. exit (1) ;
  866. } ;
  867. check_log_buffer_or_die (file, __LINE__) ;
  868. sf_close (file) ;
  869. if (bc_read.coding_history_size == 0)
  870. { printf ("nnLine %d : missing coding history.nn", __LINE__) ;
  871. exit (1) ;
  872. } ;
  873. if (bc_read.coding_history_size < strlen (default_history) || memcmp (bc_read.coding_history, default_history, strlen (default_history)) != 0)
  874. { printf ("nnLine %d : unexpected coding history '%.*s'.nn", __LINE__, bc_read.coding_history_size, bc_read.coding_history) ;
  875. exit (1) ;
  876. } ;
  877. bc_write.coding_history_size = strlen (supplied_history) ;
  878. bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "%s", supplied_history) ;
  879. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  880. if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
  881. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  882. exit (1) ;
  883. } ;
  884. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  885. sf_close (file) ;
  886. memset (&bc_read, 0, sizeof (bc_read)) ;
  887. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  888. if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
  889. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  890. exit (1) ;
  891. } ;
  892. check_log_buffer_or_die (file, __LINE__) ;
  893. sf_close (file) ;
  894. if (strstr (bc_read.coding_history, supplied_history) != bc_read.coding_history)
  895. { printf ("nnLine %d : unexpected coding history :n"
  896. "----------------------------------------------------n%s"
  897. "----------------------------------------------------n"
  898. "should be this :n"
  899. "----------------------------------------------------n%s"
  900. "----------------------------------------------------n"
  901. "with one more line at the end.nn",
  902. __LINE__, bc_read.coding_history, supplied_history) ;
  903. exit (1) ;
  904. } ;
  905. check_coding_history_newlines (filename) ;
  906. unlink (filename) ;
  907. puts ("ok") ;
  908. } /* broadcast_coding_history_test */
  909. /*==============================================================================
  910. */
  911. static void
  912. broadcast_coding_history_size (const char *filename)
  913. { /* SF_BROADCAST_INFO struct with coding_history field of 1024 bytes. */
  914. static SF_BROADCAST_INFO_VAR (1024) bc_write ;
  915. static SF_BROADCAST_INFO_VAR (1024) bc_read ;
  916. SNDFILE  *file ;
  917. SF_INFO  sfinfo ;
  918. int k ;
  919. print_test_name (__func__, filename) ;
  920. sfinfo.samplerate = 22050 ;
  921. sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
  922. sfinfo.channels = 1 ;
  923. memset (&bc_write, 0, sizeof (bc_write)) ;
  924. snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ;
  925. snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ;
  926. snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ;
  927. snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ;
  928. snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ;
  929. snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ;
  930. bc_write.coding_history_size = 0 ;
  931. for (k = 0 ; bc_write.coding_history_size < 512 ; k++)
  932. { snprintf (bc_write.coding_history + bc_write.coding_history_size,
  933. sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4dn", k) ;
  934. bc_write.coding_history_size = strlen (bc_write.coding_history) ;
  935. } ;
  936. exit_if_true (bc_write.coding_history_size < 512,
  937. "nnLine %d : bc_write.coding_history_size (%d) should be > 512.nn", __LINE__, bc_write.coding_history_size) ;
  938. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  939. if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE)
  940. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  941. exit (1) ;
  942. } ;
  943. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  944. sf_close (file) ;
  945. memset (&bc_read, 0, sizeof (bc_read)) ;
  946. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  947. if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE)
  948. { printf ("nnLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.nn", __LINE__) ;
  949. exit (1) ;
  950. } ;
  951. check_log_buffer_or_die (file, __LINE__) ;
  952. sf_close (file) ;
  953. exit_if_true (bc_read.coding_history_size < 512,
  954. "nnLine %d : unexpected coding history size %d (should be > 512).nn", __LINE__, bc_read.coding_history_size) ;
  955. exit_if_true (strstr (bc_read.coding_history, "libsndfile") == NULL,
  956. "nnLine %d : coding history incomplete (should contain 'libsndfile').nn", __LINE__) ;
  957. unlink (filename) ;
  958. puts ("ok") ;
  959. } /* broadcast_coding_history_size */
  960. /*==============================================================================
  961. */
  962. static void
  963. channel_map_test (const char *filename, int filetype)
  964. { SNDFILE  *file ;
  965. SF_INFO  sfinfo ;
  966. int channel_map_read [4], channel_map_write [4] =
  967. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE,
  968. SF_CHANNEL_MAP_REAR_CENTER
  969. } ;
  970. print_test_name ("channel_map_test", filename) ;
  971. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  972. sfinfo.samplerate = 11025 ;
  973. sfinfo.format = filetype ;
  974. sfinfo.channels = ARRAY_LEN (channel_map_read) ;
  975. switch (filetype & SF_FORMAT_TYPEMASK)
  976. { /* WAVEX and RF64 have a default channel map, even if you don't specify one. */
  977. case SF_FORMAT_WAVEX :
  978. case SF_FORMAT_RF64 :
  979. /* Write file without channel map. */
  980. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  981. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  982. sf_close (file) ;
  983. /* Read file making default channel map exists. */
  984. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  985. exit_if_true (
  986. sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) == SF_FALSE,
  987. "nnLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should not have failed.nn", __LINE__
  988. ) ;
  989. check_log_buffer_or_die (file, __LINE__) ;
  990. sf_close (file) ;
  991. break ;
  992. default :
  993. break ;
  994. } ;
  995. /* Write file with a channel map. */
  996. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  997. exit_if_true (
  998. sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE,
  999. "nnLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.nn", __LINE__
  1000. ) ;
  1001. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  1002. sf_close (file) ;
  1003. /* Read file making sure no channel map exists. */
  1004. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  1005. exit_if_true (
  1006. sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_TRUE,
  1007. "nnLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) failed.nn", __LINE__
  1008. ) ;
  1009. check_log_buffer_or_die (file, __LINE__) ;
  1010. sf_close (file) ;
  1011. exit_if_true (
  1012. memcmp (channel_map_read, channel_map_write, sizeof (channel_map_read)) != 0,
  1013. "nnLine %d : Channel map read does not match channel map written.nn", __LINE__
  1014. ) ;
  1015. unlink (filename) ;
  1016. puts ("ok") ;
  1017. } /* channel_map_test */
  1018. static void
  1019. raw_needs_endswap_test (const char *filename, int filetype)
  1020. { static int subtypes [] =
  1021. { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE,
  1022. SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
  1023. } ;
  1024. SNDFILE  *file ;
  1025. SF_INFO  sfinfo ;
  1026. unsigned k ;
  1027. int needs_endswap ;
  1028. print_test_name (__func__, filename) ;
  1029. for (k = 0 ; k < ARRAY_LEN (subtypes) ; k++)
  1030. {
  1031. if (filetype == (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF))
  1032. switch (subtypes [k])
  1033. { /* Little endian AIFF does not AFAIK support fl32 and fl64. */
  1034. case SF_FORMAT_FLOAT :
  1035. case SF_FORMAT_DOUBLE :
  1036. continue ;
  1037. default :
  1038. break ;
  1039. } ;
  1040. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1041. sfinfo.samplerate = 11025 ;
  1042. sfinfo.format = filetype | subtypes [k] ;
  1043. sfinfo.channels = 1 ;
  1044. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  1045. test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
  1046. sf_close (file) ;
  1047. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1048. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  1049. needs_endswap = sf_command (file, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0) ;
  1050. switch (filetype)
  1051. { case SF_FORMAT_WAV :
  1052. case SF_FORMAT_WAVEX :
  1053. case SF_FORMAT_AIFF | SF_ENDIAN_LITTLE :
  1054. exit_if_true (needs_endswap != CPU_IS_BIG_ENDIAN,
  1055. "nnLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).nn", __LINE__, filetype, k) ;
  1056. break ;
  1057. case SF_FORMAT_AIFF :
  1058. case SF_FORMAT_WAV | SF_ENDIAN_BIG :
  1059. exit_if_true (needs_endswap != CPU_IS_LITTLE_ENDIAN,
  1060. "nnLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).nn", __LINE__, filetype, k) ;
  1061. break ;
  1062. default :
  1063. printf ("nnLine %d : bad format value %d.nn", __LINE__, filetype) ;
  1064. exit (1) ;
  1065. break ;
  1066. } ;
  1067. sf_close (file) ;
  1068. } ;
  1069. unlink (filename) ;
  1070. puts ("ok") ;
  1071. } /* raw_needs_endswap_test */