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

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #if HAVE_UNISTD_H
  23. #include <unistd.h>
  24. #endif
  25. #include <math.h>
  26. #if (defined (WIN32) || defined (_WIN32))
  27. #include <fcntl.h>
  28. static int truncate (const char *filename, int ignored) ;
  29. #endif
  30. #include <sndfile.h>
  31. #include "utils.h"
  32. #include "generate.h"
  33. #define SAMPLE_RATE 11025
  34. #define DATA_LENGTH (1<<12)
  35. #define SILLY_WRITE_COUNT (234)
  36. static void pcm_test_char (const char *str, int format, int long_file_okz) ;
  37. static void pcm_test_short (const char *str, int format, int long_file_okz) ;
  38. static void pcm_test_24bit (const char *str, int format, int long_file_okz) ;
  39. static void pcm_test_int (const char *str, int format, int long_file_okz) ;
  40. static void pcm_test_float (const char *str, int format, int long_file_okz) ;
  41. static void pcm_test_double (const char *str, int format, int long_file_okz) ;
  42. static void empty_file_test (const char *filename, int format) ;
  43. typedef union
  44. { double d [DATA_LENGTH] ;
  45. float f [DATA_LENGTH] ;
  46. int i [DATA_LENGTH] ;
  47. short s [DATA_LENGTH] ;
  48. char c [DATA_LENGTH] ;
  49. } BUFFER ;
  50. static BUFFER orig_data ;
  51. static BUFFER test_data ;
  52. int
  53. main (int argc, char **argv)
  54. { int do_all = 0 ;
  55. int test_count = 0 ;
  56. count_open_files () ;
  57. if (argc != 2)
  58. { printf ("Usage : %s <test>n", argv [0]) ;
  59. printf ("    Where <test> is one of the following:n") ;
  60. printf ("           wav   - test WAV file functions (little endian)n") ;
  61. printf ("           aiff  - test AIFF file functions (big endian)n") ;
  62. printf ("           au    - test AU file functionsn") ;
  63. printf ("           avr   - test AVR file functionsn") ;
  64. printf ("           caf   - test CAF file functionsn") ;
  65. printf ("           raw   - test RAW header-less PCM file functionsn") ;
  66. printf ("           paf   - test PAF file functionsn") ;
  67. printf ("           svx   - test 8SVX/16SV file functionsn") ;
  68. printf ("           nist  - test NIST Sphere file functionsn") ;
  69. printf ("           ircam - test IRCAM file functionsn") ;
  70. printf ("           voc   - Create Voice file functionsn") ;
  71. printf ("           w64   - Sonic Foundry's W64 file functionsn") ;
  72. printf ("           flac  - test FLAC file functionsn") ;
  73. printf ("           mpc2k - test MPC 2000 file functionsn") ;
  74. printf ("           rf64  - test RF64 file functionsn") ;
  75. printf ("           all   - perform all testsn") ;
  76. exit (1) ;
  77. } ;
  78. do_all = !strcmp (argv [1], "all") ;
  79. if (do_all || ! strcmp (argv [1], "wav"))
  80. { pcm_test_char ("char.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_U8, SF_FALSE) ;
  81. pcm_test_short ("short.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_16, SF_FALSE) ;
  82. pcm_test_24bit ("24bit.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_24, SF_FALSE) ;
  83. pcm_test_int ("int.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_32, SF_FALSE) ;
  84. pcm_test_char ("char.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_U8, SF_FALSE) ;
  85. pcm_test_short ("short.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16, SF_FALSE) ;
  86. pcm_test_24bit ("24bit.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_24, SF_FALSE) ;
  87. pcm_test_int ("int.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_32, SF_FALSE) ;
  88. pcm_test_24bit ("24bit.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_PCM_24, SF_FALSE) ;
  89. pcm_test_int ("int.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_PCM_32, SF_FALSE) ;
  90. /* Lite remove start */
  91. pcm_test_float ("float.wav" , SF_FORMAT_WAV | SF_FORMAT_FLOAT , SF_FALSE) ;
  92. pcm_test_double ("double.wav" , SF_FORMAT_WAV | SF_FORMAT_DOUBLE, SF_FALSE) ;
  93. pcm_test_float ("float.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_FLOAT , SF_FALSE) ;
  94. pcm_test_double ("double.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_DOUBLE, SF_FALSE) ;
  95. pcm_test_float ("float.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_FLOAT , SF_FALSE) ;
  96. pcm_test_double ("double.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_DOUBLE, SF_FALSE) ;
  97. /* Lite remove end */
  98. empty_file_test ("empty_char.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8) ;
  99. empty_file_test ("empty_short.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
  100. empty_file_test ("empty_float.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT) ;
  101. test_count++ ;
  102. } ;
  103. if (do_all || ! strcmp (argv [1], "aiff"))
  104. { pcm_test_char ("char_u8.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_U8, SF_FALSE) ;
  105. pcm_test_char ("char_s8.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_S8, SF_FALSE) ;
  106. pcm_test_short ("short.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
  107. pcm_test_24bit ("24bit.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
  108. pcm_test_int ("int.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
  109. pcm_test_short ("short_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
  110. pcm_test_24bit ("24bit_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
  111. pcm_test_int ("int_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
  112. pcm_test_short ("short_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
  113. pcm_test_24bit ("24bit_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
  114. pcm_test_int ("int_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
  115. /* Lite remove start */
  116. pcm_test_short ("dwvw16.aifc", SF_FORMAT_AIFF | SF_FORMAT_DWVW_16, SF_TRUE) ;
  117. pcm_test_24bit ("dwvw24.aifc", SF_FORMAT_AIFF | SF_FORMAT_DWVW_24, SF_TRUE) ;
  118. pcm_test_float ("float.aifc" , SF_FORMAT_AIFF | SF_FORMAT_FLOAT , SF_FALSE) ;
  119. pcm_test_double ("double.aifc" , SF_FORMAT_AIFF | SF_FORMAT_DOUBLE, SF_FALSE) ;
  120. /* Lite remove end */
  121. empty_file_test ("empty_char.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_U8) ;
  122. empty_file_test ("empty_short.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
  123. empty_file_test ("empty_float.aiff", SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ;
  124. test_count++ ;
  125. } ;
  126. if (do_all || ! strcmp (argv [1], "au"))
  127. { pcm_test_char ("char.au" , SF_FORMAT_AU | SF_FORMAT_PCM_S8, SF_FALSE) ;
  128. pcm_test_short ("short.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16, SF_FALSE) ;
  129. pcm_test_24bit ("24bit.au" , SF_FORMAT_AU | SF_FORMAT_PCM_24, SF_FALSE) ;
  130. pcm_test_int ("int.au" , SF_FORMAT_AU | SF_FORMAT_PCM_32, SF_FALSE) ;
  131. /* Lite remove start */
  132. pcm_test_float ("float.au" , SF_FORMAT_AU | SF_FORMAT_FLOAT , SF_FALSE) ;
  133. pcm_test_double ("double.au", SF_FORMAT_AU | SF_FORMAT_DOUBLE, SF_FALSE) ;
  134. /* Lite remove end */
  135. pcm_test_char ("char_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_S8, SF_FALSE) ;
  136. pcm_test_short ("short_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_16, SF_FALSE) ;
  137. pcm_test_24bit ("24bit_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_24, SF_FALSE) ;
  138. pcm_test_int ("int_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_32, SF_FALSE) ;
  139. /* Lite remove start */
  140. pcm_test_float ("float_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_FLOAT , SF_FALSE) ;
  141. pcm_test_double ("double_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_DOUBLE, SF_FALSE) ;
  142. /* Lite remove end */
  143. test_count++ ;
  144. } ;
  145. if (do_all || ! strcmp (argv [1], "caf"))
  146. { pcm_test_char ("char.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
  147. pcm_test_short ("short.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16, SF_FALSE) ;
  148. pcm_test_24bit ("24bit.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_24, SF_FALSE) ;
  149. pcm_test_int ("int.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_32, SF_FALSE) ;
  150. /* Lite remove start */
  151. pcm_test_float ("float.caf" , SF_FORMAT_CAF | SF_FORMAT_FLOAT , SF_FALSE) ;
  152. pcm_test_double ("double.caf" , SF_FORMAT_CAF | SF_FORMAT_DOUBLE, SF_FALSE) ;
  153. /* Lite remove end */
  154. pcm_test_short ("short_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_16, SF_FALSE) ;
  155. pcm_test_24bit ("24bit_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_24, SF_FALSE) ;
  156. pcm_test_int ("int_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_32, SF_FALSE) ;
  157. /* Lite remove start */
  158. pcm_test_float ("float_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_FLOAT , SF_FALSE) ;
  159. pcm_test_double ("double_le.caf", SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_DOUBLE, SF_FALSE) ;
  160. /* Lite remove end */
  161. test_count++ ;
  162. } ;
  163. if (do_all || ! strcmp (argv [1], "raw"))
  164. { pcm_test_char ("char_s8.raw" , SF_FORMAT_RAW | SF_FORMAT_PCM_S8, SF_FALSE) ;
  165. pcm_test_char ("char_u8.raw" , SF_FORMAT_RAW | SF_FORMAT_PCM_U8, SF_FALSE) ;
  166. pcm_test_short ("short_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_16, SF_FALSE) ;
  167. pcm_test_short ("short_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_16, SF_FALSE) ;
  168. pcm_test_24bit ("24bit_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_24, SF_FALSE) ;
  169. pcm_test_24bit ("24bit_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_24, SF_FALSE) ;
  170. pcm_test_int ("int_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_32, SF_FALSE) ;
  171. pcm_test_int ("int_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_32, SF_FALSE) ;
  172. /* Lite remove start */
  173. pcm_test_float ("float_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT , SF_FALSE) ;
  174. pcm_test_float ("float_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT , SF_FALSE) ;
  175. pcm_test_double ("double_le.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, SF_FALSE) ;
  176. pcm_test_double ("double_be.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, SF_FALSE) ;
  177. /* Lite remove end */
  178. test_count++ ;
  179. } ;
  180. /* Lite remove start */
  181. if (do_all || ! strcmp (argv [1], "paf"))
  182. { pcm_test_char ("char_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
  183. pcm_test_char ("char_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
  184. pcm_test_short ("short_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_16, SF_FALSE) ;
  185. pcm_test_short ("short_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_16, SF_FALSE) ;
  186. pcm_test_24bit ("24bit_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_24, SF_TRUE) ;
  187. pcm_test_24bit ("24bit_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_24, SF_TRUE) ;
  188. test_count++ ;
  189. } ;
  190. if (do_all || ! strcmp (argv [1], "svx"))
  191. { pcm_test_char ("char.svx" , SF_FORMAT_SVX | SF_FORMAT_PCM_S8, SF_FALSE) ;
  192. pcm_test_short ("short.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_16, SF_FALSE) ;
  193. empty_file_test ("empty_char.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_S8) ;
  194. empty_file_test ("empty_short.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_16) ;
  195. test_count++ ;
  196. } ;
  197. if (do_all || ! strcmp (argv [1], "nist"))
  198. { pcm_test_short ("short_le.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_16, SF_FALSE) ;
  199. pcm_test_short ("short_be.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_16, SF_FALSE) ;
  200. pcm_test_24bit ("24bit_le.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_24, SF_FALSE) ;
  201. pcm_test_24bit ("24bit_be.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_24, SF_FALSE) ;
  202. pcm_test_int ("int_le.nist" , SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_32, SF_FALSE) ;
  203. pcm_test_int  ("int_be.nist" , SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_32, SF_FALSE) ;
  204. test_count++ ;
  205. } ;
  206. if (do_all || ! strcmp (argv [1], "ircam"))
  207. { pcm_test_short ("short_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_PCM_16, SF_FALSE) ;
  208. pcm_test_short ("short_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_PCM_16, SF_FALSE) ;
  209. pcm_test_int ("int_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_PCM_32, SF_FALSE) ;
  210. pcm_test_int  ("int_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_PCM_32, SF_FALSE) ;
  211. pcm_test_float ("float_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_FLOAT , SF_FALSE) ;
  212. pcm_test_float ("float_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_FLOAT , SF_FALSE) ;
  213. test_count++ ;
  214. } ;
  215. if (do_all || ! strcmp (argv [1], "voc"))
  216. { pcm_test_char  ("char.voc" , SF_FORMAT_VOC | SF_FORMAT_PCM_U8, SF_FALSE) ;
  217. pcm_test_short ("short.voc", SF_FORMAT_VOC | SF_FORMAT_PCM_16, SF_FALSE) ;
  218. test_count++ ;
  219. } ;
  220. if (do_all || ! strcmp (argv [1], "mat4"))
  221. { pcm_test_short ("short_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_PCM_16, SF_FALSE) ;
  222. pcm_test_short ("short_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_PCM_16, SF_FALSE) ;
  223. pcm_test_int ("int_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_PCM_32, SF_FALSE) ;
  224. pcm_test_int  ("int_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_PCM_32, SF_FALSE) ;
  225. pcm_test_float ("float_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_FLOAT , SF_FALSE) ;
  226. pcm_test_float ("float_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_FLOAT , SF_FALSE) ;
  227. pcm_test_double ("double_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  228. pcm_test_double ("double_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  229. empty_file_test ("empty_short.mat4", SF_FORMAT_MAT4 | SF_FORMAT_PCM_16) ;
  230. empty_file_test ("empty_float.mat4", SF_FORMAT_MAT4 | SF_FORMAT_FLOAT) ;
  231. test_count++ ;
  232. } ;
  233. if (do_all || ! strcmp (argv [1], "mat5"))
  234. { pcm_test_char  ("char_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8, SF_FALSE) ;
  235. pcm_test_char  ("char_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8, SF_FALSE) ;
  236. pcm_test_short ("short_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_16, SF_FALSE) ;
  237. pcm_test_short ("short_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_16, SF_FALSE) ;
  238. pcm_test_int ("int_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_32, SF_FALSE) ;
  239. pcm_test_int  ("int_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_32, SF_FALSE) ;
  240. pcm_test_float ("float_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_FLOAT , SF_FALSE) ;
  241. pcm_test_float ("float_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_FLOAT , SF_FALSE) ;
  242. pcm_test_double ("double_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  243. pcm_test_double ("double_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  244. increment_open_file_count () ;
  245. empty_file_test ("empty_char.mat5", SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8) ;
  246. empty_file_test ("empty_short.mat5", SF_FORMAT_MAT5 | SF_FORMAT_PCM_16) ;
  247. empty_file_test ("empty_float.mat5", SF_FORMAT_MAT5 | SF_FORMAT_FLOAT) ;
  248. test_count++ ;
  249. } ;
  250. if (do_all || ! strcmp (argv [1], "pvf"))
  251. { pcm_test_char  ("char.pvf" , SF_FORMAT_PVF | SF_FORMAT_PCM_S8, SF_FALSE) ;
  252. pcm_test_short ("short.pvf", SF_FORMAT_PVF | SF_FORMAT_PCM_16, SF_FALSE) ;
  253. pcm_test_int ("int.pvf" , SF_FORMAT_PVF | SF_FORMAT_PCM_32, SF_FALSE) ;
  254. test_count++ ;
  255. } ;
  256. if (do_all || ! strcmp (argv [1], "htk"))
  257. { pcm_test_short ("short.htk", SF_FORMAT_HTK | SF_FORMAT_PCM_16, SF_FALSE) ;
  258. test_count++ ;
  259. } ;
  260. if (do_all || ! strcmp (argv [1], "mpc2k"))
  261. { pcm_test_short ("short.mpc", SF_FORMAT_MPC2K | SF_FORMAT_PCM_16, SF_FALSE) ;
  262. test_count++ ;
  263. } ;
  264. if (do_all || ! strcmp (argv [1], "avr"))
  265. { pcm_test_char  ("char_u8.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_U8, SF_FALSE) ;
  266. pcm_test_char  ("char_s8.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_S8, SF_FALSE) ;
  267. pcm_test_short ("short.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_16, SF_FALSE) ;
  268. test_count++ ;
  269. } ;
  270. /* Lite remove end */
  271. if (do_all || ! strcmp (argv [1], "w64"))
  272. { pcm_test_char ("char.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_U8, SF_FALSE) ;
  273. pcm_test_short ("short.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_16, SF_FALSE) ;
  274. pcm_test_24bit ("24bit.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_24, SF_FALSE) ;
  275. pcm_test_int ("int.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_32, SF_FALSE) ;
  276. /* Lite remove start */
  277. pcm_test_float ("float.w64" , SF_FORMAT_W64 | SF_FORMAT_FLOAT , SF_FALSE) ;
  278. pcm_test_double ("double.w64" , SF_FORMAT_W64 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  279. /* Lite remove end */
  280. empty_file_test ("empty_char.w64", SF_FORMAT_W64 | SF_FORMAT_PCM_U8) ;
  281. empty_file_test ("empty_short.w64", SF_FORMAT_W64 | SF_FORMAT_PCM_16) ;
  282. empty_file_test ("empty_float.w64", SF_FORMAT_W64 | SF_FORMAT_FLOAT) ;
  283. test_count++ ;
  284. } ;
  285. if (do_all || ! strcmp (argv [1], "sds"))
  286. { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_TRUE) ;
  287. pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_TRUE) ;
  288. pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_TRUE) ;
  289. empty_file_test ("empty_char.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_S8) ;
  290. empty_file_test ("empty_short.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_16) ;
  291. test_count++ ;
  292. } ;
  293. if (do_all || ! strcmp (argv [1], "sd2"))
  294. { pcm_test_char ("char.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_S8, SF_TRUE) ;
  295. pcm_test_short ("short.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_16, SF_TRUE) ;
  296. pcm_test_24bit ("24bit.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_24, SF_TRUE) ;
  297. test_count++ ;
  298. } ;
  299. if (do_all || ! strcmp (argv [1], "flac"))
  300. { if (HAVE_EXTERNAL_LIBS)
  301. { pcm_test_char ("char.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_S8, SF_TRUE) ;
  302. pcm_test_short ("short.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_16, SF_TRUE) ;
  303. pcm_test_24bit ("24bit.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_24, SF_TRUE) ;
  304. }
  305. else
  306. puts ("    No FLAC tests because FLAC support was not compiled in.") ;
  307. test_count++ ;
  308. } ;
  309. if (do_all || ! strcmp (argv [1], "rf64"))
  310. { pcm_test_char ("char.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_U8, SF_FALSE) ;
  311. pcm_test_short ("short.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_16, SF_FALSE) ;
  312. pcm_test_24bit ("24bit.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_24, SF_FALSE) ;
  313. pcm_test_int ("int.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_32, SF_FALSE) ;
  314. /* Lite remove start */
  315. pcm_test_float ("float.rf64" , SF_FORMAT_RF64 | SF_FORMAT_FLOAT , SF_FALSE) ;
  316. pcm_test_double ("double.rf64" , SF_FORMAT_RF64 | SF_FORMAT_DOUBLE, SF_FALSE) ;
  317. empty_file_test ("empty_char.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_U8) ;
  318. empty_file_test ("empty_short.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
  319. empty_file_test ("empty_float.rf64", SF_FORMAT_RF64 | SF_FORMAT_FLOAT) ;
  320. /* Lite remove end */
  321. test_count++ ;
  322. } ;
  323. if (test_count == 0)
  324. { printf ("Mono : ************************************n") ;
  325. printf ("Mono : *  No '%s' test defined.n", argv [1]) ;
  326. printf ("Mono : ************************************n") ;
  327. return 1 ;
  328. } ;
  329. /* Only open file descriptors should be stdin, stdout and stderr. */
  330. check_open_file_count_or_die (__LINE__) ;
  331. return 0 ;
  332. } /* main */
  333. /*============================================================================================
  334. ** Helper functions and macros.
  335. */
  336. static void create_short_file (const char *filename) ;
  337. #define CHAR_ERROR(x,y) (abs ((x) - (y)) > 255)
  338. #define INT_ERROR(x,y) (((x) - (y)) != 0)
  339. #define TRIBYTE_ERROR(x,y) (abs ((x) - (y)) > 255)
  340. #define FLOAT_ERROR(x,y) (fabs ((x) - (y)) > 1e-5)
  341. #define CONVERT_DATA(k,len,new,orig)
  342. { for ((k) = 0 ; (k) < (len) ; (k) ++)
  343. (new) [k] = (orig) [k] ;
  344. }
  345. /*======================================================================================
  346. */
  347. static void mono_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  348. static void stereo_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  349. static void mono_rdwr_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  350. static void new_rdwr_char_test (const char *filename, int format, int allow_fd) ;
  351. static void multi_seek_test (const char * filename, int format) ;
  352. static void write_seek_extend_test (const char * filename, int format) ;
  353. static void
  354. pcm_test_char (const char *filename, int format, int long_file_ok)
  355. { SF_INFO sfinfo ;
  356. short *orig, *test ;
  357. int k, items, allow_fd ;
  358. /* Sd2 files cannot be opened from an existing file descriptor. */
  359. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  360. print_test_name ("pcm_test_char", filename) ;
  361. sfinfo.samplerate = 44100 ;
  362. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  363. sfinfo.channels = 1 ;
  364. sfinfo.format = format ;
  365. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
  366. orig = orig_data.s ;
  367. test = test_data.s ;
  368. /* Make this a macro so gdb steps over it in one go. */
  369. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  370. items = DATA_LENGTH ;
  371. /* Some test broken out here. */
  372. mono_char_test (filename, format, long_file_ok, allow_fd) ;
  373. /* Sub format DWVW does not allow seeking. */
  374. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  375. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  376. { unlink (filename) ;
  377. printf ("no seek : okn") ;
  378. return ;
  379. } ;
  380. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  381. mono_rdwr_char_test (filename, format, long_file_ok, allow_fd) ;
  382. /* If the format doesn't support stereo we're done. */
  383. sfinfo.channels = 2 ;
  384. if (sf_format_check (&sfinfo) == 0)
  385. { unlink (filename) ;
  386. puts ("no stereo : ok") ;
  387. return ;
  388. } ;
  389. stereo_char_test (filename, format, long_file_ok, allow_fd) ;
  390. /* New read/write test. Not sure if this is needed yet. */
  391. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  392. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  393. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  394. new_rdwr_char_test (filename, format, allow_fd) ;
  395. delete_file (format, filename) ;
  396. puts ("ok") ;
  397. return ;
  398. } /* pcm_test_char */
  399. static void
  400. mono_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
  401. { SNDFILE *file ;
  402. SF_INFO sfinfo ;
  403. short *orig, *test ;
  404. sf_count_t count ;
  405. int k, items ;
  406. sfinfo.samplerate = 44100 ;
  407. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  408. sfinfo.channels = 1 ;
  409. sfinfo.format = format ;
  410. orig = orig_data.s ;
  411. test = test_data.s ;
  412. items = DATA_LENGTH ;
  413. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  414. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  415. test_write_short_or_die (file, 0, orig, items, __LINE__) ;
  416. sf_write_sync (file) ;
  417. test_write_short_or_die (file, 0, orig, items, __LINE__) ;
  418. sf_write_sync (file) ;
  419. /* Add non-audio data after the audio. */
  420. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  421. sf_close (file) ;
  422. memset (test, 0, items * sizeof (short)) ;
  423. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  424. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  425. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  426. if (sfinfo.format != format)
  427. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  428. exit (1) ;
  429. } ;
  430. if (sfinfo.frames < 2 * items)
  431. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  432. exit (1) ;
  433. } ;
  434. if (! long_file_ok && sfinfo.frames > 2 * items)
  435. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  436. exit (1) ;
  437. } ;
  438. if (sfinfo.channels != 1)
  439. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  440. exit (1) ;
  441. } ;
  442. check_log_buffer_or_die (file, __LINE__) ;
  443. test_read_short_or_die (file, 0, test, items, __LINE__) ;
  444. for (k = 0 ; k < items ; k++)
  445. if (CHAR_ERROR (orig [k], test [k]))
  446. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  447. oct_save_short (orig, test, items) ;
  448. exit (1) ;
  449. } ;
  450. /* Seek to start of file. */
  451. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  452. test_read_short_or_die (file, 0, test, 4, __LINE__) ;
  453. for (k = 0 ; k < 4 ; k++)
  454. if (CHAR_ERROR (orig [k], test [k]))
  455. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  456. exit (1) ;
  457. } ;
  458. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  459. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  460. { sf_close (file) ;
  461. unlink (filename) ;
  462. printf ("no seek : ") ;
  463. return ;
  464. } ;
  465. /* Seek to offset from start of file. */
  466. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  467. test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
  468. for (k = 10 ; k < 14 ; k++)
  469. if (CHAR_ERROR (orig [k], test [k]))
  470. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  471. exit (1) ;
  472. } ;
  473. /* Seek to offset from current position. */
  474. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  475. test_read_short_or_die (file, 0, test + 20, 4, __LINE__) ;
  476. for (k = 20 ; k < 24 ; k++)
  477. if (CHAR_ERROR (orig [k], test [k]))
  478. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  479. exit (1) ;
  480. } ;
  481. /* Seek to offset from end of file. */
  482. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  483. test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
  484. for (k = 10 ; k < 14 ; k++)
  485. if (CHAR_ERROR (orig [k], test [k]))
  486. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  487. exit (1) ;
  488. } ;
  489. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  490. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  491. count = 0 ;
  492. while (count < sfinfo.frames)
  493. count += sf_read_short (file, test, 311) ;
  494. /* Check that no error has occurred. */
  495. if (sf_error (file))
  496. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  497. puts (sf_strerror (file)) ;
  498. exit (1) ;
  499. } ;
  500. /* Check that we haven't read beyond EOF. */
  501. if (count > sfinfo.frames)
  502. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  503. exit (1) ;
  504. } ;
  505. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  506. sf_close (file) ;
  507. multi_seek_test (filename, format) ;
  508. write_seek_extend_test (filename, format) ;
  509. } /* mono_char_test */
  510. static void
  511. stereo_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
  512. { SNDFILE *file ;
  513. SF_INFO sfinfo ;
  514. short *orig, *test ;
  515. int k, items, frames ;
  516. sfinfo.samplerate = 44100 ;
  517. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  518. sfinfo.channels = 2 ;
  519. sfinfo.format = format ;
  520. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
  521. orig = orig_data.s ;
  522. test = test_data.s ;
  523. /* Make this a macro so gdb steps over it in one go. */
  524. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  525. items = DATA_LENGTH ;
  526. frames = items / sfinfo.channels ;
  527. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  528. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  529. test_writef_short_or_die (file, 0, orig, frames, __LINE__) ;
  530. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  531. sf_close (file) ;
  532. memset (test, 0, items * sizeof (short)) ;
  533. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  534. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  535. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  536. if (sfinfo.format != format)
  537. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  538. __LINE__, format, sfinfo.format) ;
  539. exit (1) ;
  540. } ;
  541. if (sfinfo.frames < frames)
  542. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  543. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  544. exit (1) ;
  545. } ;
  546. if (! long_file_ok && sfinfo.frames > frames)
  547. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  548. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  549. exit (1) ;
  550. } ;
  551. if (sfinfo.channels != 2)
  552. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  553. exit (1) ;
  554. } ;
  555. check_log_buffer_or_die (file, __LINE__) ;
  556. test_readf_short_or_die (file, 0, test, frames, __LINE__) ;
  557. for (k = 0 ; k < items ; k++)
  558. if (CHAR_ERROR (test [k], orig [k]))
  559. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  560. exit (1) ;
  561. } ;
  562. /* Seek to start of file. */
  563. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  564. test_readf_short_or_die (file, 0, test, 2, __LINE__) ;
  565. for (k = 0 ; k < 4 ; k++)
  566. if (CHAR_ERROR (test [k], orig [k]))
  567. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  568. exit (1) ;
  569. } ;
  570. /* Seek to offset from start of file. */
  571. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  572. /* Check for errors here. */
  573. if (sf_error (file))
  574. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  575. puts (sf_strerror (file)) ;
  576. exit (1) ;
  577. } ;
  578. if (sf_read_short (file, test, 1) > 0)
  579. { printf ("Line %d: Should return 0.n", __LINE__) ;
  580. exit (1) ;
  581. } ;
  582. if (! sf_error (file))
  583. { printf ("Line %d: Should return an error.n", __LINE__) ;
  584. exit (1) ;
  585. } ;
  586. /*-----------------------*/
  587. test_readf_short_or_die (file, 0, test + 10, 2, __LINE__) ;
  588. for (k = 20 ; k < 24 ; k++)
  589. if (CHAR_ERROR (test [k], orig [k]))
  590. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  591. exit (1) ;
  592. } ;
  593. /* Seek to offset from current position. */
  594. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  595. test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
  596. for (k = 40 ; k < 44 ; k++)
  597. if (CHAR_ERROR (test [k], orig [k]))
  598. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  599. exit (1) ;
  600. } ;
  601. /* Seek to offset from end of file. */
  602. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  603. test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
  604. for (k = 20 ; k < 24 ; k++)
  605. if (CHAR_ERROR (test [k], orig [k]))
  606. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  607. exit (1) ;
  608. } ;
  609. sf_close (file) ;
  610. } /* stereo_char_test */
  611. static void
  612. mono_rdwr_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
  613. { SNDFILE *file ;
  614. SF_INFO sfinfo ;
  615. short *orig, *test ;
  616. int k, pass ;
  617. orig = orig_data.s ;
  618. test = test_data.s ;
  619. sfinfo.samplerate = SAMPLE_RATE ;
  620. sfinfo.frames = DATA_LENGTH ;
  621. sfinfo.channels = 1 ;
  622. sfinfo.format = format ;
  623. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  624. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  625. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  626. unlink (filename) ;
  627. else
  628. { /* Create a short file. */
  629. create_short_file (filename) ;
  630. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  631. ** If this returns a valif pointer sf_open() screwed up.
  632. */
  633. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  634. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  635. exit (1) ;
  636. } ;
  637. /* Truncate the file to zero bytes. */
  638. if (truncate (filename, 0) < 0)
  639. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  640. perror (NULL) ;
  641. exit (1) ;
  642. } ;
  643. } ;
  644. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  645. ** all the usual data required when opening the file in WRITE mode.
  646. */
  647. sfinfo.samplerate = SAMPLE_RATE ;
  648. sfinfo.frames = DATA_LENGTH ;
  649. sfinfo.channels = 1 ;
  650. sfinfo.format = format ;
  651. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  652. /* Do 3 writes followed by reads. After each, check the data and the current
  653. ** read and write offsets.
  654. */
  655. for (pass = 1 ; pass <= 3 ; pass ++)
  656. { orig [20] = pass * 2 ;
  657. /* Write some data. */
  658. test_write_short_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  659. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  660. /* Read what we just wrote. */
  661. test_read_short_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  662. /* Check the data. */
  663. for (k = 0 ; k < DATA_LENGTH ; k++)
  664. if (CHAR_ERROR (orig [k], test [k]))
  665. { printf ("nnLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  666. oct_save_short (orig, test, DATA_LENGTH) ;
  667. exit (1) ;
  668. } ;
  669. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  670. } ; /* for (pass ...) */
  671. sf_close (file) ;
  672. /* Open the file again to check the data. */
  673. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  674. if (sfinfo.format != format)
  675. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  676. exit (1) ;
  677. } ;
  678. if (sfinfo.frames < 3 * DATA_LENGTH)
  679. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  680. exit (1) ;
  681. }
  682. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  683. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  684. exit (1) ;
  685. } ;
  686. if (sfinfo.channels != 1)
  687. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  688. exit (1) ;
  689. } ;
  690. if (! long_file_ok)
  691. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  692. else
  693. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  694. for (pass = 1 ; pass <= 3 ; pass ++)
  695. { orig [20] = pass * 2 ;
  696. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  697. /* Read what we just wrote. */
  698. test_read_short_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  699. /* Check the data. */
  700. for (k = 0 ; k < DATA_LENGTH ; k++)
  701. if (CHAR_ERROR (orig [k], test [k]))
  702. { printf ("nnLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  703. oct_save_short (orig, test, DATA_LENGTH) ;
  704. exit (1) ;
  705. } ;
  706. } ; /* for (pass ...) */
  707. sf_close (file) ;
  708. } /* mono_rdwr_short_test */
  709. static void
  710. new_rdwr_char_test (const char *filename, int format, int allow_fd)
  711. { SNDFILE *wfile, *rwfile ;
  712. SF_INFO sfinfo ;
  713. short *orig, *test ;
  714. int items, frames ;
  715. orig = orig_data.s ;
  716. test = test_data.s ;
  717. sfinfo.samplerate = 44100 ;
  718. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  719. sfinfo.channels = 2 ;
  720. sfinfo.format = format ;
  721. items = DATA_LENGTH ;
  722. frames = items / sfinfo.channels ;
  723. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  724. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  725. test_writef_short_or_die (wfile, 1, orig, frames, __LINE__) ;
  726. sf_write_sync (wfile) ;
  727. test_writef_short_or_die (wfile, 2, orig, frames, __LINE__) ;
  728. sf_write_sync (wfile) ;
  729. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  730. if (sfinfo.frames != 2 * frames)
  731. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  732. exit (1) ;
  733. } ;
  734. test_writef_short_or_die (wfile, 3, orig, frames, __LINE__) ;
  735. test_readf_short_or_die (rwfile, 1, test, frames, __LINE__) ;
  736. test_readf_short_or_die (rwfile, 2, test, frames, __LINE__) ;
  737. sf_close (wfile) ;
  738. sf_close (rwfile) ;
  739. } /* new_rdwr_char_test */
  740. /*======================================================================================
  741. */
  742. static void mono_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  743. static void stereo_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  744. static void mono_rdwr_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  745. static void new_rdwr_short_test (const char *filename, int format, int allow_fd) ;
  746. static void multi_seek_test (const char * filename, int format) ;
  747. static void write_seek_extend_test (const char * filename, int format) ;
  748. static void
  749. pcm_test_short (const char *filename, int format, int long_file_ok)
  750. { SF_INFO sfinfo ;
  751. short *orig, *test ;
  752. int k, items, allow_fd ;
  753. /* Sd2 files cannot be opened from an existing file descriptor. */
  754. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  755. print_test_name ("pcm_test_short", filename) ;
  756. sfinfo.samplerate = 44100 ;
  757. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  758. sfinfo.channels = 1 ;
  759. sfinfo.format = format ;
  760. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
  761. orig = orig_data.s ;
  762. test = test_data.s ;
  763. /* Make this a macro so gdb steps over it in one go. */
  764. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  765. items = DATA_LENGTH ;
  766. /* Some test broken out here. */
  767. mono_short_test (filename, format, long_file_ok, allow_fd) ;
  768. /* Sub format DWVW does not allow seeking. */
  769. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  770. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  771. { unlink (filename) ;
  772. printf ("no seek : okn") ;
  773. return ;
  774. } ;
  775. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  776. mono_rdwr_short_test (filename, format, long_file_ok, allow_fd) ;
  777. /* If the format doesn't support stereo we're done. */
  778. sfinfo.channels = 2 ;
  779. if (sf_format_check (&sfinfo) == 0)
  780. { unlink (filename) ;
  781. puts ("no stereo : ok") ;
  782. return ;
  783. } ;
  784. stereo_short_test (filename, format, long_file_ok, allow_fd) ;
  785. /* New read/write test. Not sure if this is needed yet. */
  786. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  787. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  788. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  789. new_rdwr_short_test (filename, format, allow_fd) ;
  790. delete_file (format, filename) ;
  791. puts ("ok") ;
  792. return ;
  793. } /* pcm_test_short */
  794. static void
  795. mono_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
  796. { SNDFILE *file ;
  797. SF_INFO sfinfo ;
  798. short *orig, *test ;
  799. sf_count_t count ;
  800. int k, items ;
  801. sfinfo.samplerate = 44100 ;
  802. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  803. sfinfo.channels = 1 ;
  804. sfinfo.format = format ;
  805. orig = orig_data.s ;
  806. test = test_data.s ;
  807. items = DATA_LENGTH ;
  808. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  809. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  810. test_write_short_or_die (file, 0, orig, items, __LINE__) ;
  811. sf_write_sync (file) ;
  812. test_write_short_or_die (file, 0, orig, items, __LINE__) ;
  813. sf_write_sync (file) ;
  814. /* Add non-audio data after the audio. */
  815. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  816. sf_close (file) ;
  817. memset (test, 0, items * sizeof (short)) ;
  818. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  819. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  820. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  821. if (sfinfo.format != format)
  822. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  823. exit (1) ;
  824. } ;
  825. if (sfinfo.frames < 2 * items)
  826. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  827. exit (1) ;
  828. } ;
  829. if (! long_file_ok && sfinfo.frames > 2 * items)
  830. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  831. exit (1) ;
  832. } ;
  833. if (sfinfo.channels != 1)
  834. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  835. exit (1) ;
  836. } ;
  837. check_log_buffer_or_die (file, __LINE__) ;
  838. test_read_short_or_die (file, 0, test, items, __LINE__) ;
  839. for (k = 0 ; k < items ; k++)
  840. if (INT_ERROR (orig [k], test [k]))
  841. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  842. oct_save_short (orig, test, items) ;
  843. exit (1) ;
  844. } ;
  845. /* Seek to start of file. */
  846. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  847. test_read_short_or_die (file, 0, test, 4, __LINE__) ;
  848. for (k = 0 ; k < 4 ; k++)
  849. if (INT_ERROR (orig [k], test [k]))
  850. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  851. exit (1) ;
  852. } ;
  853. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  854. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  855. { sf_close (file) ;
  856. unlink (filename) ;
  857. printf ("no seek : ") ;
  858. return ;
  859. } ;
  860. /* Seek to offset from start of file. */
  861. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  862. test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
  863. for (k = 10 ; k < 14 ; k++)
  864. if (INT_ERROR (orig [k], test [k]))
  865. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  866. exit (1) ;
  867. } ;
  868. /* Seek to offset from current position. */
  869. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  870. test_read_short_or_die (file, 0, test + 20, 4, __LINE__) ;
  871. for (k = 20 ; k < 24 ; k++)
  872. if (INT_ERROR (orig [k], test [k]))
  873. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  874. exit (1) ;
  875. } ;
  876. /* Seek to offset from end of file. */
  877. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  878. test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
  879. for (k = 10 ; k < 14 ; k++)
  880. if (INT_ERROR (orig [k], test [k]))
  881. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  882. exit (1) ;
  883. } ;
  884. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  885. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  886. count = 0 ;
  887. while (count < sfinfo.frames)
  888. count += sf_read_short (file, test, 311) ;
  889. /* Check that no error has occurred. */
  890. if (sf_error (file))
  891. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  892. puts (sf_strerror (file)) ;
  893. exit (1) ;
  894. } ;
  895. /* Check that we haven't read beyond EOF. */
  896. if (count > sfinfo.frames)
  897. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  898. exit (1) ;
  899. } ;
  900. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  901. sf_close (file) ;
  902. multi_seek_test (filename, format) ;
  903. write_seek_extend_test (filename, format) ;
  904. } /* mono_short_test */
  905. static void
  906. stereo_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
  907. { SNDFILE *file ;
  908. SF_INFO sfinfo ;
  909. short *orig, *test ;
  910. int k, items, frames ;
  911. sfinfo.samplerate = 44100 ;
  912. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  913. sfinfo.channels = 2 ;
  914. sfinfo.format = format ;
  915. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
  916. orig = orig_data.s ;
  917. test = test_data.s ;
  918. /* Make this a macro so gdb steps over it in one go. */
  919. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  920. items = DATA_LENGTH ;
  921. frames = items / sfinfo.channels ;
  922. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  923. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  924. test_writef_short_or_die (file, 0, orig, frames, __LINE__) ;
  925. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  926. sf_close (file) ;
  927. memset (test, 0, items * sizeof (short)) ;
  928. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  929. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  930. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  931. if (sfinfo.format != format)
  932. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  933. __LINE__, format, sfinfo.format) ;
  934. exit (1) ;
  935. } ;
  936. if (sfinfo.frames < frames)
  937. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  938. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  939. exit (1) ;
  940. } ;
  941. if (! long_file_ok && sfinfo.frames > frames)
  942. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  943. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  944. exit (1) ;
  945. } ;
  946. if (sfinfo.channels != 2)
  947. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  948. exit (1) ;
  949. } ;
  950. check_log_buffer_or_die (file, __LINE__) ;
  951. test_readf_short_or_die (file, 0, test, frames, __LINE__) ;
  952. for (k = 0 ; k < items ; k++)
  953. if (INT_ERROR (test [k], orig [k]))
  954. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  955. exit (1) ;
  956. } ;
  957. /* Seek to start of file. */
  958. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  959. test_readf_short_or_die (file, 0, test, 2, __LINE__) ;
  960. for (k = 0 ; k < 4 ; k++)
  961. if (INT_ERROR (test [k], orig [k]))
  962. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  963. exit (1) ;
  964. } ;
  965. /* Seek to offset from start of file. */
  966. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  967. /* Check for errors here. */
  968. if (sf_error (file))
  969. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  970. puts (sf_strerror (file)) ;
  971. exit (1) ;
  972. } ;
  973. if (sf_read_short (file, test, 1) > 0)
  974. { printf ("Line %d: Should return 0.n", __LINE__) ;
  975. exit (1) ;
  976. } ;
  977. if (! sf_error (file))
  978. { printf ("Line %d: Should return an error.n", __LINE__) ;
  979. exit (1) ;
  980. } ;
  981. /*-----------------------*/
  982. test_readf_short_or_die (file, 0, test + 10, 2, __LINE__) ;
  983. for (k = 20 ; k < 24 ; k++)
  984. if (INT_ERROR (test [k], orig [k]))
  985. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  986. exit (1) ;
  987. } ;
  988. /* Seek to offset from current position. */
  989. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  990. test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
  991. for (k = 40 ; k < 44 ; k++)
  992. if (INT_ERROR (test [k], orig [k]))
  993. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  994. exit (1) ;
  995. } ;
  996. /* Seek to offset from end of file. */
  997. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  998. test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
  999. for (k = 20 ; k < 24 ; k++)
  1000. if (INT_ERROR (test [k], orig [k]))
  1001. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1002. exit (1) ;
  1003. } ;
  1004. sf_close (file) ;
  1005. } /* stereo_short_test */
  1006. static void
  1007. mono_rdwr_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1008. { SNDFILE *file ;
  1009. SF_INFO sfinfo ;
  1010. short *orig, *test ;
  1011. int k, pass ;
  1012. orig = orig_data.s ;
  1013. test = test_data.s ;
  1014. sfinfo.samplerate = SAMPLE_RATE ;
  1015. sfinfo.frames = DATA_LENGTH ;
  1016. sfinfo.channels = 1 ;
  1017. sfinfo.format = format ;
  1018. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  1019. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  1020. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  1021. unlink (filename) ;
  1022. else
  1023. { /* Create a short file. */
  1024. create_short_file (filename) ;
  1025. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  1026. ** If this returns a valif pointer sf_open() screwed up.
  1027. */
  1028. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  1029. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  1030. exit (1) ;
  1031. } ;
  1032. /* Truncate the file to zero bytes. */
  1033. if (truncate (filename, 0) < 0)
  1034. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  1035. perror (NULL) ;
  1036. exit (1) ;
  1037. } ;
  1038. } ;
  1039. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  1040. ** all the usual data required when opening the file in WRITE mode.
  1041. */
  1042. sfinfo.samplerate = SAMPLE_RATE ;
  1043. sfinfo.frames = DATA_LENGTH ;
  1044. sfinfo.channels = 1 ;
  1045. sfinfo.format = format ;
  1046. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1047. /* Do 3 writes followed by reads. After each, check the data and the current
  1048. ** read and write offsets.
  1049. */
  1050. for (pass = 1 ; pass <= 3 ; pass ++)
  1051. { orig [20] = pass * 2 ;
  1052. /* Write some data. */
  1053. test_write_short_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  1054. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  1055. /* Read what we just wrote. */
  1056. test_read_short_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  1057. /* Check the data. */
  1058. for (k = 0 ; k < DATA_LENGTH ; k++)
  1059. if (INT_ERROR (orig [k], test [k]))
  1060. { printf ("nnLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1061. oct_save_short (orig, test, DATA_LENGTH) ;
  1062. exit (1) ;
  1063. } ;
  1064. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  1065. } ; /* for (pass ...) */
  1066. sf_close (file) ;
  1067. /* Open the file again to check the data. */
  1068. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1069. if (sfinfo.format != format)
  1070. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  1071. exit (1) ;
  1072. } ;
  1073. if (sfinfo.frames < 3 * DATA_LENGTH)
  1074. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1075. exit (1) ;
  1076. }
  1077. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  1078. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1079. exit (1) ;
  1080. } ;
  1081. if (sfinfo.channels != 1)
  1082. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  1083. exit (1) ;
  1084. } ;
  1085. if (! long_file_ok)
  1086. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  1087. else
  1088. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  1089. for (pass = 1 ; pass <= 3 ; pass ++)
  1090. { orig [20] = pass * 2 ;
  1091. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  1092. /* Read what we just wrote. */
  1093. test_read_short_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  1094. /* Check the data. */
  1095. for (k = 0 ; k < DATA_LENGTH ; k++)
  1096. if (INT_ERROR (orig [k], test [k]))
  1097. { printf ("nnLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1098. oct_save_short (orig, test, DATA_LENGTH) ;
  1099. exit (1) ;
  1100. } ;
  1101. } ; /* for (pass ...) */
  1102. sf_close (file) ;
  1103. } /* mono_rdwr_short_test */
  1104. static void
  1105. new_rdwr_short_test (const char *filename, int format, int allow_fd)
  1106. { SNDFILE *wfile, *rwfile ;
  1107. SF_INFO sfinfo ;
  1108. short *orig, *test ;
  1109. int items, frames ;
  1110. orig = orig_data.s ;
  1111. test = test_data.s ;
  1112. sfinfo.samplerate = 44100 ;
  1113. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1114. sfinfo.channels = 2 ;
  1115. sfinfo.format = format ;
  1116. items = DATA_LENGTH ;
  1117. frames = items / sfinfo.channels ;
  1118. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1119. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  1120. test_writef_short_or_die (wfile, 1, orig, frames, __LINE__) ;
  1121. sf_write_sync (wfile) ;
  1122. test_writef_short_or_die (wfile, 2, orig, frames, __LINE__) ;
  1123. sf_write_sync (wfile) ;
  1124. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1125. if (sfinfo.frames != 2 * frames)
  1126. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  1127. exit (1) ;
  1128. } ;
  1129. test_writef_short_or_die (wfile, 3, orig, frames, __LINE__) ;
  1130. test_readf_short_or_die (rwfile, 1, test, frames, __LINE__) ;
  1131. test_readf_short_or_die (rwfile, 2, test, frames, __LINE__) ;
  1132. sf_close (wfile) ;
  1133. sf_close (rwfile) ;
  1134. } /* new_rdwr_short_test */
  1135. /*======================================================================================
  1136. */
  1137. static void mono_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1138. static void stereo_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1139. static void mono_rdwr_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1140. static void new_rdwr_24bit_test (const char *filename, int format, int allow_fd) ;
  1141. static void multi_seek_test (const char * filename, int format) ;
  1142. static void write_seek_extend_test (const char * filename, int format) ;
  1143. static void
  1144. pcm_test_24bit (const char *filename, int format, int long_file_ok)
  1145. { SF_INFO sfinfo ;
  1146. int *orig, *test ;
  1147. int k, items, allow_fd ;
  1148. /* Sd2 files cannot be opened from an existing file descriptor. */
  1149. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  1150. print_test_name ("pcm_test_24bit", filename) ;
  1151. sfinfo.samplerate = 44100 ;
  1152. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1153. sfinfo.channels = 1 ;
  1154. sfinfo.format = format ;
  1155. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
  1156. orig = orig_data.i ;
  1157. test = test_data.i ;
  1158. /* Make this a macro so gdb steps over it in one go. */
  1159. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  1160. items = DATA_LENGTH ;
  1161. /* Some test broken out here. */
  1162. mono_24bit_test (filename, format, long_file_ok, allow_fd) ;
  1163. /* Sub format DWVW does not allow seeking. */
  1164. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  1165. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  1166. { unlink (filename) ;
  1167. printf ("no seek : okn") ;
  1168. return ;
  1169. } ;
  1170. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1171. mono_rdwr_24bit_test (filename, format, long_file_ok, allow_fd) ;
  1172. /* If the format doesn't support stereo we're done. */
  1173. sfinfo.channels = 2 ;
  1174. if (sf_format_check (&sfinfo) == 0)
  1175. { unlink (filename) ;
  1176. puts ("no stereo : ok") ;
  1177. return ;
  1178. } ;
  1179. stereo_24bit_test (filename, format, long_file_ok, allow_fd) ;
  1180. /* New read/write test. Not sure if this is needed yet. */
  1181. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  1182. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  1183. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1184. new_rdwr_24bit_test (filename, format, allow_fd) ;
  1185. delete_file (format, filename) ;
  1186. puts ("ok") ;
  1187. return ;
  1188. } /* pcm_test_24bit */
  1189. static void
  1190. mono_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1191. { SNDFILE *file ;
  1192. SF_INFO sfinfo ;
  1193. int *orig, *test ;
  1194. sf_count_t count ;
  1195. int k, items ;
  1196. sfinfo.samplerate = 44100 ;
  1197. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1198. sfinfo.channels = 1 ;
  1199. sfinfo.format = format ;
  1200. orig = orig_data.i ;
  1201. test = test_data.i ;
  1202. items = DATA_LENGTH ;
  1203. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1204. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  1205. test_write_int_or_die (file, 0, orig, items, __LINE__) ;
  1206. sf_write_sync (file) ;
  1207. test_write_int_or_die (file, 0, orig, items, __LINE__) ;
  1208. sf_write_sync (file) ;
  1209. /* Add non-audio data after the audio. */
  1210. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  1211. sf_close (file) ;
  1212. memset (test, 0, items * sizeof (int)) ;
  1213. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1214. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1215. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  1216. if (sfinfo.format != format)
  1217. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  1218. exit (1) ;
  1219. } ;
  1220. if (sfinfo.frames < 2 * items)
  1221. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  1222. exit (1) ;
  1223. } ;
  1224. if (! long_file_ok && sfinfo.frames > 2 * items)
  1225. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  1226. exit (1) ;
  1227. } ;
  1228. if (sfinfo.channels != 1)
  1229. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  1230. exit (1) ;
  1231. } ;
  1232. check_log_buffer_or_die (file, __LINE__) ;
  1233. test_read_int_or_die (file, 0, test, items, __LINE__) ;
  1234. for (k = 0 ; k < items ; k++)
  1235. if (TRIBYTE_ERROR (orig [k], test [k]))
  1236. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1237. oct_save_int (orig, test, items) ;
  1238. exit (1) ;
  1239. } ;
  1240. /* Seek to start of file. */
  1241. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1242. test_read_int_or_die (file, 0, test, 4, __LINE__) ;
  1243. for (k = 0 ; k < 4 ; k++)
  1244. if (TRIBYTE_ERROR (orig [k], test [k]))
  1245. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1246. exit (1) ;
  1247. } ;
  1248. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  1249. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  1250. { sf_close (file) ;
  1251. unlink (filename) ;
  1252. printf ("no seek : ") ;
  1253. return ;
  1254. } ;
  1255. /* Seek to offset from start of file. */
  1256. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  1257. test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
  1258. for (k = 10 ; k < 14 ; k++)
  1259. if (TRIBYTE_ERROR (orig [k], test [k]))
  1260. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1261. exit (1) ;
  1262. } ;
  1263. /* Seek to offset from current position. */
  1264. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  1265. test_read_int_or_die (file, 0, test + 20, 4, __LINE__) ;
  1266. for (k = 20 ; k < 24 ; k++)
  1267. if (TRIBYTE_ERROR (orig [k], test [k]))
  1268. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1269. exit (1) ;
  1270. } ;
  1271. /* Seek to offset from end of file. */
  1272. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  1273. test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
  1274. for (k = 10 ; k < 14 ; k++)
  1275. if (TRIBYTE_ERROR (orig [k], test [k]))
  1276. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1277. exit (1) ;
  1278. } ;
  1279. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  1280. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1281. count = 0 ;
  1282. while (count < sfinfo.frames)
  1283. count += sf_read_int (file, test, 311) ;
  1284. /* Check that no error has occurred. */
  1285. if (sf_error (file))
  1286. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  1287. puts (sf_strerror (file)) ;
  1288. exit (1) ;
  1289. } ;
  1290. /* Check that we haven't read beyond EOF. */
  1291. if (count > sfinfo.frames)
  1292. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  1293. exit (1) ;
  1294. } ;
  1295. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  1296. sf_close (file) ;
  1297. multi_seek_test (filename, format) ;
  1298. write_seek_extend_test (filename, format) ;
  1299. } /* mono_24bit_test */
  1300. static void
  1301. stereo_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1302. { SNDFILE *file ;
  1303. SF_INFO sfinfo ;
  1304. int *orig, *test ;
  1305. int k, items, frames ;
  1306. sfinfo.samplerate = 44100 ;
  1307. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1308. sfinfo.channels = 2 ;
  1309. sfinfo.format = format ;
  1310. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
  1311. orig = orig_data.i ;
  1312. test = test_data.i ;
  1313. /* Make this a macro so gdb steps over it in one go. */
  1314. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  1315. items = DATA_LENGTH ;
  1316. frames = items / sfinfo.channels ;
  1317. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1318. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  1319. test_writef_int_or_die (file, 0, orig, frames, __LINE__) ;
  1320. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  1321. sf_close (file) ;
  1322. memset (test, 0, items * sizeof (int)) ;
  1323. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1324. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1325. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  1326. if (sfinfo.format != format)
  1327. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  1328. __LINE__, format, sfinfo.format) ;
  1329. exit (1) ;
  1330. } ;
  1331. if (sfinfo.frames < frames)
  1332. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  1333. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  1334. exit (1) ;
  1335. } ;
  1336. if (! long_file_ok && sfinfo.frames > frames)
  1337. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  1338. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  1339. exit (1) ;
  1340. } ;
  1341. if (sfinfo.channels != 2)
  1342. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  1343. exit (1) ;
  1344. } ;
  1345. check_log_buffer_or_die (file, __LINE__) ;
  1346. test_readf_int_or_die (file, 0, test, frames, __LINE__) ;
  1347. for (k = 0 ; k < items ; k++)
  1348. if (TRIBYTE_ERROR (test [k], orig [k]))
  1349. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1350. exit (1) ;
  1351. } ;
  1352. /* Seek to start of file. */
  1353. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1354. test_readf_int_or_die (file, 0, test, 2, __LINE__) ;
  1355. for (k = 0 ; k < 4 ; k++)
  1356. if (TRIBYTE_ERROR (test [k], orig [k]))
  1357. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1358. exit (1) ;
  1359. } ;
  1360. /* Seek to offset from start of file. */
  1361. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  1362. /* Check for errors here. */
  1363. if (sf_error (file))
  1364. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  1365. puts (sf_strerror (file)) ;
  1366. exit (1) ;
  1367. } ;
  1368. if (sf_read_int (file, test, 1) > 0)
  1369. { printf ("Line %d: Should return 0.n", __LINE__) ;
  1370. exit (1) ;
  1371. } ;
  1372. if (! sf_error (file))
  1373. { printf ("Line %d: Should return an error.n", __LINE__) ;
  1374. exit (1) ;
  1375. } ;
  1376. /*-----------------------*/
  1377. test_readf_int_or_die (file, 0, test + 10, 2, __LINE__) ;
  1378. for (k = 20 ; k < 24 ; k++)
  1379. if (TRIBYTE_ERROR (test [k], orig [k]))
  1380. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1381. exit (1) ;
  1382. } ;
  1383. /* Seek to offset from current position. */
  1384. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  1385. test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
  1386. for (k = 40 ; k < 44 ; k++)
  1387. if (TRIBYTE_ERROR (test [k], orig [k]))
  1388. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1389. exit (1) ;
  1390. } ;
  1391. /* Seek to offset from end of file. */
  1392. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  1393. test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
  1394. for (k = 20 ; k < 24 ; k++)
  1395. if (TRIBYTE_ERROR (test [k], orig [k]))
  1396. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1397. exit (1) ;
  1398. } ;
  1399. sf_close (file) ;
  1400. } /* stereo_24bit_test */
  1401. static void
  1402. mono_rdwr_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1403. { SNDFILE *file ;
  1404. SF_INFO sfinfo ;
  1405. int *orig, *test ;
  1406. int k, pass ;
  1407. orig = orig_data.i ;
  1408. test = test_data.i ;
  1409. sfinfo.samplerate = SAMPLE_RATE ;
  1410. sfinfo.frames = DATA_LENGTH ;
  1411. sfinfo.channels = 1 ;
  1412. sfinfo.format = format ;
  1413. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  1414. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  1415. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  1416. unlink (filename) ;
  1417. else
  1418. { /* Create a short file. */
  1419. create_short_file (filename) ;
  1420. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  1421. ** If this returns a valif pointer sf_open() screwed up.
  1422. */
  1423. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  1424. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  1425. exit (1) ;
  1426. } ;
  1427. /* Truncate the file to zero bytes. */
  1428. if (truncate (filename, 0) < 0)
  1429. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  1430. perror (NULL) ;
  1431. exit (1) ;
  1432. } ;
  1433. } ;
  1434. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  1435. ** all the usual data required when opening the file in WRITE mode.
  1436. */
  1437. sfinfo.samplerate = SAMPLE_RATE ;
  1438. sfinfo.frames = DATA_LENGTH ;
  1439. sfinfo.channels = 1 ;
  1440. sfinfo.format = format ;
  1441. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1442. /* Do 3 writes followed by reads. After each, check the data and the current
  1443. ** read and write offsets.
  1444. */
  1445. for (pass = 1 ; pass <= 3 ; pass ++)
  1446. { orig [20] = pass * 2 ;
  1447. /* Write some data. */
  1448. test_write_int_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  1449. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  1450. /* Read what we just wrote. */
  1451. test_read_int_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  1452. /* Check the data. */
  1453. for (k = 0 ; k < DATA_LENGTH ; k++)
  1454. if (TRIBYTE_ERROR (orig [k], test [k]))
  1455. { printf ("nnLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1456. oct_save_int (orig, test, DATA_LENGTH) ;
  1457. exit (1) ;
  1458. } ;
  1459. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  1460. } ; /* for (pass ...) */
  1461. sf_close (file) ;
  1462. /* Open the file again to check the data. */
  1463. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1464. if (sfinfo.format != format)
  1465. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  1466. exit (1) ;
  1467. } ;
  1468. if (sfinfo.frames < 3 * DATA_LENGTH)
  1469. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1470. exit (1) ;
  1471. }
  1472. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  1473. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1474. exit (1) ;
  1475. } ;
  1476. if (sfinfo.channels != 1)
  1477. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  1478. exit (1) ;
  1479. } ;
  1480. if (! long_file_ok)
  1481. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  1482. else
  1483. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  1484. for (pass = 1 ; pass <= 3 ; pass ++)
  1485. { orig [20] = pass * 2 ;
  1486. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  1487. /* Read what we just wrote. */
  1488. test_read_int_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  1489. /* Check the data. */
  1490. for (k = 0 ; k < DATA_LENGTH ; k++)
  1491. if (TRIBYTE_ERROR (orig [k], test [k]))
  1492. { printf ("nnLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1493. oct_save_int (orig, test, DATA_LENGTH) ;
  1494. exit (1) ;
  1495. } ;
  1496. } ; /* for (pass ...) */
  1497. sf_close (file) ;
  1498. } /* mono_rdwr_int_test */
  1499. static void
  1500. new_rdwr_24bit_test (const char *filename, int format, int allow_fd)
  1501. { SNDFILE *wfile, *rwfile ;
  1502. SF_INFO sfinfo ;
  1503. int *orig, *test ;
  1504. int items, frames ;
  1505. orig = orig_data.i ;
  1506. test = test_data.i ;
  1507. sfinfo.samplerate = 44100 ;
  1508. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1509. sfinfo.channels = 2 ;
  1510. sfinfo.format = format ;
  1511. items = DATA_LENGTH ;
  1512. frames = items / sfinfo.channels ;
  1513. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1514. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  1515. test_writef_int_or_die (wfile, 1, orig, frames, __LINE__) ;
  1516. sf_write_sync (wfile) ;
  1517. test_writef_int_or_die (wfile, 2, orig, frames, __LINE__) ;
  1518. sf_write_sync (wfile) ;
  1519. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1520. if (sfinfo.frames != 2 * frames)
  1521. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  1522. exit (1) ;
  1523. } ;
  1524. test_writef_int_or_die (wfile, 3, orig, frames, __LINE__) ;
  1525. test_readf_int_or_die (rwfile, 1, test, frames, __LINE__) ;
  1526. test_readf_int_or_die (rwfile, 2, test, frames, __LINE__) ;
  1527. sf_close (wfile) ;
  1528. sf_close (rwfile) ;
  1529. } /* new_rdwr_24bit_test */
  1530. /*======================================================================================
  1531. */
  1532. static void mono_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1533. static void stereo_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1534. static void mono_rdwr_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1535. static void new_rdwr_int_test (const char *filename, int format, int allow_fd) ;
  1536. static void multi_seek_test (const char * filename, int format) ;
  1537. static void write_seek_extend_test (const char * filename, int format) ;
  1538. static void
  1539. pcm_test_int (const char *filename, int format, int long_file_ok)
  1540. { SF_INFO sfinfo ;
  1541. int *orig, *test ;
  1542. int k, items, allow_fd ;
  1543. /* Sd2 files cannot be opened from an existing file descriptor. */
  1544. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  1545. print_test_name ("pcm_test_int", filename) ;
  1546. sfinfo.samplerate = 44100 ;
  1547. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1548. sfinfo.channels = 1 ;
  1549. sfinfo.format = format ;
  1550. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
  1551. orig = orig_data.i ;
  1552. test = test_data.i ;
  1553. /* Make this a macro so gdb steps over it in one go. */
  1554. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  1555. items = DATA_LENGTH ;
  1556. /* Some test broken out here. */
  1557. mono_int_test (filename, format, long_file_ok, allow_fd) ;
  1558. /* Sub format DWVW does not allow seeking. */
  1559. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  1560. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  1561. { unlink (filename) ;
  1562. printf ("no seek : okn") ;
  1563. return ;
  1564. } ;
  1565. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1566. mono_rdwr_int_test (filename, format, long_file_ok, allow_fd) ;
  1567. /* If the format doesn't support stereo we're done. */
  1568. sfinfo.channels = 2 ;
  1569. if (sf_format_check (&sfinfo) == 0)
  1570. { unlink (filename) ;
  1571. puts ("no stereo : ok") ;
  1572. return ;
  1573. } ;
  1574. stereo_int_test (filename, format, long_file_ok, allow_fd) ;
  1575. /* New read/write test. Not sure if this is needed yet. */
  1576. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  1577. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  1578. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1579. new_rdwr_int_test (filename, format, allow_fd) ;
  1580. delete_file (format, filename) ;
  1581. puts ("ok") ;
  1582. return ;
  1583. } /* pcm_test_int */
  1584. static void
  1585. mono_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1586. { SNDFILE *file ;
  1587. SF_INFO sfinfo ;
  1588. int *orig, *test ;
  1589. sf_count_t count ;
  1590. int k, items ;
  1591. sfinfo.samplerate = 44100 ;
  1592. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1593. sfinfo.channels = 1 ;
  1594. sfinfo.format = format ;
  1595. orig = orig_data.i ;
  1596. test = test_data.i ;
  1597. items = DATA_LENGTH ;
  1598. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1599. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  1600. test_write_int_or_die (file, 0, orig, items, __LINE__) ;
  1601. sf_write_sync (file) ;
  1602. test_write_int_or_die (file, 0, orig, items, __LINE__) ;
  1603. sf_write_sync (file) ;
  1604. /* Add non-audio data after the audio. */
  1605. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  1606. sf_close (file) ;
  1607. memset (test, 0, items * sizeof (int)) ;
  1608. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1609. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1610. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  1611. if (sfinfo.format != format)
  1612. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  1613. exit (1) ;
  1614. } ;
  1615. if (sfinfo.frames < 2 * items)
  1616. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  1617. exit (1) ;
  1618. } ;
  1619. if (! long_file_ok && sfinfo.frames > 2 * items)
  1620. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  1621. exit (1) ;
  1622. } ;
  1623. if (sfinfo.channels != 1)
  1624. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  1625. exit (1) ;
  1626. } ;
  1627. check_log_buffer_or_die (file, __LINE__) ;
  1628. test_read_int_or_die (file, 0, test, items, __LINE__) ;
  1629. for (k = 0 ; k < items ; k++)
  1630. if (INT_ERROR (orig [k], test [k]))
  1631. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1632. oct_save_int (orig, test, items) ;
  1633. exit (1) ;
  1634. } ;
  1635. /* Seek to start of file. */
  1636. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1637. test_read_int_or_die (file, 0, test, 4, __LINE__) ;
  1638. for (k = 0 ; k < 4 ; k++)
  1639. if (INT_ERROR (orig [k], test [k]))
  1640. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1641. exit (1) ;
  1642. } ;
  1643. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  1644. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  1645. { sf_close (file) ;
  1646. unlink (filename) ;
  1647. printf ("no seek : ") ;
  1648. return ;
  1649. } ;
  1650. /* Seek to offset from start of file. */
  1651. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  1652. test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
  1653. for (k = 10 ; k < 14 ; k++)
  1654. if (INT_ERROR (orig [k], test [k]))
  1655. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1656. exit (1) ;
  1657. } ;
  1658. /* Seek to offset from current position. */
  1659. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  1660. test_read_int_or_die (file, 0, test + 20, 4, __LINE__) ;
  1661. for (k = 20 ; k < 24 ; k++)
  1662. if (INT_ERROR (orig [k], test [k]))
  1663. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1664. exit (1) ;
  1665. } ;
  1666. /* Seek to offset from end of file. */
  1667. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  1668. test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
  1669. for (k = 10 ; k < 14 ; k++)
  1670. if (INT_ERROR (orig [k], test [k]))
  1671. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).n", __LINE__, k, test [k], orig [k]) ;
  1672. exit (1) ;
  1673. } ;
  1674. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  1675. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1676. count = 0 ;
  1677. while (count < sfinfo.frames)
  1678. count += sf_read_int (file, test, 311) ;
  1679. /* Check that no error has occurred. */
  1680. if (sf_error (file))
  1681. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  1682. puts (sf_strerror (file)) ;
  1683. exit (1) ;
  1684. } ;
  1685. /* Check that we haven't read beyond EOF. */
  1686. if (count > sfinfo.frames)
  1687. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  1688. exit (1) ;
  1689. } ;
  1690. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  1691. sf_close (file) ;
  1692. multi_seek_test (filename, format) ;
  1693. write_seek_extend_test (filename, format) ;
  1694. } /* mono_int_test */
  1695. static void
  1696. stereo_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1697. { SNDFILE *file ;
  1698. SF_INFO sfinfo ;
  1699. int *orig, *test ;
  1700. int k, items, frames ;
  1701. sfinfo.samplerate = 44100 ;
  1702. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1703. sfinfo.channels = 2 ;
  1704. sfinfo.format = format ;
  1705. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
  1706. orig = orig_data.i ;
  1707. test = test_data.i ;
  1708. /* Make this a macro so gdb steps over it in one go. */
  1709. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  1710. items = DATA_LENGTH ;
  1711. frames = items / sfinfo.channels ;
  1712. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1713. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  1714. test_writef_int_or_die (file, 0, orig, frames, __LINE__) ;
  1715. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  1716. sf_close (file) ;
  1717. memset (test, 0, items * sizeof (int)) ;
  1718. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1719. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1720. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  1721. if (sfinfo.format != format)
  1722. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  1723. __LINE__, format, sfinfo.format) ;
  1724. exit (1) ;
  1725. } ;
  1726. if (sfinfo.frames < frames)
  1727. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  1728. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  1729. exit (1) ;
  1730. } ;
  1731. if (! long_file_ok && sfinfo.frames > frames)
  1732. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  1733. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  1734. exit (1) ;
  1735. } ;
  1736. if (sfinfo.channels != 2)
  1737. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  1738. exit (1) ;
  1739. } ;
  1740. check_log_buffer_or_die (file, __LINE__) ;
  1741. test_readf_int_or_die (file, 0, test, frames, __LINE__) ;
  1742. for (k = 0 ; k < items ; k++)
  1743. if (INT_ERROR (test [k], orig [k]))
  1744. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1745. exit (1) ;
  1746. } ;
  1747. /* Seek to start of file. */
  1748. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  1749. test_readf_int_or_die (file, 0, test, 2, __LINE__) ;
  1750. for (k = 0 ; k < 4 ; k++)
  1751. if (INT_ERROR (test [k], orig [k]))
  1752. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1753. exit (1) ;
  1754. } ;
  1755. /* Seek to offset from start of file. */
  1756. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  1757. /* Check for errors here. */
  1758. if (sf_error (file))
  1759. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  1760. puts (sf_strerror (file)) ;
  1761. exit (1) ;
  1762. } ;
  1763. if (sf_read_int (file, test, 1) > 0)
  1764. { printf ("Line %d: Should return 0.n", __LINE__) ;
  1765. exit (1) ;
  1766. } ;
  1767. if (! sf_error (file))
  1768. { printf ("Line %d: Should return an error.n", __LINE__) ;
  1769. exit (1) ;
  1770. } ;
  1771. /*-----------------------*/
  1772. test_readf_int_or_die (file, 0, test + 10, 2, __LINE__) ;
  1773. for (k = 20 ; k < 24 ; k++)
  1774. if (INT_ERROR (test [k], orig [k]))
  1775. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1776. exit (1) ;
  1777. } ;
  1778. /* Seek to offset from current position. */
  1779. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  1780. test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
  1781. for (k = 40 ; k < 44 ; k++)
  1782. if (INT_ERROR (test [k], orig [k]))
  1783. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1784. exit (1) ;
  1785. } ;
  1786. /* Seek to offset from end of file. */
  1787. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  1788. test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
  1789. for (k = 20 ; k < 24 ; k++)
  1790. if (INT_ERROR (test [k], orig [k]))
  1791. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).n", __LINE__, k, orig [k], test [k]) ;
  1792. exit (1) ;
  1793. } ;
  1794. sf_close (file) ;
  1795. } /* stereo_int_test */
  1796. static void
  1797. mono_rdwr_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1798. { SNDFILE *file ;
  1799. SF_INFO sfinfo ;
  1800. int *orig, *test ;
  1801. int k, pass ;
  1802. orig = orig_data.i ;
  1803. test = test_data.i ;
  1804. sfinfo.samplerate = SAMPLE_RATE ;
  1805. sfinfo.frames = DATA_LENGTH ;
  1806. sfinfo.channels = 1 ;
  1807. sfinfo.format = format ;
  1808. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  1809. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  1810. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  1811. unlink (filename) ;
  1812. else
  1813. { /* Create a short file. */
  1814. create_short_file (filename) ;
  1815. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  1816. ** If this returns a valif pointer sf_open() screwed up.
  1817. */
  1818. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  1819. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  1820. exit (1) ;
  1821. } ;
  1822. /* Truncate the file to zero bytes. */
  1823. if (truncate (filename, 0) < 0)
  1824. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  1825. perror (NULL) ;
  1826. exit (1) ;
  1827. } ;
  1828. } ;
  1829. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  1830. ** all the usual data required when opening the file in WRITE mode.
  1831. */
  1832. sfinfo.samplerate = SAMPLE_RATE ;
  1833. sfinfo.frames = DATA_LENGTH ;
  1834. sfinfo.channels = 1 ;
  1835. sfinfo.format = format ;
  1836. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1837. /* Do 3 writes followed by reads. After each, check the data and the current
  1838. ** read and write offsets.
  1839. */
  1840. for (pass = 1 ; pass <= 3 ; pass ++)
  1841. { orig [20] = pass * 2 ;
  1842. /* Write some data. */
  1843. test_write_int_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  1844. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  1845. /* Read what we just wrote. */
  1846. test_read_int_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  1847. /* Check the data. */
  1848. for (k = 0 ; k < DATA_LENGTH ; k++)
  1849. if (INT_ERROR (orig [k], test [k]))
  1850. { printf ("nnLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1851. oct_save_int (orig, test, DATA_LENGTH) ;
  1852. exit (1) ;
  1853. } ;
  1854. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  1855. } ; /* for (pass ...) */
  1856. sf_close (file) ;
  1857. /* Open the file again to check the data. */
  1858. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1859. if (sfinfo.format != format)
  1860. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  1861. exit (1) ;
  1862. } ;
  1863. if (sfinfo.frames < 3 * DATA_LENGTH)
  1864. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1865. exit (1) ;
  1866. }
  1867. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  1868. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  1869. exit (1) ;
  1870. } ;
  1871. if (sfinfo.channels != 1)
  1872. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  1873. exit (1) ;
  1874. } ;
  1875. if (! long_file_ok)
  1876. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  1877. else
  1878. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  1879. for (pass = 1 ; pass <= 3 ; pass ++)
  1880. { orig [20] = pass * 2 ;
  1881. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  1882. /* Read what we just wrote. */
  1883. test_read_int_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  1884. /* Check the data. */
  1885. for (k = 0 ; k < DATA_LENGTH ; k++)
  1886. if (INT_ERROR (orig [k], test [k]))
  1887. { printf ("nnLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).n", __LINE__, pass, k, orig [k], test [k]) ;
  1888. oct_save_int (orig, test, DATA_LENGTH) ;
  1889. exit (1) ;
  1890. } ;
  1891. } ; /* for (pass ...) */
  1892. sf_close (file) ;
  1893. } /* mono_rdwr_int_test */
  1894. static void
  1895. new_rdwr_int_test (const char *filename, int format, int allow_fd)
  1896. { SNDFILE *wfile, *rwfile ;
  1897. SF_INFO sfinfo ;
  1898. int *orig, *test ;
  1899. int items, frames ;
  1900. orig = orig_data.i ;
  1901. test = test_data.i ;
  1902. sfinfo.samplerate = 44100 ;
  1903. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1904. sfinfo.channels = 2 ;
  1905. sfinfo.format = format ;
  1906. items = DATA_LENGTH ;
  1907. frames = items / sfinfo.channels ;
  1908. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1909. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  1910. test_writef_int_or_die (wfile, 1, orig, frames, __LINE__) ;
  1911. sf_write_sync (wfile) ;
  1912. test_writef_int_or_die (wfile, 2, orig, frames, __LINE__) ;
  1913. sf_write_sync (wfile) ;
  1914. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  1915. if (sfinfo.frames != 2 * frames)
  1916. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  1917. exit (1) ;
  1918. } ;
  1919. test_writef_int_or_die (wfile, 3, orig, frames, __LINE__) ;
  1920. test_readf_int_or_die (rwfile, 1, test, frames, __LINE__) ;
  1921. test_readf_int_or_die (rwfile, 2, test, frames, __LINE__) ;
  1922. sf_close (wfile) ;
  1923. sf_close (rwfile) ;
  1924. } /* new_rdwr_int_test */
  1925. /*======================================================================================
  1926. */
  1927. static void mono_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1928. static void stereo_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1929. static void mono_rdwr_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  1930. static void new_rdwr_float_test (const char *filename, int format, int allow_fd) ;
  1931. static void multi_seek_test (const char * filename, int format) ;
  1932. static void write_seek_extend_test (const char * filename, int format) ;
  1933. static void
  1934. pcm_test_float (const char *filename, int format, int long_file_ok)
  1935. { SF_INFO sfinfo ;
  1936. float *orig, *test ;
  1937. int k, items, allow_fd ;
  1938. /* Sd2 files cannot be opened from an existing file descriptor. */
  1939. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  1940. print_test_name ("pcm_test_float", filename) ;
  1941. sfinfo.samplerate = 44100 ;
  1942. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1943. sfinfo.channels = 1 ;
  1944. sfinfo.format = format ;
  1945. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
  1946. orig = orig_data.f ;
  1947. test = test_data.f ;
  1948. /* Make this a macro so gdb steps over it in one go. */
  1949. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  1950. items = DATA_LENGTH ;
  1951. /* Some test broken out here. */
  1952. mono_float_test (filename, format, long_file_ok, allow_fd) ;
  1953. /* Sub format DWVW does not allow seeking. */
  1954. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  1955. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  1956. { unlink (filename) ;
  1957. printf ("no seek : okn") ;
  1958. return ;
  1959. } ;
  1960. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1961. mono_rdwr_float_test (filename, format, long_file_ok, allow_fd) ;
  1962. /* If the format doesn't support stereo we're done. */
  1963. sfinfo.channels = 2 ;
  1964. if (sf_format_check (&sfinfo) == 0)
  1965. { unlink (filename) ;
  1966. puts ("no stereo : ok") ;
  1967. return ;
  1968. } ;
  1969. stereo_float_test (filename, format, long_file_ok, allow_fd) ;
  1970. /* New read/write test. Not sure if this is needed yet. */
  1971. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  1972. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  1973. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  1974. new_rdwr_float_test (filename, format, allow_fd) ;
  1975. delete_file (format, filename) ;
  1976. puts ("ok") ;
  1977. return ;
  1978. } /* pcm_test_float */
  1979. static void
  1980. mono_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
  1981. { SNDFILE *file ;
  1982. SF_INFO sfinfo ;
  1983. float *orig, *test ;
  1984. sf_count_t count ;
  1985. int k, items ;
  1986. sfinfo.samplerate = 44100 ;
  1987. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  1988. sfinfo.channels = 1 ;
  1989. sfinfo.format = format ;
  1990. orig = orig_data.f ;
  1991. test = test_data.f ;
  1992. items = DATA_LENGTH ;
  1993. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  1994. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  1995. test_write_float_or_die (file, 0, orig, items, __LINE__) ;
  1996. sf_write_sync (file) ;
  1997. test_write_float_or_die (file, 0, orig, items, __LINE__) ;
  1998. sf_write_sync (file) ;
  1999. /* Add non-audio data after the audio. */
  2000. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  2001. sf_close (file) ;
  2002. memset (test, 0, items * sizeof (float)) ;
  2003. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  2004. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  2005. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  2006. if (sfinfo.format != format)
  2007. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  2008. exit (1) ;
  2009. } ;
  2010. if (sfinfo.frames < 2 * items)
  2011. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  2012. exit (1) ;
  2013. } ;
  2014. if (! long_file_ok && sfinfo.frames > 2 * items)
  2015. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  2016. exit (1) ;
  2017. } ;
  2018. if (sfinfo.channels != 1)
  2019. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  2020. exit (1) ;
  2021. } ;
  2022. check_log_buffer_or_die (file, __LINE__) ;
  2023. test_read_float_or_die (file, 0, test, items, __LINE__) ;
  2024. for (k = 0 ; k < items ; k++)
  2025. if (FLOAT_ERROR (orig [k], test [k]))
  2026. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2027. oct_save_float (orig, test, items) ;
  2028. exit (1) ;
  2029. } ;
  2030. /* Seek to start of file. */
  2031. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2032. test_read_float_or_die (file, 0, test, 4, __LINE__) ;
  2033. for (k = 0 ; k < 4 ; k++)
  2034. if (FLOAT_ERROR (orig [k], test [k]))
  2035. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2036. exit (1) ;
  2037. } ;
  2038. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  2039. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  2040. { sf_close (file) ;
  2041. unlink (filename) ;
  2042. printf ("no seek : ") ;
  2043. return ;
  2044. } ;
  2045. /* Seek to offset from start of file. */
  2046. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  2047. test_read_float_or_die (file, 0, test + 10, 4, __LINE__) ;
  2048. for (k = 10 ; k < 14 ; k++)
  2049. if (FLOAT_ERROR (orig [k], test [k]))
  2050. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2051. exit (1) ;
  2052. } ;
  2053. /* Seek to offset from current position. */
  2054. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  2055. test_read_float_or_die (file, 0, test + 20, 4, __LINE__) ;
  2056. for (k = 20 ; k < 24 ; k++)
  2057. if (FLOAT_ERROR (orig [k], test [k]))
  2058. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2059. exit (1) ;
  2060. } ;
  2061. /* Seek to offset from end of file. */
  2062. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  2063. test_read_float_or_die (file, 0, test + 10, 4, __LINE__) ;
  2064. for (k = 10 ; k < 14 ; k++)
  2065. if (FLOAT_ERROR (orig [k], test [k]))
  2066. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2067. exit (1) ;
  2068. } ;
  2069. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  2070. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2071. count = 0 ;
  2072. while (count < sfinfo.frames)
  2073. count += sf_read_float (file, test, 311) ;
  2074. /* Check that no error has occurred. */
  2075. if (sf_error (file))
  2076. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  2077. puts (sf_strerror (file)) ;
  2078. exit (1) ;
  2079. } ;
  2080. /* Check that we haven't read beyond EOF. */
  2081. if (count > sfinfo.frames)
  2082. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  2083. exit (1) ;
  2084. } ;
  2085. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  2086. sf_close (file) ;
  2087. multi_seek_test (filename, format) ;
  2088. write_seek_extend_test (filename, format) ;
  2089. } /* mono_float_test */
  2090. static void
  2091. stereo_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
  2092. { SNDFILE *file ;
  2093. SF_INFO sfinfo ;
  2094. float *orig, *test ;
  2095. int k, items, frames ;
  2096. sfinfo.samplerate = 44100 ;
  2097. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2098. sfinfo.channels = 2 ;
  2099. sfinfo.format = format ;
  2100. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
  2101. orig = orig_data.f ;
  2102. test = test_data.f ;
  2103. /* Make this a macro so gdb steps over it in one go. */
  2104. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  2105. items = DATA_LENGTH ;
  2106. frames = items / sfinfo.channels ;
  2107. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  2108. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  2109. test_writef_float_or_die (file, 0, orig, frames, __LINE__) ;
  2110. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  2111. sf_close (file) ;
  2112. memset (test, 0, items * sizeof (float)) ;
  2113. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  2114. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  2115. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  2116. if (sfinfo.format != format)
  2117. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  2118. __LINE__, format, sfinfo.format) ;
  2119. exit (1) ;
  2120. } ;
  2121. if (sfinfo.frames < frames)
  2122. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  2123. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  2124. exit (1) ;
  2125. } ;
  2126. if (! long_file_ok && sfinfo.frames > frames)
  2127. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  2128. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  2129. exit (1) ;
  2130. } ;
  2131. if (sfinfo.channels != 2)
  2132. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  2133. exit (1) ;
  2134. } ;
  2135. check_log_buffer_or_die (file, __LINE__) ;
  2136. test_readf_float_or_die (file, 0, test, frames, __LINE__) ;
  2137. for (k = 0 ; k < items ; k++)
  2138. if (FLOAT_ERROR (test [k], orig [k]))
  2139. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2140. exit (1) ;
  2141. } ;
  2142. /* Seek to start of file. */
  2143. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2144. test_readf_float_or_die (file, 0, test, 2, __LINE__) ;
  2145. for (k = 0 ; k < 4 ; k++)
  2146. if (FLOAT_ERROR (test [k], orig [k]))
  2147. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2148. exit (1) ;
  2149. } ;
  2150. /* Seek to offset from start of file. */
  2151. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  2152. /* Check for errors here. */
  2153. if (sf_error (file))
  2154. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  2155. puts (sf_strerror (file)) ;
  2156. exit (1) ;
  2157. } ;
  2158. if (sf_read_float (file, test, 1) > 0)
  2159. { printf ("Line %d: Should return 0.n", __LINE__) ;
  2160. exit (1) ;
  2161. } ;
  2162. if (! sf_error (file))
  2163. { printf ("Line %d: Should return an error.n", __LINE__) ;
  2164. exit (1) ;
  2165. } ;
  2166. /*-----------------------*/
  2167. test_readf_float_or_die (file, 0, test + 10, 2, __LINE__) ;
  2168. for (k = 20 ; k < 24 ; k++)
  2169. if (FLOAT_ERROR (test [k], orig [k]))
  2170. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2171. exit (1) ;
  2172. } ;
  2173. /* Seek to offset from current position. */
  2174. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  2175. test_readf_float_or_die (file, 0, test + 20, 2, __LINE__) ;
  2176. for (k = 40 ; k < 44 ; k++)
  2177. if (FLOAT_ERROR (test [k], orig [k]))
  2178. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2179. exit (1) ;
  2180. } ;
  2181. /* Seek to offset from end of file. */
  2182. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  2183. test_readf_float_or_die (file, 0, test + 20, 2, __LINE__) ;
  2184. for (k = 20 ; k < 24 ; k++)
  2185. if (FLOAT_ERROR (test [k], orig [k]))
  2186. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2187. exit (1) ;
  2188. } ;
  2189. sf_close (file) ;
  2190. } /* stereo_float_test */
  2191. static void
  2192. mono_rdwr_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
  2193. { SNDFILE *file ;
  2194. SF_INFO sfinfo ;
  2195. float *orig, *test ;
  2196. int k, pass ;
  2197. orig = orig_data.f ;
  2198. test = test_data.f ;
  2199. sfinfo.samplerate = SAMPLE_RATE ;
  2200. sfinfo.frames = DATA_LENGTH ;
  2201. sfinfo.channels = 1 ;
  2202. sfinfo.format = format ;
  2203. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  2204. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  2205. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  2206. unlink (filename) ;
  2207. else
  2208. { /* Create a short file. */
  2209. create_short_file (filename) ;
  2210. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  2211. ** If this returns a valif pointer sf_open() screwed up.
  2212. */
  2213. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  2214. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  2215. exit (1) ;
  2216. } ;
  2217. /* Truncate the file to zero bytes. */
  2218. if (truncate (filename, 0) < 0)
  2219. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  2220. perror (NULL) ;
  2221. exit (1) ;
  2222. } ;
  2223. } ;
  2224. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  2225. ** all the usual data required when opening the file in WRITE mode.
  2226. */
  2227. sfinfo.samplerate = SAMPLE_RATE ;
  2228. sfinfo.frames = DATA_LENGTH ;
  2229. sfinfo.channels = 1 ;
  2230. sfinfo.format = format ;
  2231. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2232. /* Do 3 writes followed by reads. After each, check the data and the current
  2233. ** read and write offsets.
  2234. */
  2235. for (pass = 1 ; pass <= 3 ; pass ++)
  2236. { orig [20] = pass * 2 ;
  2237. /* Write some data. */
  2238. test_write_float_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  2239. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  2240. /* Read what we just wrote. */
  2241. test_read_float_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  2242. /* Check the data. */
  2243. for (k = 0 ; k < DATA_LENGTH ; k++)
  2244. if (FLOAT_ERROR (orig [k], test [k]))
  2245. { printf ("nnLine %d (pass %d) A : Error at sample %d (%g => %g).n", __LINE__, pass, k, orig [k], test [k]) ;
  2246. oct_save_float (orig, test, DATA_LENGTH) ;
  2247. exit (1) ;
  2248. } ;
  2249. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  2250. } ; /* for (pass ...) */
  2251. sf_close (file) ;
  2252. /* Open the file again to check the data. */
  2253. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2254. if (sfinfo.format != format)
  2255. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  2256. exit (1) ;
  2257. } ;
  2258. if (sfinfo.frames < 3 * DATA_LENGTH)
  2259. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  2260. exit (1) ;
  2261. }
  2262. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  2263. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  2264. exit (1) ;
  2265. } ;
  2266. if (sfinfo.channels != 1)
  2267. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  2268. exit (1) ;
  2269. } ;
  2270. if (! long_file_ok)
  2271. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  2272. else
  2273. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  2274. for (pass = 1 ; pass <= 3 ; pass ++)
  2275. { orig [20] = pass * 2 ;
  2276. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  2277. /* Read what we just wrote. */
  2278. test_read_float_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  2279. /* Check the data. */
  2280. for (k = 0 ; k < DATA_LENGTH ; k++)
  2281. if (FLOAT_ERROR (orig [k], test [k]))
  2282. { printf ("nnLine %d (pass %d) B : Error at sample %d (%g => %g).n", __LINE__, pass, k, orig [k], test [k]) ;
  2283. oct_save_float (orig, test, DATA_LENGTH) ;
  2284. exit (1) ;
  2285. } ;
  2286. } ; /* for (pass ...) */
  2287. sf_close (file) ;
  2288. } /* mono_rdwr_float_test */
  2289. static void
  2290. new_rdwr_float_test (const char *filename, int format, int allow_fd)
  2291. { SNDFILE *wfile, *rwfile ;
  2292. SF_INFO sfinfo ;
  2293. float *orig, *test ;
  2294. int items, frames ;
  2295. orig = orig_data.f ;
  2296. test = test_data.f ;
  2297. sfinfo.samplerate = 44100 ;
  2298. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2299. sfinfo.channels = 2 ;
  2300. sfinfo.format = format ;
  2301. items = DATA_LENGTH ;
  2302. frames = items / sfinfo.channels ;
  2303. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  2304. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  2305. test_writef_float_or_die (wfile, 1, orig, frames, __LINE__) ;
  2306. sf_write_sync (wfile) ;
  2307. test_writef_float_or_die (wfile, 2, orig, frames, __LINE__) ;
  2308. sf_write_sync (wfile) ;
  2309. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2310. if (sfinfo.frames != 2 * frames)
  2311. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  2312. exit (1) ;
  2313. } ;
  2314. test_writef_float_or_die (wfile, 3, orig, frames, __LINE__) ;
  2315. test_readf_float_or_die (rwfile, 1, test, frames, __LINE__) ;
  2316. test_readf_float_or_die (rwfile, 2, test, frames, __LINE__) ;
  2317. sf_close (wfile) ;
  2318. sf_close (rwfile) ;
  2319. } /* new_rdwr_float_test */
  2320. /*======================================================================================
  2321. */
  2322. static void mono_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  2323. static void stereo_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  2324. static void mono_rdwr_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
  2325. static void new_rdwr_double_test (const char *filename, int format, int allow_fd) ;
  2326. static void multi_seek_test (const char * filename, int format) ;
  2327. static void write_seek_extend_test (const char * filename, int format) ;
  2328. static void
  2329. pcm_test_double (const char *filename, int format, int long_file_ok)
  2330. { SF_INFO sfinfo ;
  2331. double *orig, *test ;
  2332. int k, items, allow_fd ;
  2333. /* Sd2 files cannot be opened from an existing file descriptor. */
  2334. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  2335. print_test_name ("pcm_test_double", filename) ;
  2336. sfinfo.samplerate = 44100 ;
  2337. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2338. sfinfo.channels = 1 ;
  2339. sfinfo.format = format ;
  2340. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
  2341. orig = orig_data.d ;
  2342. test = test_data.d ;
  2343. /* Make this a macro so gdb steps over it in one go. */
  2344. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  2345. items = DATA_LENGTH ;
  2346. /* Some test broken out here. */
  2347. mono_double_test (filename, format, long_file_ok, allow_fd) ;
  2348. /* Sub format DWVW does not allow seeking. */
  2349. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  2350. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  2351. { unlink (filename) ;
  2352. printf ("no seek : okn") ;
  2353. return ;
  2354. } ;
  2355. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  2356. mono_rdwr_double_test (filename, format, long_file_ok, allow_fd) ;
  2357. /* If the format doesn't support stereo we're done. */
  2358. sfinfo.channels = 2 ;
  2359. if (sf_format_check (&sfinfo) == 0)
  2360. { unlink (filename) ;
  2361. puts ("no stereo : ok") ;
  2362. return ;
  2363. } ;
  2364. stereo_double_test (filename, format, long_file_ok, allow_fd) ;
  2365. /* New read/write test. Not sure if this is needed yet. */
  2366. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF &&
  2367. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC &&
  2368. (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
  2369. new_rdwr_double_test (filename, format, allow_fd) ;
  2370. delete_file (format, filename) ;
  2371. puts ("ok") ;
  2372. return ;
  2373. } /* pcm_test_double */
  2374. static void
  2375. mono_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
  2376. { SNDFILE *file ;
  2377. SF_INFO sfinfo ;
  2378. double *orig, *test ;
  2379. sf_count_t count ;
  2380. int k, items ;
  2381. sfinfo.samplerate = 44100 ;
  2382. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2383. sfinfo.channels = 1 ;
  2384. sfinfo.format = format ;
  2385. orig = orig_data.d ;
  2386. test = test_data.d ;
  2387. items = DATA_LENGTH ;
  2388. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  2389. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  2390. test_write_double_or_die (file, 0, orig, items, __LINE__) ;
  2391. sf_write_sync (file) ;
  2392. test_write_double_or_die (file, 0, orig, items, __LINE__) ;
  2393. sf_write_sync (file) ;
  2394. /* Add non-audio data after the audio. */
  2395. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  2396. sf_close (file) ;
  2397. memset (test, 0, items * sizeof (double)) ;
  2398. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  2399. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  2400. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  2401. if (sfinfo.format != format)
  2402. { printf ("nnLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  2403. exit (1) ;
  2404. } ;
  2405. if (sfinfo.frames < 2 * items)
  2406. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too short). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  2407. exit (1) ;
  2408. } ;
  2409. if (! long_file_ok && sfinfo.frames > 2 * items)
  2410. { printf ("nnLine %d : Mono : Incorrect number of frames in file (too long). (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), items) ;
  2411. exit (1) ;
  2412. } ;
  2413. if (sfinfo.channels != 1)
  2414. { printf ("nnLine %d : Mono : Incorrect number of channels in file.n", __LINE__) ;
  2415. exit (1) ;
  2416. } ;
  2417. check_log_buffer_or_die (file, __LINE__) ;
  2418. test_read_double_or_die (file, 0, test, items, __LINE__) ;
  2419. for (k = 0 ; k < items ; k++)
  2420. if (FLOAT_ERROR (orig [k], test [k]))
  2421. { printf ("nnLine %d: Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2422. oct_save_double (orig, test, items) ;
  2423. exit (1) ;
  2424. } ;
  2425. /* Seek to start of file. */
  2426. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2427. test_read_double_or_die (file, 0, test, 4, __LINE__) ;
  2428. for (k = 0 ; k < 4 ; k++)
  2429. if (FLOAT_ERROR (orig [k], test [k]))
  2430. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2431. exit (1) ;
  2432. } ;
  2433. if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
  2434. (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
  2435. { sf_close (file) ;
  2436. unlink (filename) ;
  2437. printf ("no seek : ") ;
  2438. return ;
  2439. } ;
  2440. /* Seek to offset from start of file. */
  2441. test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
  2442. test_read_double_or_die (file, 0, test + 10, 4, __LINE__) ;
  2443. for (k = 10 ; k < 14 ; k++)
  2444. if (FLOAT_ERROR (orig [k], test [k]))
  2445. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2446. exit (1) ;
  2447. } ;
  2448. /* Seek to offset from current position. */
  2449. test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
  2450. test_read_double_or_die (file, 0, test + 20, 4, __LINE__) ;
  2451. for (k = 20 ; k < 24 ; k++)
  2452. if (FLOAT_ERROR (orig [k], test [k]))
  2453. { printf ("nnLine %d : Mono : Incorrect sample A (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2454. exit (1) ;
  2455. } ;
  2456. /* Seek to offset from end of file. */
  2457. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  2458. test_read_double_or_die (file, 0, test + 10, 4, __LINE__) ;
  2459. for (k = 10 ; k < 14 ; k++)
  2460. if (FLOAT_ERROR (orig [k], test [k]))
  2461. { printf ("nnLine %d : Mono : Incorrect sample D (#%d : %g => %g).n", __LINE__, k, test [k], orig [k]) ;
  2462. exit (1) ;
  2463. } ;
  2464. /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
  2465. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2466. count = 0 ;
  2467. while (count < sfinfo.frames)
  2468. count += sf_read_double (file, test, 311) ;
  2469. /* Check that no error has occurred. */
  2470. if (sf_error (file))
  2471. { printf ("nnLine %d : Mono : error where there shouldn't have been one.n", __LINE__) ;
  2472. puts (sf_strerror (file)) ;
  2473. exit (1) ;
  2474. } ;
  2475. /* Check that we haven't read beyond EOF. */
  2476. if (count > sfinfo.frames)
  2477. { printf ("nnLines %d : read past end of file (%ld should be %ld)n", __LINE__, (long) count, (long) sfinfo.frames) ;
  2478. exit (1) ;
  2479. } ;
  2480. test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
  2481. sf_close (file) ;
  2482. multi_seek_test (filename, format) ;
  2483. write_seek_extend_test (filename, format) ;
  2484. } /* mono_double_test */
  2485. static void
  2486. stereo_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
  2487. { SNDFILE *file ;
  2488. SF_INFO sfinfo ;
  2489. double *orig, *test ;
  2490. int k, items, frames ;
  2491. sfinfo.samplerate = 44100 ;
  2492. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2493. sfinfo.channels = 2 ;
  2494. sfinfo.format = format ;
  2495. gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
  2496. orig = orig_data.d ;
  2497. test = test_data.d ;
  2498. /* Make this a macro so gdb steps over it in one go. */
  2499. CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
  2500. items = DATA_LENGTH ;
  2501. frames = items / sfinfo.channels ;
  2502. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  2503. sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
  2504. test_writef_double_or_die (file, 0, orig, frames, __LINE__) ;
  2505. sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
  2506. sf_close (file) ;
  2507. memset (test, 0, items * sizeof (double)) ;
  2508. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  2509. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  2510. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
  2511. if (sfinfo.format != format)
  2512. { printf ("nnLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).n",
  2513. __LINE__, format, sfinfo.format) ;
  2514. exit (1) ;
  2515. } ;
  2516. if (sfinfo.frames < frames)
  2517. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too short). (%ld should be %d)n",
  2518. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  2519. exit (1) ;
  2520. } ;
  2521. if (! long_file_ok && sfinfo.frames > frames)
  2522. { printf ("nnLine %d : Stereo : Incorrect number of frames in file (too long). (%ld should be %d)n",
  2523. __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), frames) ;
  2524. exit (1) ;
  2525. } ;
  2526. if (sfinfo.channels != 2)
  2527. { printf ("nnLine %d : Stereo : Incorrect number of channels in file.n", __LINE__) ;
  2528. exit (1) ;
  2529. } ;
  2530. check_log_buffer_or_die (file, __LINE__) ;
  2531. test_readf_double_or_die (file, 0, test, frames, __LINE__) ;
  2532. for (k = 0 ; k < items ; k++)
  2533. if (FLOAT_ERROR (test [k], orig [k]))
  2534. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2535. exit (1) ;
  2536. } ;
  2537. /* Seek to start of file. */
  2538. test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
  2539. test_readf_double_or_die (file, 0, test, 2, __LINE__) ;
  2540. for (k = 0 ; k < 4 ; k++)
  2541. if (FLOAT_ERROR (test [k], orig [k]))
  2542. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2543. exit (1) ;
  2544. } ;
  2545. /* Seek to offset from start of file. */
  2546. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  2547. /* Check for errors here. */
  2548. if (sf_error (file))
  2549. { printf ("Line %d: Should NOT return an error.n", __LINE__) ;
  2550. puts (sf_strerror (file)) ;
  2551. exit (1) ;
  2552. } ;
  2553. if (sf_read_double (file, test, 1) > 0)
  2554. { printf ("Line %d: Should return 0.n", __LINE__) ;
  2555. exit (1) ;
  2556. } ;
  2557. if (! sf_error (file))
  2558. { printf ("Line %d: Should return an error.n", __LINE__) ;
  2559. exit (1) ;
  2560. } ;
  2561. /*-----------------------*/
  2562. test_readf_double_or_die (file, 0, test + 10, 2, __LINE__) ;
  2563. for (k = 20 ; k < 24 ; k++)
  2564. if (FLOAT_ERROR (test [k], orig [k]))
  2565. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2566. exit (1) ;
  2567. } ;
  2568. /* Seek to offset from current position. */
  2569. test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
  2570. test_readf_double_or_die (file, 0, test + 20, 2, __LINE__) ;
  2571. for (k = 40 ; k < 44 ; k++)
  2572. if (FLOAT_ERROR (test [k], orig [k]))
  2573. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2574. exit (1) ;
  2575. } ;
  2576. /* Seek to offset from end of file. */
  2577. test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
  2578. test_readf_double_or_die (file, 0, test + 20, 2, __LINE__) ;
  2579. for (k = 20 ; k < 24 ; k++)
  2580. if (FLOAT_ERROR (test [k], orig [k]))
  2581. { printf ("nnLine %d : Stereo : Incorrect sample (#%d : %g => %g).n", __LINE__, k, orig [k], test [k]) ;
  2582. exit (1) ;
  2583. } ;
  2584. sf_close (file) ;
  2585. } /* stereo_double_test */
  2586. static void
  2587. mono_rdwr_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
  2588. { SNDFILE *file ;
  2589. SF_INFO sfinfo ;
  2590. double *orig, *test ;
  2591. int k, pass ;
  2592. orig = orig_data.d ;
  2593. test = test_data.d ;
  2594. sfinfo.samplerate = SAMPLE_RATE ;
  2595. sfinfo.frames = DATA_LENGTH ;
  2596. sfinfo.channels = 1 ;
  2597. sfinfo.format = format ;
  2598. if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
  2599. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
  2600. || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
  2601. unlink (filename) ;
  2602. else
  2603. { /* Create a short file. */
  2604. create_short_file (filename) ;
  2605. /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
  2606. ** If this returns a valif pointer sf_open() screwed up.
  2607. */
  2608. if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
  2609. { printf ("nnLine %d: sf_open should (SFM_RDWR) have failed but didn't.n", __LINE__) ;
  2610. exit (1) ;
  2611. } ;
  2612. /* Truncate the file to zero bytes. */
  2613. if (truncate (filename, 0) < 0)
  2614. { printf ("nnLine %d: truncate (%s) failed", __LINE__, filename) ;
  2615. perror (NULL) ;
  2616. exit (1) ;
  2617. } ;
  2618. } ;
  2619. /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
  2620. ** all the usual data required when opening the file in WRITE mode.
  2621. */
  2622. sfinfo.samplerate = SAMPLE_RATE ;
  2623. sfinfo.frames = DATA_LENGTH ;
  2624. sfinfo.channels = 1 ;
  2625. sfinfo.format = format ;
  2626. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2627. /* Do 3 writes followed by reads. After each, check the data and the current
  2628. ** read and write offsets.
  2629. */
  2630. for (pass = 1 ; pass <= 3 ; pass ++)
  2631. { orig [20] = pass * 2 ;
  2632. /* Write some data. */
  2633. test_write_double_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
  2634. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
  2635. /* Read what we just wrote. */
  2636. test_read_double_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
  2637. /* Check the data. */
  2638. for (k = 0 ; k < DATA_LENGTH ; k++)
  2639. if (FLOAT_ERROR (orig [k], test [k]))
  2640. { printf ("nnLine %d (pass %d) A : Error at sample %d (%g => %g).n", __LINE__, pass, k, orig [k], test [k]) ;
  2641. oct_save_double (orig, test, DATA_LENGTH) ;
  2642. exit (1) ;
  2643. } ;
  2644. test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
  2645. } ; /* for (pass ...) */
  2646. sf_close (file) ;
  2647. /* Open the file again to check the data. */
  2648. file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2649. if (sfinfo.format != format)
  2650. { printf ("nnLine %d : Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, format, sfinfo.format) ;
  2651. exit (1) ;
  2652. } ;
  2653. if (sfinfo.frames < 3 * DATA_LENGTH)
  2654. { printf ("nnLine %d : Not enough frames in file. (%ld < %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  2655. exit (1) ;
  2656. }
  2657. if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
  2658. { printf ("nnLine %d : Incorrect number of frames in file. (%ld should be %d)n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 3 * DATA_LENGTH ) ;
  2659. exit (1) ;
  2660. } ;
  2661. if (sfinfo.channels != 1)
  2662. { printf ("nnLine %d : Incorrect number of channels in file.n", __LINE__) ;
  2663. exit (1) ;
  2664. } ;
  2665. if (! long_file_ok)
  2666. test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
  2667. else
  2668. test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
  2669. for (pass = 1 ; pass <= 3 ; pass ++)
  2670. { orig [20] = pass * 2 ;
  2671. test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
  2672. /* Read what we just wrote. */
  2673. test_read_double_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
  2674. /* Check the data. */
  2675. for (k = 0 ; k < DATA_LENGTH ; k++)
  2676. if (FLOAT_ERROR (orig [k], test [k]))
  2677. { printf ("nnLine %d (pass %d) B : Error at sample %d (%g => %g).n", __LINE__, pass, k, orig [k], test [k]) ;
  2678. oct_save_double (orig, test, DATA_LENGTH) ;
  2679. exit (1) ;
  2680. } ;
  2681. } ; /* for (pass ...) */
  2682. sf_close (file) ;
  2683. } /* mono_rdwr_double_test */
  2684. static void
  2685. new_rdwr_double_test (const char *filename, int format, int allow_fd)
  2686. { SNDFILE *wfile, *rwfile ;
  2687. SF_INFO sfinfo ;
  2688. double *orig, *test ;
  2689. int items, frames ;
  2690. orig = orig_data.d ;
  2691. test = test_data.d ;
  2692. sfinfo.samplerate = 44100 ;
  2693. sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
  2694. sfinfo.channels = 2 ;
  2695. sfinfo.format = format ;
  2696. items = DATA_LENGTH ;
  2697. frames = items / sfinfo.channels ;
  2698. wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
  2699. sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
  2700. test_writef_double_or_die (wfile, 1, orig, frames, __LINE__) ;
  2701. sf_write_sync (wfile) ;
  2702. test_writef_double_or_die (wfile, 2, orig, frames, __LINE__) ;
  2703. sf_write_sync (wfile) ;
  2704. rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
  2705. if (sfinfo.frames != 2 * frames)
  2706. { printf ("nnLine %d : incorrect number of frames in file (%ld should be %d)nn", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * frames) ;
  2707. exit (1) ;
  2708. } ;
  2709. test_writef_double_or_die (wfile, 3, orig, frames, __LINE__) ;
  2710. test_readf_double_or_die (rwfile, 1, test, frames, __LINE__) ;
  2711. test_readf_double_or_die (rwfile, 2, test, frames, __LINE__) ;
  2712. sf_close (wfile) ;
  2713. sf_close (rwfile) ;
  2714. } /* new_rdwr_double_test */
  2715. /*----------------------------------------------------------------------------------------
  2716. */
  2717. static void
  2718. empty_file_test (const char *filename, int format)
  2719. { SNDFILE *file ;
  2720. SF_INFO info ;
  2721. int allow_fd ;
  2722. /* Sd2 files cannot be opened from an existing file descriptor. */
  2723. allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
  2724. print_test_name ("empty_file_test", filename) ;
  2725. unlink (filename) ;
  2726. info.samplerate = 48000 ;
  2727. info.channels = 2 ;
  2728. info.format = format ;
  2729. if (sf_format_check (&info) == SF_FALSE)
  2730. { info.channels = 1 ;
  2731. if (sf_format_check (&info) == SF_FALSE)
  2732. { puts ("invalid file format") ;
  2733. return ;
  2734. } ;
  2735. } ;
  2736. /* Create an empty file. */
  2737. file = test_open_file_or_die (filename, SFM_WRITE, &info, allow_fd, __LINE__) ;
  2738. sf_close (file) ;
  2739. /* Open for read and check the length. */
  2740. file = test_open_file_or_die (filename, SFM_READ, &info, allow_fd, __LINE__) ;
  2741. if (SF_COUNT_TO_LONG (info.frames) != 0)
  2742. { printf ("nnError : frame count (%ld) should be zero.n", SF_COUNT_TO_LONG (info.frames)) ;
  2743. exit (1) ;
  2744. } ;
  2745. sf_close (file) ;
  2746. /* Open for read/write and check the length. */
  2747. file = test_open_file_or_die (filename, SFM_RDWR, &info, allow_fd, __LINE__) ;
  2748. if (SF_COUNT_TO_LONG (info.frames) != 0)
  2749. { printf ("nnError : frame count (%ld) should be zero.n", SF_COUNT_TO_LONG (info.frames)) ;
  2750. exit (1) ;
  2751. } ;
  2752. sf_close (file) ;
  2753. /* Open for read and check the length. */
  2754. file = test_open_file_or_die (filename, SFM_READ, &info, allow_fd, __LINE__) ;
  2755. if (SF_COUNT_TO_LONG (info.frames) != 0)
  2756. { printf ("nnError : frame count (%ld) should be zero.n", SF_COUNT_TO_LONG (info.frames)) ;
  2757. exit (1) ;
  2758. } ;
  2759. sf_close (file) ;
  2760. check_open_file_count_or_die (__LINE__) ;
  2761. unlink (filename) ;
  2762. puts ("ok") ;
  2763. return ;
  2764. } /* empty_file_test */
  2765. /*----------------------------------------------------------------------------------------
  2766. */
  2767. static void
  2768. create_short_file (const char *filename)
  2769. { FILE *file ;
  2770. if (! (file = fopen (filename, "w")))
  2771. { printf ("create_short_file : fopen (%s, "w") failed.", filename) ;
  2772. fflush (stdout) ;
  2773. perror (NULL) ;
  2774. exit (1) ;
  2775. } ;
  2776. fprintf (file, "This is the file data.n") ;
  2777. fclose (file) ;
  2778. } /* create_short_file */
  2779. #if (defined (WIN32) || defined (__WIN32))
  2780. /* Win32 does not have truncate (nor does it have the POSIX function ftruncate).
  2781. ** Hack somethng up here to over come this. This function can only truncate to a
  2782. ** length of zero.
  2783. */
  2784. static int
  2785. truncate (const char *filename, int ignored)
  2786. { int fd ;
  2787. ignored = 0 ;
  2788. if ((fd = open (filename, O_RDWR | O_TRUNC | O_BINARY)) < 0)
  2789. return 0 ;
  2790. close (fd) ;
  2791. return 0 ;
  2792. } /* truncate */
  2793. #endif
  2794. static void
  2795. multi_seek_test (const char * filename, int format)
  2796. { SNDFILE * file ;
  2797. SF_INFO info ;
  2798. sf_count_t pos ;
  2799. int k ;
  2800. /* This test doesn't work on the following. */
  2801. switch (format & SF_FORMAT_TYPEMASK)
  2802. { case SF_FORMAT_RAW :
  2803. return ;
  2804. default :
  2805. break ;
  2806. } ;
  2807. memset (&info, 0, sizeof (info)) ;
  2808. generate_file (filename, format, 88200) ;
  2809. file = test_open_file_or_die (filename, SFM_READ, &info, SF_FALSE, __LINE__) ;
  2810. for (k = 0 ; k < 10 ; k++)
  2811. { pos = info.frames / (k + 2) ;
  2812. test_seek_or_die (file, pos, SEEK_SET, pos, info.channels, __LINE__) ;
  2813. } ;
  2814. sf_close (file) ;
  2815. } /* multi_seek_test */
  2816. static void
  2817. write_seek_extend_test (const char * filename, int format)
  2818. { SNDFILE * file ;
  2819. SF_INFO info ;
  2820. short *orig, *test ;
  2821. unsigned items, k ;
  2822. /* This test doesn't work on the following. */
  2823. switch (format & SF_FORMAT_TYPEMASK)
  2824. { case SF_FORMAT_FLAC :
  2825. case SF_FORMAT_HTK :
  2826. case SF_FORMAT_PAF :
  2827. case SF_FORMAT_SDS :
  2828. case SF_FORMAT_SVX :
  2829. return ;
  2830. default :
  2831. break ;
  2832. } ;
  2833. memset (&info, 0, sizeof (info)) ;
  2834. info.samplerate = 48000 ;
  2835. info.channels = 1 ;
  2836. info.format = format ;
  2837. items = 512 ;
  2838. exit_if_true (items > ARRAY_LEN (orig_data.s), "Line %d : Bad assumption.n", __LINE__) ;
  2839. orig = orig_data.s ;
  2840. test = test_data.s ;
  2841. for (k = 0 ; k < ARRAY_LEN (orig_data.s) ; k++)
  2842. orig [k] = 0x3fff ;
  2843. file = test_open_file_or_die (filename, SFM_WRITE, &info, SF_FALSE, __LINE__) ;
  2844. test_write_short_or_die (file, 0, orig, items, __LINE__) ;
  2845. /* Extend the file using a seek. */
  2846. test_seek_or_die (file, 2 * items, SEEK_SET, 2 * items, info.channels, __LINE__) ;
  2847. test_writef_short_or_die (file, 0, orig, items, __LINE__) ;
  2848. sf_close (file) ;
  2849. file = test_open_file_or_die (filename, SFM_READ, &info, SF_FALSE, __LINE__) ;
  2850. test_read_short_or_die (file, 0, test, 3 * items, __LINE__) ;
  2851. sf_close (file) ;
  2852. /* Can't do these formats due to scaling. */
  2853. switch (format & SF_FORMAT_SUBMASK)
  2854. { case SF_FORMAT_PCM_S8 :
  2855. case SF_FORMAT_PCM_U8 :
  2856. return ;
  2857. default :
  2858. break ;
  2859. } ;
  2860. for (k = 0 ; k < items ; k++)
  2861. { exit_if_true (test [k] != 0x3fff, "Line %d : test [%d] == %d, should be 0x3fff.n", __LINE__, k, test [k]) ;
  2862. exit_if_true (test [items + k] != 0, "Line %d : test [%d] == %d, should be 0.n", __LINE__, items + k, test [items + k]) ;
  2863. exit_if_true (test [2 * items + k] != 0x3fff, "Line %d : test [%d] == %d, should be 0x3fff.n", __LINE__, 2 * items + k, test [2 * items + k]) ;
  2864. } ;
  2865. return ;
  2866. } /* write_seek_extend_test */