pcm_test.tpl 30 KB

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