lossy_comp_test.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:48k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2. ** Copyright (C) 1999-2000 Erik de Castro Lopo <erikd@zip.com.au>
  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 <stdio.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <math.h>
  22. #include <sndfile.h>
  23. #ifndef M_PI
  24. #define M_PI 3.14159
  25. #endif
  26. #define BUFFER_SIZE (1<<14)
  27. #define SAMPLE_RATE 11025
  28. static void lcomp_test_short (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  29. static void lcomp_test_int (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  30. static void lcomp_test_double (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  31. static void sdlcomp_test_short (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  32. static void sdlcomp_test_int (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  33. static void sdlcomp_test_double (char *str, char *filename, int typemajor, int typeminor, double margin) ;
  34. static int error_function (double data, double orig, double margin) ;
  35. static int decay_response (int k) ;
  36. static void gen_signal (double *data, unsigned int datalen) ;
  37. static void smoothed_diff_short (short *data, unsigned int datalen) ;
  38. static void smoothed_diff_int (int *data, unsigned int datalen) ;
  39. static void smoothed_diff_double (double *data, unsigned int datalen) ;
  40. /* Force the start of these buffers to be double aligned. Sparc-solaris will
  41. ** choke if they are not.
  42. */
  43. static double data_buffer [BUFFER_SIZE + 1] ;
  44. static double orig_buffer [BUFFER_SIZE + 1] ;
  45. static double smooth_buffer [BUFFER_SIZE + 1] ;
  46. int main (int argc, char *argv[])
  47. { char *filename ;
  48. int bDoAll = 0 ;
  49. int nTests = 0 ;
  50. if (argc != 2)
  51. { printf ("Usage : %s <test>n", argv [0]) ;
  52. printf ("    Where <test> is one of the following:n") ;
  53. printf ("           wav_ima     - test IMA ADPCM WAV file functionsn") ;
  54. printf ("           wav_msadpcm - test MS ADPCM WAV file functionsn") ;
  55. printf ("           wav_gsm610  - test GSM 6.10 WAV file functionsn") ;
  56. printf ("           wav_ulaw    - test u-law WAV file functionsn") ;
  57. printf ("           wav_alaw    - test A-law WAV file functionsn") ;
  58. printf ("           wav_pcm     - test PCM WAV file functionsn") ;
  59. printf ("           all         - perform all testsn") ;
  60. exit (1) ;
  61. } ;
  62. bDoAll = !strcmp (argv [1], "all") ;
  63. if (bDoAll || ! strcmp (argv [1], "wav_pcm"))
  64. { filename = "test.wav" ;
  65. lcomp_test_short ("wav_pcm", filename, SF_FORMAT_WAV, SF_FORMAT_PCM, 0.00001) ;
  66. lcomp_test_int ("wav_pcm", filename, SF_FORMAT_WAV, SF_FORMAT_PCM, 0.00001) ;
  67. lcomp_test_double ("wav_pcm", filename, SF_FORMAT_WAV, SF_FORMAT_PCM, 0.005) ;
  68. unlink (filename) ;
  69. nTests++ ;
  70. } ;
  71. if (bDoAll || ! strcmp (argv [1], "wav_ima"))
  72. { filename = "test.wav" ;
  73. lcomp_test_short ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  74. lcomp_test_int ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  75. lcomp_test_double ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  76. sdlcomp_test_short ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  77. sdlcomp_test_int ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  78. sdlcomp_test_double ("wav_ima", filename, SF_FORMAT_WAV, SF_FORMAT_IMA_ADPCM, 0.17) ;
  79. unlink (filename) ;
  80. nTests++ ;
  81. } ;
  82. if (bDoAll || ! strcmp (argv [1], "wav_msadpcm"))
  83. { filename = "test.wav" ;
  84. lcomp_test_short ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  85. lcomp_test_int ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  86. lcomp_test_double ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  87. sdlcomp_test_short ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  88. sdlcomp_test_int ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  89. sdlcomp_test_double ("wav_msadpcm", filename, SF_FORMAT_WAV, SF_FORMAT_MS_ADPCM, 0.36) ;
  90. unlink (filename) ;
  91. nTests++ ;
  92. } ;
  93. if (bDoAll || ! strcmp (argv [1], "wav_ulaw"))
  94. { filename = "test.wav" ;
  95. lcomp_test_short ("wav_ulaw", filename, SF_FORMAT_WAV, SF_FORMAT_ULAW, 0.04) ;
  96. lcomp_test_int ("wav_ulaw", filename, SF_FORMAT_WAV, SF_FORMAT_ULAW, 0.04) ;
  97. lcomp_test_double ("wav_ulaw", filename, SF_FORMAT_WAV, SF_FORMAT_ULAW, 0.04) ;
  98. unlink (filename) ;
  99. nTests++ ;
  100. } ;
  101. if (bDoAll || ! strcmp (argv [1], "wav_alaw"))
  102. { filename = "test.wav" ;
  103. lcomp_test_short ("wav_alaw", filename, SF_FORMAT_WAV, SF_FORMAT_ALAW, 0.04) ;
  104. lcomp_test_int ("wav_alaw", filename, SF_FORMAT_WAV, SF_FORMAT_ALAW, 0.04) ;
  105. lcomp_test_double ("wav_alaw", filename, SF_FORMAT_WAV, SF_FORMAT_ALAW, 0.04) ;
  106. unlink (filename) ;
  107. nTests++ ;
  108. } ;
  109. if (bDoAll || ! strcmp (argv [1], "wav_gsm610"))
  110. { filename = "test.wav" ;
  111. sdlcomp_test_short ("wav_gsm610", filename, SF_FORMAT_WAV, SF_FORMAT_GSM610, 0.2) ;
  112. sdlcomp_test_int ("wav_gsm610", filename, SF_FORMAT_WAV, SF_FORMAT_GSM610, 0.2) ;
  113. sdlcomp_test_double ("wav_gsm610", filename, SF_FORMAT_WAV, SF_FORMAT_GSM610, 0.2) ;
  114. unlink (filename) ;
  115. nTests++ ;
  116. } ;
  117. if (bDoAll || ! strcmp (argv [1], "au_ulaw"))
  118. { filename = "test.au" ;
  119. lcomp_test_short ("au_ulaw", filename, SF_FORMAT_AU, SF_FORMAT_ULAW, 0.04) ;
  120. lcomp_test_int ("au_ulaw", filename, SF_FORMAT_AU, SF_FORMAT_ULAW, 0.04) ;
  121. lcomp_test_double ("au_ulaw", filename, SF_FORMAT_AU, SF_FORMAT_ULAW, 0.04) ;
  122. unlink (filename) ;
  123. nTests++ ;
  124. } ;
  125. if (bDoAll || ! strcmp (argv [1], "au_alaw"))
  126. { filename = "test.au" ;
  127. lcomp_test_short ("au_alaw", filename, SF_FORMAT_AU, SF_FORMAT_ALAW, 0.04) ;
  128. lcomp_test_int ("au_alaw", filename, SF_FORMAT_AU, SF_FORMAT_ALAW, 0.04) ;
  129. lcomp_test_double ("au_alaw", filename, SF_FORMAT_AU, SF_FORMAT_ALAW, 0.04) ;
  130. unlink (filename) ;
  131. nTests++ ;
  132. } ;
  133. if (bDoAll || ! strcmp (argv [1], "aule_ulaw"))
  134. { filename = "test.au" ;
  135. lcomp_test_short ("aule_ulaw", filename, SF_FORMAT_AULE, SF_FORMAT_ULAW, 0.04) ;
  136. lcomp_test_int ("aule_ulaw", filename, SF_FORMAT_AULE, SF_FORMAT_ULAW, 0.04) ;
  137. lcomp_test_double ("aule_ulaw", filename, SF_FORMAT_AULE, SF_FORMAT_ULAW, 0.04) ;
  138. unlink (filename) ;
  139. nTests++ ;
  140. } ;
  141. if (bDoAll || ! strcmp (argv [1], "aule_alaw"))
  142. { filename = "test.au" ;
  143. lcomp_test_short ("aule_alaw", filename, SF_FORMAT_AULE, SF_FORMAT_ALAW, 0.04) ;
  144. lcomp_test_int ("aule_alaw", filename, SF_FORMAT_AULE, SF_FORMAT_ALAW, 0.04) ;
  145. lcomp_test_double ("aule_alaw", filename, SF_FORMAT_AULE, SF_FORMAT_ALAW, 0.04) ;
  146. unlink (filename) ;
  147. nTests++ ;
  148. } ;
  149. if (bDoAll || ! strcmp (argv [1], "au_g721"))
  150. { filename = "test.au" ;
  151. lcomp_test_short ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  152. lcomp_test_int ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  153. lcomp_test_double ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  154. sdlcomp_test_short ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  155. sdlcomp_test_int ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  156. sdlcomp_test_double ("au_g721", filename, SF_FORMAT_AU, SF_FORMAT_G721_32, 0.05) ;
  157. unlink (filename) ;
  158. nTests++ ;
  159. } ;
  160. if (bDoAll || ! strcmp (argv [1], "aule_g721"))
  161. { filename = "test.au" ;
  162. lcomp_test_short ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  163. lcomp_test_int ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  164. lcomp_test_double ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  165. sdlcomp_test_short ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  166. sdlcomp_test_int ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  167. sdlcomp_test_double ("aule_g721", filename, SF_FORMAT_AULE, SF_FORMAT_G721_32, 0.05) ;
  168. unlink (filename) ;
  169. nTests++ ;
  170. } ;
  171. if (bDoAll || ! strcmp (argv [1], "au_g723"))
  172. { filename = "test.au" ;
  173. lcomp_test_short ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  174. lcomp_test_int ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  175. lcomp_test_double ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  176. sdlcomp_test_short ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  177. sdlcomp_test_int ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  178. sdlcomp_test_double ("au_g723", filename, SF_FORMAT_AU, SF_FORMAT_G723_24, 0.15) ;
  179. unlink (filename) ;
  180. nTests++ ;
  181. } ;
  182. if (bDoAll || ! strcmp (argv [1], "aule_g723"))
  183. { filename = "test.au" ;
  184. lcomp_test_short ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  185. lcomp_test_int ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  186. lcomp_test_double ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  187. sdlcomp_test_short ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  188. sdlcomp_test_int ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  189. sdlcomp_test_double ("aule_g723", filename, SF_FORMAT_AULE, SF_FORMAT_G723_24, 0.15) ;
  190. unlink (filename) ;
  191. nTests++ ;
  192. } ;
  193. if (nTests == 0)
  194. { printf ("************************************n") ;
  195. printf ("*  No '%s' test defined.n", argv [1]) ;
  196. printf ("************************************n") ;
  197. return 1 ;
  198. } ;
  199. return 0;
  200. } /* main */
  201. /*============================================================================================
  202. ** Here are the test functions.
  203. */ 
  204.  
  205. static
  206. void lcomp_test_short (char *str, char *filename, int typemajor, int typeminor, double margin)
  207. { SNDFILE *file ;
  208. SF_INFO sfinfo ;
  209. int k, m, seekpos ;
  210. unsigned int datalen ;
  211. short *orig, *data ;
  212. printf ("    lcomp_test_short    : %s ... ", str) ;
  213. datalen = BUFFER_SIZE ;
  214. orig = (short*) orig_buffer ;
  215. data = (short*) data_buffer ;
  216. gen_signal (orig_buffer, datalen) ;
  217. for (k = 0 ; k < datalen ; k++)
  218. orig [k] = (short) (orig_buffer [k]) ;
  219. sfinfo.samplerate  = SAMPLE_RATE ;
  220. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  221. sfinfo.channels    = 1 ;
  222. sfinfo.pcmbitwidth = 16 ;
  223. sfinfo.format     = (typemajor | typeminor) ;
  224. if (! (file = sf_open_write (filename, &sfinfo)))
  225. { printf ("sf_open_write failed with error : ") ;
  226. sf_perror (NULL) ;
  227. exit (1) ;
  228. } ;
  229. if ((k = sf_write_short (file, orig, datalen)) != datalen)
  230. { printf ("sf_write_short failed with short write (%d => %d).n", datalen, k) ;
  231. exit (1) ;
  232. } ;
  233. sf_close (file) ;
  234. memset (data, 0, datalen * sizeof (short)) ;
  235. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  236. if (! (file = sf_open_read (filename, &sfinfo)))
  237. { printf ("sf_open_read failed with error : ") ;
  238. sf_perror (NULL) ;
  239. exit (1) ;
  240. } ;
  241. if (sfinfo.format != (typemajor | typeminor))
  242. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  243. exit (1) ;
  244. } ;
  245. if (sfinfo.samples < datalen)
  246. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  247. exit (1) ;
  248. } ;
  249. if (sfinfo.samples > (datalen + datalen/2))
  250. { printf ("Too many samples in file. (%d should be a little more than %d)n", sfinfo.samples, datalen) ;
  251. exit (1) ;
  252. } ;
  253. if (sfinfo.channels != 1)
  254. { printf ("Incorrect number of channels in file.n") ;
  255. exit (1) ;
  256. } ;
  257. if (sfinfo.pcmbitwidth != 16)
  258. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  259. exit (1) ;
  260. } ;
  261. if ((k = sf_read_short (file, data, datalen)) < 0.99 * datalen)
  262. { printf ("short read (%d).n", k) ;
  263. exit (1) ;
  264. } ;
  265. for (k = 0 ; k < datalen ; k++)
  266. { if (error_function ((double) data [k], (double) orig [k], margin))
  267. { printf ("Incorrect sample A (#%d : %d should be %d).n", k, data [k], orig [k]) ;
  268. exit (1) ;
  269. } ;
  270. } ;
  271. if ((k = sf_read_short (file, data, datalen)) != sfinfo.samples - datalen)
  272. { printf ("Incorrect read length A (%d should be %d).n", sfinfo.samples - datalen, k) ;
  273. exit (1) ;
  274. } ;
  275. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  276. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  277. if (abs (data [k]) > decay_response (k))
  278. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, data [k], decay_response (k)) ;
  279. exit (1) ;
  280. } ;
  281. if (! sfinfo.seekable)
  282. { printf ("okn") ;
  283. return ;
  284. } ;
  285. /* Now test sf_seek function. */
  286. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  287. { printf ("Seek to start of file failed (%d).n", k) ;
  288. exit (1) ;
  289. } ;
  290. for (m = 0 ; m < 3 ; m++)
  291. { if ((k = sf_read_short (file, data, datalen/7)) != datalen / 7)
  292. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  293. exit (1) ;
  294. } ;
  295. for (k = 0 ; k < datalen/7 ; k++)
  296. if (error_function ((double) data [k], (double) orig [k + m * (datalen / 7)], margin))
  297. { printf ("Incorrect sample C (#%d : %d => %d).n", k + m * (datalen / 7), orig [k + m * (datalen / 7)], data [k]) ;
  298. for (m = 0 ; m < 10 ; m++)
  299. printf ("%d ", data [k]) ;
  300. printf ("n") ;
  301. exit (1) ;
  302. } ;
  303. } ;
  304. seekpos = BUFFER_SIZE / 10 ;
  305. /* Check seek from start of file. */
  306. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  307. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  308. exit (1) ;
  309. } ;
  310. if ((k = sf_read_short (file, data, 1)) != 1)
  311. { printf ("sf_read_short (file, data, 1) returned %d.n", k) ;
  312. exit (1) ;
  313. } ;
  314. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  315. { printf ("sf_seek (SEEK_SET) followed by sf_read_short failed (%d, %d).n", orig [1], data [0]) ;
  316. exit (1) ;
  317. } ;
  318. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  319. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  320. exit (1) ;
  321. } ;
  322. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  323. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  324. sf_read_short (file, data, 1) ;
  325. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  326. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos + 1) ;
  327. exit (1) ;
  328. } ;
  329. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  330. /* Check seek backward from current position. */
  331. k = sf_seek (file, -20, SEEK_CUR) ;
  332. sf_read_short (file, data, 1) ;
  333. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  334. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos) ;
  335. exit (1) ;
  336. } ;
  337. /* Check that read past end of file returns number of items. */
  338. sf_seek (file, (int) datalen, SEEK_SET) ;
  339.   if ((k = sf_read_short (file, data, datalen)) != sfinfo.samples - datalen)
  340.   { printf ("Return value from sf_read_short past end of file incorrect (%d).n", k) ;
  341.   exit (1) ;
  342.   } ;
  343. /* Check seek backward from end. */
  344. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  345. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  346. exit (1) ;
  347. } ;
  348. sf_read_short (file, data, 1) ;
  349. if (error_function ((double) data [0], (double) orig [5], margin))
  350. { printf ("sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).n", data [0], orig [5]) ;
  351. exit (1) ;
  352. } ;
  353. sf_close (file) ;
  354. printf ("okn") ;
  355. } /* lcomp_test_short */
  356. /*--------------------------------------------------------------------------------------------
  357. */ 
  358.  
  359. static
  360. void lcomp_test_int (char *str, char *filename, int typemajor, int typeminor, double margin)
  361. { SNDFILE *file ;
  362. SF_INFO sfinfo ;
  363. int k, m, seekpos ;
  364. unsigned int datalen ;
  365. int *orig, *data ;
  366. printf ("    lcomp_test_int      : %s ... ", str) ;
  367. datalen = BUFFER_SIZE ;
  368. data = (int*) data_buffer ;
  369. orig = (int*) orig_buffer ;
  370. gen_signal (orig_buffer, datalen) ;
  371. for (k = 0 ; k < datalen ; k++)
  372. orig [k] = (int) (orig_buffer [k]) ;
  373. sfinfo.samplerate  = SAMPLE_RATE ;
  374. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  375. sfinfo.channels    = 1 ;
  376. sfinfo.pcmbitwidth = 16 ;
  377. sfinfo.format     = (typemajor | typeminor) ;
  378. if (! (file = sf_open_write (filename, &sfinfo)))
  379. { printf ("sf_open_write failed with error : ") ;
  380. sf_perror (NULL) ;
  381. exit (1) ;
  382. } ;
  383. if ((k = sf_write_int (file, orig, datalen)) != datalen)
  384. { printf ("sf_write_int failed with short write (%d => %d).n", datalen, k) ;
  385. exit (1) ;
  386. } ;
  387. sf_close (file) ;
  388. memset (data, 0, datalen * sizeof (short)) ;
  389. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  390. if (! (file = sf_open_read (filename, &sfinfo)))
  391. { printf ("sf_open_read failed with error : ") ;
  392. sf_perror (NULL) ;
  393. exit (1) ;
  394. } ;
  395. if (sfinfo.format != (typemajor | typeminor))
  396. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  397. exit (1) ;
  398. } ;
  399. if (sfinfo.samples < datalen)
  400. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  401. exit (1) ;
  402. } ;
  403. if (sfinfo.samples > (datalen + datalen/2))
  404. { printf ("Too many samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  405. exit (1) ;
  406. } ;
  407. if (sfinfo.channels != 1)
  408. { printf ("Incorrect number of channels in file.n") ;
  409. exit (1) ;
  410. } ;
  411. if (sfinfo.pcmbitwidth != 16)
  412. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  413. exit (1) ;
  414. } ;
  415. if ((k = sf_read_int (file, data, datalen)) != datalen)
  416. { printf ("short read (%d).n", k) ;
  417. exit (1) ;
  418. } ;
  419. for (k = 0 ; k < datalen ; k++)
  420. { if (error_function ((double) data [k], (double) orig [k], margin))
  421. { printf ("Incorrect sample A (#%d : %d should be %d).n", k, data [k], orig [k]) ;
  422. exit (1) ;
  423. } ;
  424. } ;
  425. if ((k = sf_read_int (file, data, datalen)) != sfinfo.samples - datalen)
  426. { printf ("Incorrect read length A (%d should be %d).n", sfinfo.samples - datalen, k) ;
  427. exit (1) ;
  428. } ;
  429. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  430. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  431. if (abs (data [k]) > decay_response (k))
  432. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, data [k], decay_response (k)) ;
  433. exit (1) ;
  434. } ;
  435. if (! sfinfo.seekable)
  436. { printf ("okn") ;
  437. return ;
  438. } ;
  439. /* Now test sf_seek function. */
  440. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  441. { printf ("Seek to start of file failed (%d).n", k) ;
  442. exit (1) ;
  443. } ;
  444. for (m = 0 ; m < 3 ; m++)
  445. { if ((k = sf_read_int (file, data, datalen/7)) != datalen / 7)
  446. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  447. exit (1) ;
  448. } ;
  449. for (k = 0 ; k < datalen/7 ; k++)
  450. if (error_function ((double) data [k], (double) orig [k + m * (datalen / 7)], margin))
  451. { printf ("Incorrect sample C (#%d : %d => %d).n", k + m * (datalen / 7), orig [k + m * (datalen / 7)], data [k]) ;
  452. for (m = 0 ; m < 10 ; m++)
  453. printf ("%d ", data [k]) ;
  454. printf ("n") ;
  455. exit (1) ;
  456. } ;
  457. } ;
  458. seekpos = BUFFER_SIZE / 10 ;
  459. /* Check seek from start of file. */
  460. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  461. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  462. exit (1) ;
  463. } ;
  464. if ((k = sf_read_int (file, data, 1)) != 1)
  465. { printf ("sf_read_int (file, data, 1) returned %d.n", k) ;
  466. exit (1) ;
  467. } ;
  468. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  469. { printf ("sf_seek (SEEK_SET) followed by sf_read_int failed (%d, %d).n", orig [1], data [0]) ;
  470. exit (1) ;
  471. } ;
  472. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  473. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  474. exit (1) ;
  475. } ;
  476. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  477. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  478. sf_read_int (file, data, 1) ;
  479. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  480. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_int failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos + 1) ;
  481. exit (1) ;
  482. } ;
  483. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  484. /* Check seek backward from current position. */
  485. k = sf_seek (file, -20, SEEK_CUR) ;
  486. sf_read_int (file, data, 1) ;
  487. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  488. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_int failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos) ;
  489. exit (1) ;
  490. } ;
  491. /* Check that read past end of file returns number of items. */
  492. sf_seek (file, (int) datalen, SEEK_SET) ;
  493.   if ((k = sf_read_int (file, data, datalen)) != sfinfo.samples - datalen)
  494.   { printf ("Return value from sf_read_int past end of file incorrect (%d).n", k) ;
  495.   exit (1) ;
  496.   } ;
  497. /* Check seek backward from end. */
  498. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  499. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  500. exit (1) ;
  501. } ;
  502. sf_read_int (file, data, 1) ;
  503. if (error_function ((double) data [0], (double) orig [5], margin))
  504. { printf ("sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).n", data [0], orig [5]) ;
  505. exit (1) ;
  506. } ;
  507. sf_close (file) ;
  508. printf ("okn") ;
  509. } /* lcomp_test_int */
  510. /*--------------------------------------------------------------------------------------------
  511. */ 
  512. static
  513. void lcomp_test_double (char *str, char *filename, int typemajor, int typeminor, double margin)
  514. { SNDFILE *file ;
  515. SF_INFO sfinfo ;
  516. int k, m, seekpos ;
  517. unsigned int datalen ;
  518. double *orig, *data ;
  519. printf ("    lcomp_test_double   : %s ... ", str) ;
  520. datalen = BUFFER_SIZE ;
  521. orig = (double*) orig_buffer ;
  522. data = (double*) data_buffer ;
  523. gen_signal (orig_buffer, datalen) ;
  524. sfinfo.samplerate  = SAMPLE_RATE ;
  525. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  526. sfinfo.channels    = 1 ;
  527. sfinfo.pcmbitwidth = 16 ;
  528. sfinfo.format     = (typemajor | typeminor) ;
  529. if (! (file = sf_open_write (filename, &sfinfo)))
  530. { printf ("sf_open_write failed with error : ") ;
  531. sf_perror (NULL) ;
  532. exit (1) ;
  533. } ;
  534. if ((k = sf_write_double (file, orig, datalen, 0)) != datalen)
  535. { printf ("sf_write_double failed with double write (%d => %d).n", datalen, k) ;
  536. exit (1) ;
  537. } ;
  538. sf_close (file) ;
  539. memset (data, 0, datalen * sizeof (double)) ;
  540. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  541. if (! (file = sf_open_read (filename, &sfinfo)))
  542. { printf ("sf_open_read failed with error : ") ;
  543. sf_perror (NULL) ;
  544. exit (1) ;
  545. } ;
  546. if (sfinfo.format != (typemajor | typeminor))
  547. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  548. exit (1) ;
  549. } ;
  550. if (sfinfo.samples < datalen)
  551. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  552. exit (1) ;
  553. } ;
  554. if (sfinfo.samples > (datalen + datalen/2))
  555. { printf ("Too many samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  556. exit (1) ;
  557. } ;
  558. if (sfinfo.channels != 1)
  559. { printf ("Incorrect number of channels in file.n") ;
  560. exit (1) ;
  561. } ;
  562. if (sfinfo.pcmbitwidth != 16)
  563. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  564. exit (1) ;
  565. } ;
  566. if ((k = sf_read_double (file, data, datalen, 0)) != datalen)
  567. { printf ("double read (%d).n", k) ;
  568. exit (1) ;
  569. } ;
  570. for (k = 0 ; k < datalen ; k++)
  571. if (error_function (data [k], orig [k], margin))
  572. { printf ("Incorrect sample A (#%d : %f should be %f).n", k, data [k], orig [k]) ;
  573. exit (1) ;
  574. } ;
  575. if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen)
  576. { printf ("Incorrect read length A (%d should be %d).n", sfinfo.samples - datalen, k) ;
  577. exit (1) ;
  578. } ;
  579. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  580. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  581. if (abs ((int) data [k]) > decay_response (k))
  582. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, (int) data [k], decay_response (k)) ;
  583. exit (1) ;
  584. } ;
  585. if (! sfinfo.seekable)
  586. { printf ("okn") ;
  587. return ;
  588. } ;
  589. /* Now test sf_seek function. */
  590. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  591. { printf ("Seek to start of file failed (%d).n", k) ;
  592. exit (1) ;
  593. } ;
  594. for (m = 0 ; m < 3 ; m++)
  595. { if ((k = sf_read_double (file, data, datalen/7, 0)) != datalen / 7)
  596. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  597. exit (1) ;
  598. } ;
  599. for (k = 0 ; k < datalen/7 ; k++)
  600. if (error_function (data [k], orig [k + m * (datalen / 7)], margin))
  601. { printf ("Incorrect sample C (#%d : %d => %d).n", k + m * (datalen / 7), (int) orig [k + m * (datalen / 7)], (int) data [k]) ;
  602. for (m = 0 ; m < 10 ; m++)
  603. printf ("%d ", (int) data [k]) ;
  604. printf ("n") ;
  605. exit (1) ;
  606. } ;
  607. } ;
  608. seekpos = BUFFER_SIZE / 10 ;
  609. /* Check seek from start of file. */
  610. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  611. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  612. exit (1) ;
  613. } ;
  614. if ((k = sf_read_double (file, data, 1, 0)) != 1)
  615. { printf ("sf_read_double (file, data, 1, 0) returned %d.n", k) ;
  616. exit (1) ;
  617. } ;
  618. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  619. { printf ("sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).n", (int) orig [1], (int) data [0]) ;
  620. exit (1) ;
  621. } ;
  622. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  623. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  624. exit (1) ;
  625. } ;
  626. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  627. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  628. sf_read_double (file, data, 1, 0) ;
  629. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  630. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).n", (int) data [0], (int) orig [seekpos], k, seekpos + 1) ;
  631. exit (1) ;
  632. } ;
  633. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  634. /* Check seek backward from current position. */
  635. k = sf_seek (file, -20, SEEK_CUR) ;
  636. sf_read_double (file, data, 1, 0) ;
  637. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  638. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).n", (int) data [0], (int) orig [seekpos], k, seekpos) ;
  639. exit (1) ;
  640. } ;
  641. /* Check that read past end of file returns number of items. */
  642. sf_seek (file, (int) datalen, SEEK_SET) ;
  643.   if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen)
  644.   { printf ("Return value from sf_read_double past end of file incorrect (%d).n", k) ;
  645.   exit (1) ;
  646.   } ;
  647. /* Check seek backward from end. */
  648. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  649. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  650. exit (1) ;
  651. } ;
  652. sf_read_double (file, data, 1, 0) ;
  653. if (error_function (data [0], orig [5], margin))
  654. { printf ("sf_seek (SEEK_END) followed by sf_read_double failed (%d, %d).n", (int) data [0], (int) orig [5]) ;
  655. exit (1) ;
  656. } ;
  657. sf_close (file) ;
  658. printf ("okn") ;
  659. } /* lcomp_test_double */
  660. /*========================================================================================
  661. ** Smoothed differential loss compression tests.
  662. */
  663. static
  664. void sdlcomp_test_short (char *str, char *filename, int typemajor, int typeminor, double margin)
  665. { SNDFILE *file ;
  666. SF_INFO sfinfo ;
  667. int k, m, seekpos ;
  668. unsigned int datalen ;
  669. short *orig, *data, *smooth ;
  670. printf ("    sdlcomp_test_short  : %s ... ", str) ;
  671. datalen = BUFFER_SIZE ;
  672. orig = (short*) orig_buffer ;
  673. data = (short*) data_buffer ;
  674. smooth = (short*) smooth_buffer ;
  675. gen_signal (orig_buffer, datalen) ;
  676. for (k = 0 ; k < datalen ; k++)
  677. orig [k] = (short) (orig_buffer [k]) ;
  678. sfinfo.samplerate  = SAMPLE_RATE ;
  679. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  680. sfinfo.channels    = 1 ;
  681. sfinfo.pcmbitwidth = 16 ;
  682. sfinfo.format     = (typemajor | typeminor) ;
  683. if (! (file = sf_open_write (filename, &sfinfo)))
  684. { printf ("sf_open_write failed with error : ") ;
  685. sf_perror (NULL) ;
  686. exit (1) ;
  687. } ;
  688. if ((k = sf_write_short (file, orig, datalen)) != datalen)
  689. { printf ("sf_write_short failed with short write (%d => %d).n", datalen, k) ;
  690. exit (1) ;
  691. } ;
  692. sf_close (file) ;
  693. memset (data, 0, datalen * sizeof (short)) ;
  694. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  695. if (! (file = sf_open_read (filename, &sfinfo)))
  696. { printf ("sf_open_read failed with error : ") ;
  697. sf_perror (NULL) ;
  698. exit (1) ;
  699. } ;
  700. if (sfinfo.format != (typemajor | typeminor))
  701. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  702. exit (1) ;
  703. } ;
  704. if (sfinfo.samples < datalen)
  705. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  706. exit (1) ;
  707. } ;
  708. if (sfinfo.samples > (datalen + 400))
  709. { printf ("Too many samples in file. (%d should be a little more than %d)n", sfinfo.samples, datalen) ;
  710. exit (1) ;
  711. } ;
  712. if (sfinfo.channels != 1)
  713. { printf ("Incorrect number of channels in file.n") ;
  714. exit (1) ;
  715. } ;
  716. if (sfinfo.pcmbitwidth != 16)
  717. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  718. exit (1) ;
  719. } ;
  720. if ((k = sf_read_short (file, data, datalen)) != datalen)
  721. { printf ("short read (%d).n", k) ;
  722. exit (1) ;
  723. } ;
  724. memcpy (smooth, orig, datalen * sizeof (short)) ;
  725. smoothed_diff_short (data, datalen) ;
  726. smoothed_diff_short (smooth, datalen) ;
  727. for (k = 1 ; k < datalen ; k++)
  728. { if (error_function ((double) data [k], (double) smooth [k], margin))
  729. { printf ("Incorrect sample A (#%d : %d should be %d).n", k, data [k], smooth [k]) ;
  730. exit (1) ;
  731. } ;
  732. } ;
  733. if ((k = sf_read_short (file, data, datalen)) != sfinfo.samples - datalen)
  734. { printf ("Incorrect read length A (%d should be %d).n", k, sfinfo.samples - datalen) ;
  735. exit (1) ;
  736. } ;
  737. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  738. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  739. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  740. if (abs (data [k]) > decay_response (k))
  741. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, data [k], decay_response (k)) ;
  742. exit (1) ;
  743. } ;
  744. /* Now test sf_seek function. */
  745. if (sfinfo.seekable)
  746. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  747. { printf ("Seek to start of file failed (%d).n", k) ;
  748. exit (1) ;
  749. } ;
  750. for (m = 0 ; m < 3 ; m++)
  751. { if ((k = sf_read_short (file, data, datalen/7)) != datalen / 7)
  752. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  753. exit (1) ;
  754. } ;
  755. smoothed_diff_short (data, datalen/7) ;
  756. memcpy (smooth, orig + m * datalen/7, datalen/7 * sizeof (short)) ;
  757. smoothed_diff_short (smooth, datalen/7) ;
  758. for (k = 0 ; k < datalen/7 ; k++)
  759. if (error_function ((double) data [k], (double) smooth [k], margin))
  760. { printf ("Incorrect sample C (#%d (%d) : %d => %d).n", k, k + m * (datalen / 7), smooth [k], data [k]) ;
  761. for (m = 0 ; m < 10 ; m++)
  762. printf ("%d ", data [k]) ;
  763. printf ("n") ;
  764. exit (1) ;
  765. } ;
  766. } ; /* for (m = 0 ; m < 3 ; m++) */
  767. seekpos = BUFFER_SIZE / 10 ;
  768. /* Check seek from start of file. */
  769. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  770. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  771. exit (1) ;
  772. } ;
  773. if ((k = sf_read_short (file, data, 1)) != 1)
  774. { printf ("sf_read_short (file, data, 1) returned %d.n", k) ;
  775. exit (1) ;
  776. } ;
  777. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  778. { printf ("sf_seek (SEEK_SET) followed by sf_read_short failed (%d, %d).n", orig [1], data [0]) ;
  779. exit (1) ;
  780. } ;
  781. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  782. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  783. exit (1) ;
  784. } ;
  785. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  786. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  787. sf_read_short (file, data, 1) ;
  788. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  789. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos + 1) ;
  790. exit (1) ;
  791. } ;
  792. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  793. /* Check seek backward from current position. */
  794. k = sf_seek (file, -20, SEEK_CUR) ;
  795. sf_read_short (file, data, 1) ;
  796. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  797. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos) ;
  798. exit (1) ;
  799. } ;
  800. /* Check that read past end of file returns number of items. */
  801. sf_seek (file, (int) datalen, SEEK_SET) ;
  802.   if ((k = sf_read_short (file, data, datalen)) != sfinfo.samples - datalen)
  803.   { printf ("Return value from sf_read_short past end of file incorrect (%d).n", k) ;
  804.   exit (1) ;
  805.   } ;
  806. /* Check seek backward from end. */
  807. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  808. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  809. exit (1) ;
  810. } ;
  811. sf_read_short (file, data, 1) ;
  812. if (error_function ((double) data [0], (double) orig [5], margin))
  813. { printf ("sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).n", data [0], orig [5]) ;
  814. exit (1) ;
  815. } ;
  816. } /* if (sfinfo.seekable) */
  817. sf_close (file) ;
  818. printf ("okn") ;
  819. } /* sdlcomp_test_short */
  820. static
  821. void sdlcomp_test_int (char *str, char *filename, int typemajor, int typeminor, double margin)
  822. { SNDFILE *file ;
  823. SF_INFO sfinfo ;
  824. int k, m, seekpos ;
  825. unsigned int datalen ;
  826. int *orig, *data, *smooth ;
  827. printf ("    sdlcomp_test_int    : %s ... ", str) ;
  828. datalen = BUFFER_SIZE ;
  829. orig = (int*) orig_buffer ;
  830. data = (int*) data_buffer ;
  831. smooth = (int*) smooth_buffer ;
  832. gen_signal (orig_buffer, datalen) ;
  833. for (k = 0 ; k < datalen ; k++)
  834. orig [k] = (int) (orig_buffer [k]) ;
  835. sfinfo.samplerate  = SAMPLE_RATE ;
  836. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  837. sfinfo.channels    = 1 ;
  838. sfinfo.pcmbitwidth = 16 ;
  839. sfinfo.format     = (typemajor | typeminor) ;
  840. if (! (file = sf_open_write (filename, &sfinfo)))
  841. { printf ("sf_open_write failed with error : ") ;
  842. sf_perror (NULL) ;
  843. exit (1) ;
  844. } ;
  845. if ((k = sf_write_int (file, orig, datalen)) != datalen)
  846. { printf ("sf_write_int failed with int write (%d => %d).n", datalen, k) ;
  847. exit (1) ;
  848. } ;
  849. sf_close (file) ;
  850. memset (data, 0, datalen * sizeof (int)) ;
  851. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  852. if (! (file = sf_open_read (filename, &sfinfo)))
  853. { printf ("sf_open_read failed with error : ") ;
  854. sf_perror (NULL) ;
  855. exit (1) ;
  856. } ;
  857. if (sfinfo.format != (typemajor | typeminor))
  858. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  859. exit (1) ;
  860. } ;
  861. if (sfinfo.samples < datalen)
  862. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  863. exit (1) ;
  864. } ;
  865. if (sfinfo.samples > (datalen + 400))
  866. { printf ("Too many samples in file. (%d should be a little more than %d)n", sfinfo.samples, datalen) ;
  867. exit (1) ;
  868. } ;
  869. if (sfinfo.channels != 1)
  870. { printf ("Incorrect number of channels in file.n") ;
  871. exit (1) ;
  872. } ;
  873. if (sfinfo.pcmbitwidth != 16)
  874. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  875. exit (1) ;
  876. } ;
  877. if ((k = sf_read_int (file, data, datalen)) != datalen)
  878. { printf ("int read (%d).n", k) ;
  879. exit (1) ;
  880. } ;
  881. memcpy (smooth, orig, datalen * sizeof (int)) ;
  882. smoothed_diff_int (data, datalen) ;
  883. smoothed_diff_int (smooth, datalen) ;
  884. for (k = 1 ; k < datalen ; k++)
  885. { if (error_function ((double) data [k], (double) smooth [k], margin))
  886. { printf ("Incorrect sample A (#%d : %d should be %d).n", k, data [k], smooth [k]) ;
  887. exit (1) ;
  888. } ;
  889. } ;
  890. if ((k = sf_read_int (file, data, datalen)) != sfinfo.samples - datalen)
  891. { printf ("Incorrect read length A (%d should be %d).n", k, sfinfo.samples - datalen) ;
  892. exit (1) ;
  893. } ;
  894. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  895. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  896. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  897. if (abs (data [k]) > decay_response (k))
  898. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, data [k], decay_response (k)) ;
  899. exit (1) ;
  900. } ;
  901. /* Now test sf_seek function. */
  902. if (sfinfo.seekable)
  903. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  904. { printf ("Seek to start of file failed (%d).n", k) ;
  905. exit (1) ;
  906. } ;
  907. for (m = 0 ; m < 3 ; m++)
  908. { if ((k = sf_read_int (file, data, datalen/7)) != datalen / 7)
  909. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  910. exit (1) ;
  911. } ;
  912. smoothed_diff_int (data, datalen/7) ;
  913. memcpy (smooth, orig + m * datalen/7, datalen/7 * sizeof (int)) ;
  914. smoothed_diff_int (smooth, datalen/7) ;
  915. for (k = 0 ; k < datalen/7 ; k++)
  916. if (error_function ((double) data [k], (double) smooth [k], margin))
  917. { printf ("Incorrect sample C (#%d (%d) : %d => %d).n", k, k + m * (datalen / 7), smooth [k], data [k]) ;
  918. for (m = 0 ; m < 10 ; m++)
  919. printf ("%d ", data [k]) ;
  920. printf ("n") ;
  921. exit (1) ;
  922. } ;
  923. } ; /* for (m = 0 ; m < 3 ; m++) */
  924. seekpos = BUFFER_SIZE / 10 ;
  925. /* Check seek from start of file. */
  926. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  927. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  928. exit (1) ;
  929. } ;
  930. if ((k = sf_read_int (file, data, 1)) != 1)
  931. { printf ("sf_read_int (file, data, 1) returned %d.n", k) ;
  932. exit (1) ;
  933. } ;
  934. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  935. { printf ("sf_seek (SEEK_SET) followed by sf_read_int failed (%d, %d).n", orig [1], data [0]) ;
  936. exit (1) ;
  937. } ;
  938. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  939. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  940. exit (1) ;
  941. } ;
  942. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  943. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  944. sf_read_int (file, data, 1) ;
  945. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  946. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_int failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos + 1) ;
  947. exit (1) ;
  948. } ;
  949. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  950. /* Check seek backward from current position. */
  951. k = sf_seek (file, -20, SEEK_CUR) ;
  952. sf_read_int (file, data, 1) ;
  953. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  954. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_int failed (%d, %d) (%d, %d).n", data [0], orig [seekpos], k, seekpos) ;
  955. exit (1) ;
  956. } ;
  957. /* Check that read past end of file returns number of items. */
  958. sf_seek (file, (int) datalen, SEEK_SET) ;
  959.   if ((k = sf_read_int (file, data, datalen)) != sfinfo.samples - datalen)
  960.   { printf ("Return value from sf_read_int past end of file incorrect (%d).n", k) ;
  961.   exit (1) ;
  962.   } ;
  963. /* Check seek backward from end. */
  964. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  965. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  966. exit (1) ;
  967. } ;
  968. sf_read_int (file, data, 1) ;
  969. if (error_function ((double) data [0], (double) orig [5], margin))
  970. { printf ("sf_seek (SEEK_END) followed by sf_read_int failed (%d should be %d).n", data [0], orig [5]) ;
  971. exit (1) ;
  972. } ;
  973. } /* if (sfinfo.seekable) */
  974. sf_close (file) ;
  975. printf ("okn") ;
  976. } /* sdlcomp_test_int */
  977. static
  978. void sdlcomp_test_double (char *str, char *filename, int typemajor, int typeminor, double margin)
  979. { SNDFILE *file ;
  980. SF_INFO sfinfo ;
  981. int k, m, seekpos ;
  982. unsigned int datalen ;
  983. double *orig, *data, *smooth ;
  984. printf ("    sdlcomp_test_double : %s ... ", str) ;
  985. datalen = BUFFER_SIZE ;
  986. orig = orig_buffer ;
  987. data = data_buffer ;
  988. smooth = smooth_buffer ;
  989. gen_signal (orig_buffer, datalen) ;
  990. sfinfo.samplerate  = SAMPLE_RATE ;
  991. sfinfo.samples     = 123456789 ; /* Ridiculous value. */
  992. sfinfo.channels    = 1 ;
  993. sfinfo.pcmbitwidth = 16 ;
  994. sfinfo.format     = (typemajor | typeminor) ;
  995. if (! (file = sf_open_write (filename, &sfinfo)))
  996. { printf ("sf_open_write failed with error : ") ;
  997. sf_perror (NULL) ;
  998. exit (1) ;
  999. } ;
  1000. if ((k = sf_write_double (file, orig, datalen, 0)) != datalen)
  1001. { printf ("sf_write_double failed with int write (%d => %d).n", datalen, k) ;
  1002. exit (1) ;
  1003. } ;
  1004. sf_close (file) ;
  1005. memset (data, 0, datalen * sizeof (double)) ;
  1006. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1007. if (! (file = sf_open_read (filename, &sfinfo)))
  1008. { printf ("sf_open_read failed with error : ") ;
  1009. sf_perror (NULL) ;
  1010. exit (1) ;
  1011. } ;
  1012. if (sfinfo.format != (typemajor | typeminor))
  1013. { printf ("Returned format incorrect (0x%08X => 0x%08X).n", (typemajor | typeminor), sfinfo.format) ;
  1014. exit (1) ;
  1015. } ;
  1016. if (sfinfo.samples < datalen)
  1017. { printf ("Too few samples in file. (%d should be a little more than %d)n", datalen, sfinfo.samples) ;
  1018. exit (1) ;
  1019. } ;
  1020. if (sfinfo.samples > (datalen + 400))
  1021. { printf ("Too many samples in file. (%d should be a little more than %d)n", sfinfo.samples, datalen) ;
  1022. exit (1) ;
  1023. } ;
  1024. if (sfinfo.channels != 1)
  1025. { printf ("Incorrect number of channels in file.n") ;
  1026. exit (1) ;
  1027. } ;
  1028. if (sfinfo.pcmbitwidth != 16)
  1029. { printf ("Incorrect bit width (%d).n", sfinfo.pcmbitwidth) ;
  1030. exit (1) ;
  1031. } ;
  1032. if ((k = sf_read_double (file, data, datalen, 0)) != datalen)
  1033. { printf ("int read (%d).n", k) ;
  1034. exit (1) ;
  1035. } ;
  1036. memcpy (smooth, orig, datalen * sizeof (double)) ;
  1037. smoothed_diff_double (data, datalen) ;
  1038. smoothed_diff_double (smooth, datalen) ;
  1039. for (k = 1 ; k < datalen ; k++)
  1040. { if (error_function (data [k], smooth [k], margin))
  1041. { printf ("Incorrect sample A (#%d : %d should be %d).n", k, (int) data [k], (int) smooth [k]) ;
  1042. exit (1) ;
  1043. } ;
  1044. } ;
  1045. if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen)
  1046. { printf ("Incorrect read length A (%d should be %d).n", k, sfinfo.samples - datalen) ;
  1047. exit (1) ;
  1048. } ;
  1049. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  1050. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  1051. for (k = 0 ; k < sfinfo.samples - datalen ; k++)
  1052. if (abs (data [k]) > decay_response (k))
  1053. { printf ("Incorrect sample B (#%d : abs (%d) should be < %d).n", datalen + k, (int) data [k], (int) decay_response (k)) ;
  1054. exit (1) ;
  1055. } ;
  1056. /* Now test sf_seek function. */
  1057. if (sfinfo.seekable)
  1058. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1059. { printf ("Seek to start of file failed (%d).n", k) ;
  1060. exit (1) ;
  1061. } ;
  1062. for (m = 0 ; m < 3 ; m++)
  1063. { if ((k = sf_read_double (file, data, datalen/7, 0)) != datalen / 7)
  1064. { printf ("Incorrect read length B (%d => %d).n", datalen / 7, k) ;
  1065. exit (1) ;
  1066. } ;
  1067. smoothed_diff_double (data, datalen/7) ;
  1068. memcpy (smooth, orig + m * datalen/7, datalen/7 * sizeof (double)) ;
  1069. smoothed_diff_double (smooth, datalen/7) ;
  1070. for (k = 0 ; k < datalen/7 ; k++)
  1071. if (error_function ((double) data [k], (double) smooth [k], margin))
  1072. { printf ("Incorrect sample C (#%d (%d) : %d => %d).n", k, k + m * (datalen / 7), (int) smooth [k], (int) data [k]) ;
  1073. for (m = 0 ; m < 10 ; m++)
  1074. printf ("%d ", (int) data [k]) ;
  1075. printf ("n") ;
  1076. exit (1) ;
  1077. } ;
  1078. } ; /* for (m = 0 ; m < 3 ; m++) */
  1079. seekpos = BUFFER_SIZE / 10 ;
  1080. /* Check seek from start of file. */
  1081. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1082. { printf ("Seek to start of file + %d failed (%d).n", seekpos, k) ;
  1083. exit (1) ;
  1084. } ;
  1085. if ((k = sf_read_double (file, data, 1, 0)) != 1)
  1086. { printf ("sf_read_double (file, data, 1) returned %d.n", k) ;
  1087. exit (1) ;
  1088. } ;
  1089. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  1090. { printf ("sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).n", (int) orig [1], (int) data [0]) ;
  1091. exit (1) ;
  1092. } ;
  1093. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1094. { printf ("sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)n", k, seekpos + 1) ;
  1095. exit (1) ;
  1096. } ;
  1097. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1098. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1099. sf_read_double (file, data, 1, 0) ;
  1100. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  1101. { printf ("sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).n", (int) data [0], (int) orig [seekpos], k, seekpos + 1) ;
  1102. exit (1) ;
  1103. } ;
  1104. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1105. /* Check seek backward from current position. */
  1106. k = sf_seek (file, -20, SEEK_CUR) ;
  1107. sf_read_double (file, data, 1, 0) ;
  1108. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  1109. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).n", (int) data [0], (int) orig [seekpos], k, seekpos) ;
  1110. exit (1) ;
  1111. } ;
  1112. /* Check that read past end of file returns number of items. */
  1113. sf_seek (file, (int) datalen, SEEK_SET) ;
  1114.   if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen)
  1115.   { printf ("Return value from sf_read_double past end of file incorrect (%d).n", k) ;
  1116.   exit (1) ;
  1117.   } ;
  1118. /* Check seek backward from end. */
  1119. if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5)
  1120. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  1121. exit (1) ;
  1122. } ;
  1123. sf_read_double (file, data, 1, 0) ;
  1124. if (error_function ((double) data [0], (double) orig [5], margin))
  1125. { printf ("sf_seek (SEEK_END) followed by sf_read_double failed (%d should be %d).n", (int) data [0], (int) orig [5]) ;
  1126. exit (1) ;
  1127. } ;
  1128. } /* if (sfinfo.seekable) */
  1129. sf_close (file) ;
  1130. printf ("okn") ;
  1131. } /* sdlcomp_test_double */
  1132. /*========================================================================================
  1133. ** Auxiliary functions
  1134. */
  1135. static
  1136. int decay_response (int k)
  1137. { if (k < 1)
  1138. return ((int) 30000.0) ;
  1139. return (int) (30000.0 / (0.5 * k * k)) ;
  1140. } /* decay_response */
  1141. static
  1142. void gen_signal (double *data, unsigned int datalen)
  1143. { unsigned int k, ramplen ;
  1144. double amp = 0.0 ;
  1145. ramplen = datalen / 20 ;
  1146. for (k = 0 ; k < datalen ; k++)
  1147. { if (k <= ramplen)
  1148. amp = 30000.0 * k / ((double) ramplen) ;
  1149. else if (k > datalen - ramplen)
  1150. amp = 30000.0 * (datalen - k) / ((double) ramplen) ;
  1151. data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
  1152. + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
  1153. } ;
  1154. return ;
  1155. } /* gen_signal */
  1156. static
  1157. int error_function (double data, double orig, double margin)
  1158. { double error ;
  1159. if (fabs (orig) <= 500.0)
  1160. error = fabs (fabs (data) - fabs(orig)) / 2000.0 ;
  1161. else if (fabs (orig) <= 1000.0)
  1162. error = fabs (data - orig) / 3000.0 ;
  1163. else
  1164. error = fabs (data - orig) / fabs (orig) ;
  1165. if (error > margin)
  1166. { printf ("nn*******************nError : %fn", error) ;
  1167. return 1 ;
  1168. } ;
  1169. return 0 ;
  1170. } /* error_function */
  1171. static
  1172. void smoothed_diff_short (short *data, unsigned int datalen)
  1173. { unsigned int k ;
  1174. double memory = 0.0 ;
  1175. /* Calculate the smoothed sample-to-sample difference. */
  1176. for (k = 0 ; k < datalen - 1 ; k++)
  1177. { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
  1178. data [k] = (short) memory ;
  1179. } ;
  1180. data [datalen-1] = data [datalen-2] ;
  1181. } /* smoothed_diff_short */
  1182. static
  1183. void smoothed_diff_int (int *data, unsigned int datalen)
  1184. { unsigned int k ;
  1185. double memory = 0.0 ;
  1186. /* Calculate the smoothed sample-to-sample difference. */
  1187. for (k = 0 ; k < datalen - 1 ; k++)
  1188. { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
  1189. data [k] = (int) memory ;
  1190. } ;
  1191. data [datalen-1] = data [datalen-2] ;
  1192. } /* smoothed_diff_int */
  1193. static
  1194. void smoothed_diff_double (double *data, unsigned int datalen)
  1195. { unsigned int k ;
  1196. double memory = 0.0 ;
  1197. /* Calculate the smoothed sample-to-sample difference. */
  1198. for (k = 0 ; k < datalen - 1 ; k++)
  1199. { memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
  1200. data [k] = memory ;
  1201. } ;
  1202. data [datalen-1] = data [datalen-2] ;
  1203. } /* smoothed_diff_double */