pcm_test.tpl 30 KB

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