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

Audio

开发平台:

Unix_Linux

  1. [+ AutoGen5 template c +]
  2. /*
  3. ** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  4. **
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation; either version 2 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. #include "sfconfig.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <math.h>
  24. #if HAVE_UNISTD_H
  25. #include <unistd.h>
  26. #endif
  27. #include <sndfile.h>
  28. #include "utils.h"
  29. #define BUFFER_SIZE (1<<12)
  30. static void lrintf_test (void) ;
  31. [+ FOR data_type
  32. +]static void pcm_test_[+ (get "name") +] (const char *filename, int filetype, uint64_t hash) ;
  33. [+ ENDFOR data_type
  34. +]
  35. static void pcm_test_float (const char *filename, int filetype, uint64_t hash, int replace_float) ;
  36. static void pcm_test_double (const char *filename, int filetype, uint64_t hash, int replace_float) ;
  37. typedef union
  38. { double d [BUFFER_SIZE + 1] ;
  39. float f [BUFFER_SIZE + 1] ;
  40. int i [BUFFER_SIZE + 1] ;
  41. short s [BUFFER_SIZE + 1] ;
  42. } BUFFER ;
  43. /* Data written to the file. */
  44. static BUFFER data_out ;
  45. /* Data read back from the file. */
  46. static BUFFER data_in ;
  47. int
  48. main (void)
  49. {
  50. lrintf_test () ;
  51. pcm_test_bits_8 ("pcm-s8.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_S8, 0x1cda335091249dbfLL) ;
  52. pcm_test_bits_8 ("pcm-u8.raw", SF_FORMAT_RAW | SF_FORMAT_PCM_U8, 0x7f748c433d695f3fLL) ;
  53. pcm_test_bits_16 ("le-pcm16.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_16, 0x3a2b956c881ebf08LL) ;
  54. pcm_test_bits_16 ("be-pcm16.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_16, 0xd9e2f840c55750f8LL) ;
  55. pcm_test_bits_24 ("le-pcm24.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_24, 0x933b6a759ab496f8LL) ;
  56. pcm_test_bits_24 ("be-pcm24.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_24, 0xbb1f3eaf9c30b6f8LL) ;
  57. pcm_test_bits_32 ("le-pcm32.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_32, 0xa77aece1c1c17f08LL) ;
  58. pcm_test_bits_32 ("be-pcm32.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_32, 0x3099ddf142d0b0f8LL) ;
  59. /* Lite remove start */
  60. pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x3c2ad04f7554267aLL, SF_FALSE) ;
  61. pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x074de3e248fa9186LL, SF_FALSE) ;
  62. pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xc682726f958f669cLL, SF_FALSE) ;
  63. pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xd9a3583f8ee51164LL, SF_FALSE) ;
  64. pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x3c2ad04f7554267aLL, SF_TRUE) ;
  65. pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x074de3e248fa9186LL, SF_TRUE) ;
  66. pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xc682726f958f669cLL, SF_TRUE) ;
  67. pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xd9a3583f8ee51164LL, SF_TRUE) ;
  68. /* Lite remove end */
  69. return 0 ;
  70. } /* main */
  71. /*============================================================================================
  72. ** Here are the test functions.
  73. */
  74. static void
  75. lrintf_test (void)
  76. { int k, items ;
  77. float *float_data ;
  78. int *int_data ;
  79. print_test_name ("lrintf_test", "") ;
  80. items = 1024 ;
  81. float_data = data_out.f ;
  82. int_data = data_in.i ;
  83. for (k = 0 ; k < items ; k++)
  84. float_data [k] = (k * ((k % 2) ? 333333.0 : -333333.0)) ;
  85. for (k = 0 ; k < items ; k++)
  86. int_data [k] = lrintf (float_data [k]) ;
  87. for (k = 0 ; k < items ; k++)
  88. if (fabs (int_data [k] - float_data [k]) > 1.0)
  89. { printf ("nnLine %d: float : Incorrect sample (#%d : %f => %d).n", __LINE__, k, float_data [k], int_data [k]) ;
  90. exit (1) ;
  91. } ;
  92. printf ("okn") ;
  93. } /* lrintf_test */
  94. [+ FOR data_type
  95. +]static void
  96. pcm_test_[+ (get "name") +] (const char *filename, int filetype, uint64_t hash)
  97. { SNDFILE *file ;
  98. SF_INFO sfinfo ;
  99. int k, items, zero_count ;
  100. short *short_out, *short_in ;
  101. int *int_out, *int_in ;
  102. /* Lite remove start */
  103. float *float_out, *float_in ;
  104. double *double_out, *double_in ;
  105. /* Lite remove end */
  106. print_test_name ("pcm_test_[+ (get "name") +]", filename) ;
  107. items = [+ (get "item_count") +] ;
  108. short_out = data_out.s ;
  109. short_in = data_in.s ;
  110. zero_count = 0 ;
  111. for (k = 0 ; k < items ; k++)
  112. { short_out [k] = [+ (get "short_func") +] ;
  113. zero_count = short_out [k] ? zero_count : zero_count + 1 ;
  114. } ;
  115. if (zero_count > items / 4)
  116. { printf ("nnLine %d: too many zeros.n", __LINE__) ;
  117. exit (1) ;
  118. } ;
  119. sfinfo.samplerate = 44100 ;
  120. sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
  121. sfinfo.channels = 1 ;
  122. sfinfo.format = filetype ;
  123. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  124. test_write_short_or_die (file, 0, short_out, items, __LINE__) ;
  125. sf_close (file) ;
  126. memset (short_in, 0, items * sizeof (short)) ;
  127. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  128. if (sfinfo.format != filetype)
  129. { printf ("nnLine %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, filetype, sfinfo.format) ;
  130. exit (1) ;
  131. } ;
  132. if (sfinfo.frames != items)
  133. { printf ("nnLine %d: Incorrect number of frames in file. (%d => %ld)n", __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  134. exit (1) ;
  135. } ;
  136. if (sfinfo.channels != 1)
  137. { printf ("nnLine %d: Incorrect number of channels in file.n", __LINE__) ;
  138. exit (1) ;
  139. } ;
  140. check_log_buffer_or_die (file, __LINE__) ;
  141. test_read_short_or_die (file, 0, short_in, items, __LINE__) ;
  142. for (k = 0 ; k < items ; k++)
  143. if (short_out [k] != short_in [k])
  144. { printf ("nnLine %d: Incorrect sample (#%d : 0x%x => 0x%x).n", __LINE__, k, short_out [k], short_in [k]) ;
  145. exit (1) ;
  146. } ;
  147. sf_close (file) ;
  148. /* Finally, check the file hash. */
  149. check_file_hash_or_die (filename, hash, __LINE__) ;
  150. /*--------------------------------------------------------------------------
  151. ** Test sf_read/write_int ()
  152. */
  153. zero_count = 0 ;
  154. int_out = data_out.i ;
  155. int_in = data_in.i ;
  156. for (k = 0 ; k < items ; k++)
  157. { int_out [k] = [+ (get "int_func") +] ;
  158. zero_count = int_out [k] ? zero_count : zero_count + 1 ;
  159. } ;
  160. if (zero_count > items / 4)
  161. { printf ("nnLine %d: too many zeros.n", __LINE__) ;
  162. exit (1) ;
  163. } ;
  164. sfinfo.samplerate = 44100 ;
  165. sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
  166. sfinfo.channels = 1 ;
  167. sfinfo.format = filetype ;
  168. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  169. test_write_int_or_die (file, 0, int_out, items, __LINE__) ;
  170. sf_close (file) ;
  171. memset (int_in, 0, items * sizeof (int)) ;
  172. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  173. if (sfinfo.format != filetype)
  174. { printf ("nnLine %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, filetype, sfinfo.format) ;
  175. exit (1) ;
  176. } ;
  177. if (sfinfo.frames != items)
  178. { printf ("nnLine %d: Incorrect number of frames in file. (%d => %ld)n", __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  179. exit (1) ;
  180. } ;
  181. if (sfinfo.channels != 1)
  182. { printf ("nnLine %d: Incorrect number of channels in file.n", __LINE__) ;
  183. exit (1) ;
  184. } ;
  185. check_log_buffer_or_die (file, __LINE__) ;
  186. test_read_int_or_die (file, 0, int_in, items, __LINE__) ;
  187. for (k = 0 ; k < items ; k++)
  188. if (int_out [k] != int_in [k])
  189. { printf ("nnLine %d: int : Incorrect sample (#%d : 0x%x => 0x%x).n", __LINE__, k, int_out [k], int_in [k]) ;
  190. exit (1) ;
  191. } ;
  192. sf_close (file) ;
  193. /* Lite remove start */
  194. /*--------------------------------------------------------------------------
  195. ** Test sf_read/write_float ()
  196. */
  197. zero_count = 0 ;
  198. float_out = data_out.f ;
  199. float_in = data_in.f ;
  200. for (k = 0 ; k < items ; k++)
  201. { float_out [k] = [+ (get "float_func") +] ;
  202. zero_count = (fabs (float_out [k]) > 1e-10) ? zero_count : zero_count + 1 ;
  203. } ;
  204. if (zero_count > items / 4)
  205. { printf ("nnLine %d: too many zeros (%d/%d).n", __LINE__, zero_count, items) ;
  206. exit (1) ;
  207. } ;
  208. sfinfo.samplerate = 44100 ;
  209. sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
  210. sfinfo.channels = 1 ;
  211. sfinfo.format = filetype ;
  212. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  213. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  214. test_write_float_or_die (file, 0, float_out, items, __LINE__) ;
  215. sf_close (file) ;
  216. memset (float_in, 0, items * sizeof (float)) ;
  217. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  218. if (sfinfo.format != filetype)
  219. { printf ("nnLine %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, filetype, sfinfo.format) ;
  220. exit (1) ;
  221. } ;
  222. if (sfinfo.frames != items)
  223. { printf ("nnLine %d: Incorrect number of frames in file. (%d => %ld)n", __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  224. exit (1) ;
  225. } ;
  226. if (sfinfo.channels != 1)
  227. { printf ("nnLine %d: Incorrect number of channels in file.n", __LINE__) ;
  228. exit (1) ;
  229. } ;
  230. check_log_buffer_or_die (file, __LINE__) ;
  231. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  232. test_read_float_or_die (file, 0, float_in, items, __LINE__) ;
  233. for (k = 0 ; k < items ; k++)
  234. if (fabs (float_out [k] - float_in [k]) > 1e-10)
  235. { printf ("nnLine %d: float : Incorrect sample (#%d : %f => %f).n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
  236. exit (1) ;
  237. break ;
  238. } ;
  239. sf_close (file) ;
  240. /*--------------------------------------------------------------------------
  241. ** Test sf_read/write_double ()
  242. */
  243. zero_count = 0 ;
  244. double_out = data_out.d ;
  245. double_in = data_in.d ;
  246. for (k = 0 ; k < items ; k++)
  247. { double_out [k] = [+ (get "float_func") +] ;
  248. zero_count = (fabs (double_out [k]) > 1e-10) ? zero_count : zero_count + 1 ;
  249. } ;
  250. if (zero_count > items / 4)
  251. { printf ("nnLine %d: too many zeros (%d/%d).n", __LINE__, zero_count, items) ;
  252. exit (1) ;
  253. } ;
  254. sfinfo.samplerate = 44100 ;
  255. sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
  256. sfinfo.channels = 1 ;
  257. sfinfo.format = filetype ;
  258. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  259. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  260. test_write_double_or_die (file, 0, double_out, items, __LINE__) ;
  261. sf_close (file) ;
  262. memset (double_in, 0, items * sizeof (double)) ;
  263. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  264. if (sfinfo.format != filetype)
  265. { printf ("nnLine %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, filetype, sfinfo.format) ;
  266. exit (1) ;
  267. } ;
  268. if (sfinfo.frames != items)
  269. { printf ("nnLine %d: Incorrect number of frames in file. (%d => %ld)n", __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  270. exit (1) ;
  271. } ;
  272. if (sfinfo.channels != 1)
  273. { printf ("nnLine %d: Incorrect number of channels in file.n", __LINE__) ;
  274. exit (1) ;
  275. } ;
  276. check_log_buffer_or_die (file, __LINE__) ;
  277. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  278. test_read_double_or_die (file, 0, double_in, items, __LINE__) ;
  279. for (k = 0 ; k < items ; k++)
  280. if (fabs (double_out [k] - double_in [k]) > 1e-10)
  281. { printf ("nnLine %d: double : Incorrect sample (#%d : %f => %f).n", __LINE__, k, double_out [k], double_in [k]) ;
  282. exit (1) ;
  283. } ;
  284. sf_close (file) ;
  285. /* Lite remove end */
  286. unlink (filename) ;
  287. puts ("ok") ;
  288. } /* pcm_test_[+ (get "name") +] */
  289. [+ ENDFOR data_type
  290. +]
  291. /*==============================================================================
  292. */
  293. static void
  294. pcm_test_float (const char *filename, int filetype, uint64_t hash, int replace_float)
  295. { SNDFILE *file ;
  296. SF_INFO sfinfo ;
  297. int k, items, frames ;
  298. int sign ;
  299. double *data, error ;
  300. print_test_name (replace_float ?  "pcm_test_float (replace)" : "pcm_test_float", filename) ;
  301. items = BUFFER_SIZE ;
  302. data = data_out.d ;
  303. for (sign = 1, k = 0 ; k < items ; k++)
  304. { data [k] = ((double) (k * sign)) / 100.0 ;
  305. sign = (sign > 0) ? -1 : 1 ;
  306. } ;
  307. sfinfo.samplerate = 44100 ;
  308. sfinfo.frames = items ;
  309. sfinfo.channels = 1 ;
  310. sfinfo.format = filetype ;
  311. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  312. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  313. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  314. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  315. dump_log_buffer (file) ;
  316. exit (1) ;
  317. } ;
  318. test_write_double_or_die (file, 0, data, items, __LINE__) ;
  319. sf_close (file) ;
  320. check_file_hash_or_die (filename, hash, __LINE__) ;
  321. memset (data, 0, items * sizeof (double)) ;
  322. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  323. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  324. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  325. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  326. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  327. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  328. dump_log_buffer (file) ;
  329. exit (1) ;
  330. } ;
  331. if (sfinfo.format != filetype)
  332. { printf ("nnError (%s:%d) Mono : Returned format incorrect (0x%08X => 0x%08X).n", __FILE__, __LINE__, filetype, sfinfo.format) ;
  333. exit (1) ;
  334. } ;
  335. if (sfinfo.frames != items)
  336. { printf ("nnError (%s:%d) Mono : Incorrect number of frames in file. (%d => %ld)n", __FILE__, __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  337. exit (1) ;
  338. } ;
  339. if (sfinfo.channels != 1)
  340. { printf ("nnError (%s:%d) Mono : Incorrect number of channels in file.n", __FILE__, __LINE__) ;
  341. exit (1) ;
  342. } ;
  343. check_log_buffer_or_die (file, __LINE__) ;
  344. test_read_double_or_die (file, 0, data, items, __LINE__) ;
  345. for (sign = -1, k = 0 ; k < items ; k++)
  346. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  347. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  348. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  349. exit (1) ;
  350. } ;
  351. } ;
  352. /* Seek to start of file. */
  353. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  354. test_read_double_or_die (file, 0, data, 4, __LINE__) ;
  355. for (k = 0 ; k < 4 ; k++)
  356. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  357. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  358. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  359. exit (1) ;
  360. } ;
  361. } ;
  362. /* Seek to offset from start of file. */
  363. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  364. test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
  365. for (k = 10 ; k < 14 ; k++)
  366. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  367. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  368. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  369. exit (1) ;
  370. } ;
  371. } ;
  372. /* Seek to offset from current position. */
  373. test_seek_or_die (file, 6, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  374. test_read_double_or_die (file, 0, data + 20, 4, __LINE__) ;
  375. for (k = 20 ; k < 24 ; k++)
  376. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  377. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  378. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  379. exit (1) ;
  380. } ;
  381. } ;
  382. /* Seek to offset from end of file. */
  383. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  384. test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
  385. for (k = 10 ; k < 14 ; k++)
  386. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  387. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  388. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  389. exit (1) ;
  390. } ;
  391. } ;
  392. sf_close (file) ;
  393. /* Now test Stereo. */
  394. if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_SVX) /* SVX is mono only */
  395. { printf ("okn") ;
  396. return ;
  397. } ;
  398. items = BUFFER_SIZE ;
  399. data = data_out.d ;
  400. for (sign = -1, k = 0 ; k < items ; k++)
  401. data [k] = ((double) k) / 100.0 * (sign *= -1) ;
  402. sfinfo.samplerate = 44100 ;
  403. sfinfo.frames = items ;
  404. sfinfo.channels = 2 ;
  405. sfinfo.format = filetype ;
  406. frames = items / sfinfo.channels ;
  407. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  408. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  409. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  410. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  411. dump_log_buffer (file) ;
  412. exit (1) ;
  413. } ;
  414. test_writef_double_or_die (file, 0, data, frames, __LINE__) ;
  415. sf_close (file) ;
  416. check_file_hash_or_die (filename, hash, __LINE__) ;
  417. memset (data, 0, items * sizeof (double)) ;
  418. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  419. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  420. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  421. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  422. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  423. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  424. dump_log_buffer (file) ;
  425. exit (1) ;
  426. } ;
  427. if (sfinfo.format != filetype)
  428. { printf ("nnError (%s:%d) Stereo : Returned format incorrect (0x%08X => 0x%08X).n", __FILE__, __LINE__, filetype, sfinfo.format) ;
  429. exit (1) ;
  430. } ;
  431. if (sfinfo.frames != frames)
  432. { printf ("nnError (%s:%d) Stereo : Incorrect number of frames in file. (%d => %ld)n", __FILE__, __LINE__, frames, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  433. exit (1) ;
  434. } ;
  435. if (sfinfo.channels != 2)
  436. { printf ("nnError (%s:%d) Stereo : Incorrect number of channels in file.n", __FILE__, __LINE__) ;
  437. exit (1) ;
  438. } ;
  439. check_log_buffer_or_die (file, __LINE__) ;
  440. test_readf_double_or_die (file, 0, data, frames, __LINE__) ;
  441. for (sign = -1, k = 0 ; k < items ; k++)
  442. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  443. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  444. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  445. exit (1) ;
  446. } ;
  447. } ;
  448. /* Seek to start of file. */
  449. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  450. test_readf_double_or_die (file, 0, data, 4, __LINE__) ;
  451. for (k = 0 ; k < 4 ; k++)
  452. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  453. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  454. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  455. exit (1) ;
  456. } ;
  457. } ;
  458. /* Seek to offset from start of file. */
  459. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  460. test_readf_double_or_die (file, 0, data + 20, 2, __LINE__) ;
  461. for (k = 20 ; k < 24 ; k++)
  462. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  463. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  464. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  465. exit (1) ;
  466. } ;
  467. } ;
  468. /* Seek to offset from current position. */
  469. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  470. test_readf_double_or_die (file, 0, data + 40, 2, __LINE__) ;
  471. for (k = 40 ; k < 44 ; k++)
  472. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  473. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  474. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  475. exit (1) ;
  476. } ;
  477. } ;
  478. /* Seek to offset from end of file. */
  479. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  480. test_readf_double_or_die (file, 0, data + 20, 2, __LINE__) ;
  481. for (k = 20 ; k < 24 ; k++)
  482. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  483. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  484. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  485. exit (1) ;
  486. } ;
  487. } ;
  488. sf_close (file) ;
  489. printf ("okn") ;
  490. unlink (filename) ;
  491. } /* pcm_test_float */
  492. static void
  493. pcm_test_double (const char *filename, int filetype, uint64_t hash, int replace_float)
  494. { SNDFILE *file ;
  495. SF_INFO sfinfo ;
  496. int k, items, frames ;
  497. int sign ;
  498. double *data, error ;
  499. /* This is the best test routine. Other should be brought up to this standard. */
  500. print_test_name (replace_float ?  "pcm_test_double (replace)" : "pcm_test_double", filename) ;
  501. items = BUFFER_SIZE ;
  502. data = data_out.d ;
  503. for (sign = 1, k = 0 ; k < items ; k++)
  504. { data [k] = ((double) (k * sign)) / 100.0 ;
  505. sign = (sign > 0) ? -1 : 1 ;
  506. } ;
  507. sfinfo.samplerate = 44100 ;
  508. sfinfo.frames = items ;
  509. sfinfo.channels = 1 ;
  510. sfinfo.format = filetype ;
  511. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  512. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  513. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  514. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  515. dump_log_buffer (file) ;
  516. exit (1) ;
  517. } ;
  518. test_write_double_or_die (file, 0, data, items, __LINE__) ;
  519. sf_close (file) ;
  520. #if (defined (WIN32) || defined (_WIN32))
  521. /* File hashing on Win32 fails due to slighty different
  522. ** calculated values of the sin() function.
  523. */
  524. hash = hash ; /* Avoid compiler warning. */
  525. #else
  526. check_file_hash_or_die (filename, hash, __LINE__) ;
  527. #endif
  528. memset (data, 0, items * sizeof (double)) ;
  529. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  530. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  531. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  532. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  533. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  534. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  535. dump_log_buffer (file) ;
  536. exit (1) ;
  537. } ;
  538. if (sfinfo.format != filetype)
  539. { printf ("nnError (%s:%d) Mono : Returned format incorrect (0x%08X => 0x%08X).n", __FILE__, __LINE__, filetype, sfinfo.format) ;
  540. exit (1) ;
  541. } ;
  542. if (sfinfo.frames != items)
  543. { printf ("nnError (%s:%d) Mono : Incorrect number of frames in file. (%d => %ld)n", __FILE__, __LINE__, items, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  544. exit (1) ;
  545. } ;
  546. if (sfinfo.channels != 1)
  547. { printf ("nnError (%s:%d) Mono : Incorrect number of channels in file.n", __FILE__, __LINE__) ;
  548. exit (1) ;
  549. } ;
  550. check_log_buffer_or_die (file, __LINE__) ;
  551. test_read_double_or_die (file, 0, data, items, __LINE__) ;
  552. for (sign = -1, k = 0 ; k < items ; k++)
  553. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  554. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  555. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  556. exit (1) ;
  557. } ;
  558. } ;
  559. /* Seek to start of file. */
  560. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  561. test_read_double_or_die (file, 0, data, 4, __LINE__) ;
  562. for (k = 0 ; k < 4 ; k++)
  563. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  564. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  565. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  566. exit (1) ;
  567. } ;
  568. } ;
  569. /* Seek to offset from start of file. */
  570. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  571. test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
  572. test_seek_or_die (file, 0, SEEK_CUR, 14, sfinfo.channels, __LINE__) ;
  573. for (k = 10 ; k < 14 ; k++)
  574. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  575. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  576. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  577. exit (1) ;
  578. } ;
  579. } ;
  580. /* Seek to offset from current position. */
  581. test_seek_or_die (file, 6, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  582. test_read_double_or_die (file, 0, data + 20, 4, __LINE__) ;
  583. for (k = 20 ; k < 24 ; k++)
  584. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  585. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  586. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  587. exit (1) ;
  588. } ;
  589. } ;
  590. /* Seek to offset from end of file. */
  591. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  592. test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
  593. for (k = 10 ; k < 14 ; k++)
  594. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  595. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  596. { printf ("nnError (%s:%d) Mono : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  597. exit (1) ;
  598. } ;
  599. } ;
  600. sf_close (file) ;
  601. /* Now test Stereo. */
  602. if ((filetype & SF_FORMAT_TYPEMASK) == SF_FORMAT_SVX) /* SVX is mono only */
  603. { printf ("okn") ;
  604. return ;
  605. } ;
  606. items = BUFFER_SIZE ;
  607. data = data_out.d ;
  608. for (sign = -1, k = 0 ; k < items ; k++)
  609. data [k] = ((double) k) / 100.0 * (sign *= -1) ;
  610. sfinfo.samplerate = 44100 ;
  611. sfinfo.frames = items ;
  612. sfinfo.channels = 2 ;
  613. sfinfo.format = filetype ;
  614. frames = items / sfinfo.channels ;
  615. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  616. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  617. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  618. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  619. dump_log_buffer (file) ;
  620. exit (1) ;
  621. } ;
  622. test_writef_double_or_die (file, 0, data, frames, __LINE__) ;
  623. sf_close (file) ;
  624. #if (defined (WIN32) || defined (_WIN32))
  625. /* File hashing on Win32 fails due to slighty different
  626. ** calculated values.
  627. */
  628. hash = hash ; /* Avoid compiler warning. */
  629. #else
  630. check_file_hash_or_die (filename, hash, __LINE__) ;
  631. #endif
  632. memset (data, 0, items * sizeof (double)) ;
  633. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  634. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  635. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
  636. sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
  637. if (replace_float && string_in_log_buffer (file, "Using IEEE replacement") == 0)
  638. { printf ("nnLine %d : Float replacement code not working.nn", __LINE__) ;
  639. dump_log_buffer (file) ;
  640. exit (1) ;
  641. } ;
  642. if (sfinfo.format != filetype)
  643. { printf ("nnError (%s:%d) Stereo : Returned format incorrect (0x%08X => 0x%08X).n", __FILE__, __LINE__, filetype, sfinfo.format) ;
  644. exit (1) ;
  645. } ;
  646. if (sfinfo.frames != frames)
  647. { printf ("nnError (%s:%d) Stereo : Incorrect number of frames in file. (%d => %ld)n", __FILE__, __LINE__, frames, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  648. exit (1) ;
  649. } ;
  650. if (sfinfo.channels != 2)
  651. { printf ("nnError (%s:%d) Stereo : Incorrect number of channels in file.n", __FILE__, __LINE__) ;
  652. exit (1) ;
  653. } ;
  654. check_log_buffer_or_die (file, __LINE__) ;
  655. test_readf_double_or_die (file, 0, data, frames, __LINE__) ;
  656. for (sign = -1, k = 0 ; k < items ; k++)
  657. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  658. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  659. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  660. exit (1) ;
  661. } ;
  662. } ;
  663. /* Seek to start of file. */
  664. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  665. test_read_double_or_die (file, 0, data, 4, __LINE__) ;
  666. for (k = 0 ; k < 4 ; k++)
  667. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  668. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  669. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  670. exit (1) ;
  671. } ;
  672. } ;
  673. /* Seek to offset from start of file. */
  674. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  675. test_read_double_or_die (file, 0, data + 10, 4, __LINE__) ;
  676. for (k = 20 ; k < 24 ; k++)
  677. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  678. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  679. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  680. exit (1) ;
  681. } ;
  682. } ;
  683. /* Seek to offset from current position. */
  684. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  685. test_readf_double_or_die (file, 0, data + 40, 4, __LINE__) ;
  686. for (k = 40 ; k < 44 ; k++)
  687. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  688. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  689. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  690. exit (1) ;
  691. } ;
  692. } ;
  693. /* Seek to offset from end of file. */
  694. test_seek_or_die (file, -1 * (sfinfo.frames -10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  695. test_readf_double_or_die (file, 0, data + 20, 4, __LINE__) ;
  696. for (k = 20 ; k < 24 ; k++)
  697. { error = fabs (data [k] - ((double) k) / 100.0 * (sign *= -1)) ;
  698. if (fabs (data [k]) > 1e-100 && fabs (error / data [k]) > 1e-5)
  699. { printf ("nnError (%s:%d) Stereo : Incorrect sample (#%d : %f => %f).n", __FILE__, __LINE__, k, ((double) k) / 100.0, data [k]) ;
  700. exit (1) ;
  701. } ;
  702. } ;
  703. sf_close (file) ;
  704. printf ("okn") ;
  705. unlink (filename) ;
  706. } /* pcm_test_double */
  707. /*==============================================================================
  708. */