1 /*
2 ** Copyright (C) 1999-2017 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
19 #include "sfconfig.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include <inttypes.h>
26
27
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #else
31 #include "sf_unistd.h"
32 #endif
33
34 #include <sndfile.h>
35
36 #include "utils.h"
37 #include "generate.h"
38
39 #define SAMPLE_RATE 11025
40 #define DATA_LENGTH (1 << 12)
41
42 #define SILLY_WRITE_COUNT (234)
43
44 static void pcm_test_char (const char *str, int format, int long_file_ok) ;
45 static void pcm_test_short (const char *str, int format, int long_file_ok) ;
46 static void pcm_test_20bit (const char *str, int format, int long_file_ok) ;
47 static void pcm_test_24bit (const char *str, int format, int long_file_ok) ;
48 static void pcm_test_int (const char *str, int format, int long_file_ok) ;
49 static void pcm_test_float (const char *str, int format, int long_file_ok) ;
50 static void pcm_test_double (const char *str, int format, int long_file_ok) ;
51
52 static void empty_file_test (const char *filename, int format) ;
53
54 typedef union
55 { double d [DATA_LENGTH] ;
56 float f [DATA_LENGTH] ;
57 int i [DATA_LENGTH] ;
58 short s [DATA_LENGTH] ;
59 char c [DATA_LENGTH] ;
60 } BUFFER ;
61
62 static BUFFER orig_data ;
63 static BUFFER test_data ;
64
65 int
main(int argc,char ** argv)66 main (int argc, char **argv)
67 { int do_all = 0 ;
68 int test_count = 0 ;
69
70 count_open_files () ;
71
72 if (argc != 2)
73 { printf ("Usage : %s <test>\n", argv [0]) ;
74 printf (" Where <test> is one of the following:\n") ;
75 printf (" wav - test WAV file functions (little endian)\n") ;
76 printf (" aiff - test AIFF file functions (big endian)\n") ;
77 printf (" au - test AU file functions\n") ;
78 printf (" avr - test AVR file functions\n") ;
79 printf (" caf - test CAF file functions\n") ;
80 printf (" raw - test RAW header-less PCM file functions\n") ;
81 printf (" paf - test PAF file functions\n") ;
82 printf (" svx - test 8SVX/16SV file functions\n") ;
83 printf (" nist - test NIST Sphere file functions\n") ;
84 printf (" ircam - test IRCAM file functions\n") ;
85 printf (" voc - Create Voice file functions\n") ;
86 printf (" w64 - Sonic Foundry's W64 file functions\n") ;
87 printf (" flac - test FLAC file functions\n") ;
88 printf (" mpc2k - test MPC 2000 file functions\n") ;
89 printf (" rf64 - test RF64 file functions\n") ;
90 printf (" all - perform all tests\n") ;
91 exit (1) ;
92 } ;
93
94 do_all = !strcmp (argv [1], "all") ;
95
96 if (do_all || ! strcmp (argv [1], "wav"))
97 { pcm_test_char ("char.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_U8, SF_FALSE) ;
98 pcm_test_short ("short.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_16, SF_FALSE) ;
99 pcm_test_24bit ("24bit.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_24, SF_FALSE) ;
100 pcm_test_int ("int.wav" , SF_FORMAT_WAV | SF_FORMAT_PCM_32, SF_FALSE) ;
101
102 pcm_test_char ("char.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_U8, SF_FALSE) ;
103 pcm_test_short ("short.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16, SF_FALSE) ;
104 pcm_test_24bit ("24bit.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_24, SF_FALSE) ;
105 pcm_test_int ("int.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_32, SF_FALSE) ;
106
107 pcm_test_24bit ("24bit.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_PCM_24, SF_FALSE) ;
108 pcm_test_int ("int.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_PCM_32, SF_FALSE) ;
109
110 /* Lite remove start */
111 pcm_test_float ("float.wav" , SF_FORMAT_WAV | SF_FORMAT_FLOAT , SF_FALSE) ;
112 pcm_test_double ("double.wav" , SF_FORMAT_WAV | SF_FORMAT_DOUBLE, SF_FALSE) ;
113
114 pcm_test_float ("float.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_FLOAT , SF_FALSE) ;
115 pcm_test_double ("double.rifx" , SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_DOUBLE, SF_FALSE) ;
116
117 pcm_test_float ("float.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_FLOAT , SF_FALSE) ;
118 pcm_test_double ("double.wavex" , SF_FORMAT_WAVEX | SF_FORMAT_DOUBLE, SF_FALSE) ;
119 /* Lite remove end */
120
121 empty_file_test ("empty_char.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8) ;
122 empty_file_test ("empty_short.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
123 empty_file_test ("empty_float.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT) ;
124
125 test_count++ ;
126 } ;
127
128 if (do_all || ! strcmp (argv [1], "aiff"))
129 { pcm_test_char ("char_u8.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_U8, SF_FALSE) ;
130 pcm_test_char ("char_s8.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_S8, SF_FALSE) ;
131 pcm_test_short ("short.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
132 pcm_test_24bit ("24bit.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
133 pcm_test_int ("int.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
134
135 pcm_test_short ("short_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
136 pcm_test_24bit ("24bit_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
137 pcm_test_int ("int_sowt.aifc" , SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
138
139 pcm_test_short ("short_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_16, SF_FALSE) ;
140 pcm_test_24bit ("24bit_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_24, SF_FALSE) ;
141 pcm_test_int ("int_twos.aifc" , SF_ENDIAN_BIG | SF_FORMAT_AIFF | SF_FORMAT_PCM_32, SF_FALSE) ;
142
143 /* Lite remove start */
144 pcm_test_short ("dwvw16.aifc", SF_FORMAT_AIFF | SF_FORMAT_DWVW_16, SF_TRUE) ;
145 pcm_test_24bit ("dwvw24.aifc", SF_FORMAT_AIFF | SF_FORMAT_DWVW_24, SF_TRUE) ;
146
147 pcm_test_float ("float.aifc" , SF_FORMAT_AIFF | SF_FORMAT_FLOAT , SF_FALSE) ;
148 pcm_test_double ("double.aifc" , SF_FORMAT_AIFF | SF_FORMAT_DOUBLE, SF_FALSE) ;
149 /* Lite remove end */
150
151 empty_file_test ("empty_char.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_U8) ;
152 empty_file_test ("empty_short.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
153 empty_file_test ("empty_float.aiff", SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ;
154
155 test_count++ ;
156 } ;
157
158 if (do_all || ! strcmp (argv [1], "au"))
159 { pcm_test_char ("char.au" , SF_FORMAT_AU | SF_FORMAT_PCM_S8, SF_FALSE) ;
160 pcm_test_short ("short.au" , SF_FORMAT_AU | SF_FORMAT_PCM_16, SF_FALSE) ;
161 pcm_test_24bit ("24bit.au" , SF_FORMAT_AU | SF_FORMAT_PCM_24, SF_FALSE) ;
162 pcm_test_int ("int.au" , SF_FORMAT_AU | SF_FORMAT_PCM_32, SF_FALSE) ;
163 /* Lite remove start */
164 pcm_test_float ("float.au" , SF_FORMAT_AU | SF_FORMAT_FLOAT , SF_FALSE) ;
165 pcm_test_double ("double.au", SF_FORMAT_AU | SF_FORMAT_DOUBLE, SF_FALSE) ;
166 /* Lite remove end */
167
168 pcm_test_char ("char_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_S8, SF_FALSE) ;
169 pcm_test_short ("short_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_16, SF_FALSE) ;
170 pcm_test_24bit ("24bit_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_24, SF_FALSE) ;
171 pcm_test_int ("int_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_32, SF_FALSE) ;
172 /* Lite remove start */
173 pcm_test_float ("float_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_FLOAT , SF_FALSE) ;
174 pcm_test_double ("double_le.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_DOUBLE, SF_FALSE) ;
175 /* Lite remove end */
176 test_count++ ;
177 } ;
178
179 if (do_all || ! strcmp (argv [1], "caf"))
180 { pcm_test_char ("char.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
181 pcm_test_short ("short.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16, SF_FALSE) ;
182 pcm_test_24bit ("24bit.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_24, SF_FALSE) ;
183 pcm_test_int ("int.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_32, SF_FALSE) ;
184 /* Lite remove start */
185 pcm_test_float ("float.caf" , SF_FORMAT_CAF | SF_FORMAT_FLOAT , SF_FALSE) ;
186 pcm_test_double ("double.caf" , SF_FORMAT_CAF | SF_FORMAT_DOUBLE, SF_FALSE) ;
187 /* Lite remove end */
188
189 pcm_test_short ("short_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_16, SF_FALSE) ;
190 pcm_test_24bit ("24bit_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_24, SF_FALSE) ;
191 pcm_test_int ("int_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_PCM_32, SF_FALSE) ;
192 /* Lite remove start */
193 pcm_test_float ("float_le.caf" , SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_FLOAT , SF_FALSE) ;
194 pcm_test_double ("double_le.caf", SF_ENDIAN_LITTLE | SF_FORMAT_CAF | SF_FORMAT_DOUBLE, SF_FALSE) ;
195
196 pcm_test_short ("alac16.caf" , SF_FORMAT_CAF | SF_FORMAT_ALAC_16, SF_FALSE) ;
197 pcm_test_20bit ("alac20.caf" , SF_FORMAT_CAF | SF_FORMAT_ALAC_20, SF_FALSE) ;
198 pcm_test_24bit ("alac24.caf" , SF_FORMAT_CAF | SF_FORMAT_ALAC_24, SF_FALSE) ;
199 pcm_test_int ("alac32.caf" , SF_FORMAT_CAF | SF_FORMAT_ALAC_32, SF_FALSE) ;
200
201 /* Lite remove end */
202 test_count++ ;
203 } ;
204
205 if (do_all || ! strcmp (argv [1], "raw"))
206 { pcm_test_char ("char_s8.raw" , SF_FORMAT_RAW | SF_FORMAT_PCM_S8, SF_FALSE) ;
207 pcm_test_char ("char_u8.raw" , SF_FORMAT_RAW | SF_FORMAT_PCM_U8, SF_FALSE) ;
208
209 pcm_test_short ("short_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_16, SF_FALSE) ;
210 pcm_test_short ("short_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_16, SF_FALSE) ;
211 pcm_test_24bit ("24bit_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_24, SF_FALSE) ;
212 pcm_test_24bit ("24bit_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_24, SF_FALSE) ;
213 pcm_test_int ("int_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_PCM_32, SF_FALSE) ;
214 pcm_test_int ("int_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_PCM_32, SF_FALSE) ;
215
216 /* Lite remove start */
217 pcm_test_float ("float_le.raw" , SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT , SF_FALSE) ;
218 pcm_test_float ("float_be.raw" , SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT , SF_FALSE) ;
219
220 pcm_test_double ("double_le.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, SF_FALSE) ;
221 pcm_test_double ("double_be.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, SF_FALSE) ;
222 /* Lite remove end */
223 test_count++ ;
224 } ;
225
226 /* Lite remove start */
227 if (do_all || ! strcmp (argv [1], "paf"))
228 { pcm_test_char ("char_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
229 pcm_test_char ("char_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_S8, SF_FALSE) ;
230 pcm_test_short ("short_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_16, SF_FALSE) ;
231 pcm_test_short ("short_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_16, SF_FALSE) ;
232 pcm_test_24bit ("24bit_le.paf", SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_24, SF_TRUE) ;
233 pcm_test_24bit ("24bit_be.paf", SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_24, SF_TRUE) ;
234 test_count++ ;
235 } ;
236
237 if (do_all || ! strcmp (argv [1], "svx"))
238 { pcm_test_char ("char.svx" , SF_FORMAT_SVX | SF_FORMAT_PCM_S8, SF_FALSE) ;
239 pcm_test_short ("short.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_16, SF_FALSE) ;
240
241 empty_file_test ("empty_char.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_S8) ;
242 empty_file_test ("empty_short.svx", SF_FORMAT_SVX | SF_FORMAT_PCM_16) ;
243
244 test_count++ ;
245 } ;
246
247 if (do_all || ! strcmp (argv [1], "nist"))
248 { pcm_test_short ("short_le.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_16, SF_FALSE) ;
249 pcm_test_short ("short_be.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_16, SF_FALSE) ;
250 pcm_test_24bit ("24bit_le.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_24, SF_FALSE) ;
251 pcm_test_24bit ("24bit_be.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_24, SF_FALSE) ;
252 pcm_test_int ("int_le.nist" , SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_PCM_32, SF_FALSE) ;
253 pcm_test_int ("int_be.nist" , SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_PCM_32, SF_FALSE) ;
254
255 test_count++ ;
256 } ;
257
258 if (do_all || ! strcmp (argv [1], "ircam"))
259 { pcm_test_short ("short_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_PCM_16, SF_FALSE) ;
260 pcm_test_short ("short_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_PCM_16, SF_FALSE) ;
261 pcm_test_int ("int_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_PCM_32, SF_FALSE) ;
262 pcm_test_int ("int_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_PCM_32, SF_FALSE) ;
263 pcm_test_float ("float_be.ircam" , SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_FLOAT , SF_FALSE) ;
264 pcm_test_float ("float_le.ircam" , SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_FLOAT , SF_FALSE) ;
265
266 test_count++ ;
267 } ;
268
269 if (do_all || ! strcmp (argv [1], "voc"))
270 { pcm_test_char ("char.voc" , SF_FORMAT_VOC | SF_FORMAT_PCM_U8, SF_FALSE) ;
271 pcm_test_short ("short.voc", SF_FORMAT_VOC | SF_FORMAT_PCM_16, SF_FALSE) ;
272
273 test_count++ ;
274 } ;
275
276 if (do_all || ! strcmp (argv [1], "mat4"))
277 { pcm_test_short ("short_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_PCM_16, SF_FALSE) ;
278 pcm_test_short ("short_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_PCM_16, SF_FALSE) ;
279 pcm_test_int ("int_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_PCM_32, SF_FALSE) ;
280 pcm_test_int ("int_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_PCM_32, SF_FALSE) ;
281 pcm_test_float ("float_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_FLOAT , SF_FALSE) ;
282 pcm_test_float ("float_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_FLOAT , SF_FALSE) ;
283 pcm_test_double ("double_be.mat4" , SF_ENDIAN_BIG | SF_FORMAT_MAT4 | SF_FORMAT_DOUBLE, SF_FALSE) ;
284 pcm_test_double ("double_le.mat4" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT4 | SF_FORMAT_DOUBLE, SF_FALSE) ;
285
286 empty_file_test ("empty_short.mat4", SF_FORMAT_MAT4 | SF_FORMAT_PCM_16) ;
287 empty_file_test ("empty_float.mat4", SF_FORMAT_MAT4 | SF_FORMAT_FLOAT) ;
288 test_count++ ;
289 } ;
290
291 if (do_all || ! strcmp (argv [1], "mat5"))
292 { pcm_test_char ("char_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8, SF_FALSE) ;
293 pcm_test_char ("char_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8, SF_FALSE) ;
294 pcm_test_short ("short_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_16, SF_FALSE) ;
295 pcm_test_short ("short_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_16, SF_FALSE) ;
296 pcm_test_int ("int_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_PCM_32, SF_FALSE) ;
297 pcm_test_int ("int_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_PCM_32, SF_FALSE) ;
298 pcm_test_float ("float_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_FLOAT , SF_FALSE) ;
299 pcm_test_float ("float_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_FLOAT , SF_FALSE) ;
300 pcm_test_double ("double_be.mat5" , SF_ENDIAN_BIG | SF_FORMAT_MAT5 | SF_FORMAT_DOUBLE, SF_FALSE) ;
301 pcm_test_double ("double_le.mat5" , SF_ENDIAN_LITTLE | SF_FORMAT_MAT5 | SF_FORMAT_DOUBLE, SF_FALSE) ;
302
303 increment_open_file_count () ;
304
305 empty_file_test ("empty_char.mat5", SF_FORMAT_MAT5 | SF_FORMAT_PCM_U8) ;
306 empty_file_test ("empty_short.mat5", SF_FORMAT_MAT5 | SF_FORMAT_PCM_16) ;
307 empty_file_test ("empty_float.mat5", SF_FORMAT_MAT5 | SF_FORMAT_FLOAT) ;
308
309 test_count++ ;
310 } ;
311
312 if (do_all || ! strcmp (argv [1], "pvf"))
313 { pcm_test_char ("char.pvf" , SF_FORMAT_PVF | SF_FORMAT_PCM_S8, SF_FALSE) ;
314 pcm_test_short ("short.pvf", SF_FORMAT_PVF | SF_FORMAT_PCM_16, SF_FALSE) ;
315 pcm_test_int ("int.pvf" , SF_FORMAT_PVF | SF_FORMAT_PCM_32, SF_FALSE) ;
316 test_count++ ;
317 } ;
318
319 if (do_all || ! strcmp (argv [1], "htk"))
320 { pcm_test_short ("short.htk", SF_FORMAT_HTK | SF_FORMAT_PCM_16, SF_FALSE) ;
321 test_count++ ;
322 } ;
323
324 if (do_all || ! strcmp (argv [1], "mpc2k"))
325 { pcm_test_short ("short.mpc", SF_FORMAT_MPC2K | SF_FORMAT_PCM_16, SF_FALSE) ;
326 test_count++ ;
327 } ;
328
329 if (do_all || ! strcmp (argv [1], "avr"))
330 { pcm_test_char ("char_u8.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_U8, SF_FALSE) ;
331 pcm_test_char ("char_s8.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_S8, SF_FALSE) ;
332 pcm_test_short ("short.avr" , SF_FORMAT_AVR | SF_FORMAT_PCM_16, SF_FALSE) ;
333 test_count++ ;
334 } ;
335 /* Lite remove end */
336
337 if (do_all || ! strcmp (argv [1], "w64"))
338 { pcm_test_char ("char.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_U8, SF_FALSE) ;
339 pcm_test_short ("short.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_16, SF_FALSE) ;
340 pcm_test_24bit ("24bit.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_24, SF_FALSE) ;
341 pcm_test_int ("int.w64" , SF_FORMAT_W64 | SF_FORMAT_PCM_32, SF_FALSE) ;
342 /* Lite remove start */
343 pcm_test_float ("float.w64" , SF_FORMAT_W64 | SF_FORMAT_FLOAT , SF_FALSE) ;
344 pcm_test_double ("double.w64" , SF_FORMAT_W64 | SF_FORMAT_DOUBLE, SF_FALSE) ;
345 /* Lite remove end */
346
347 empty_file_test ("empty_char.w64", SF_FORMAT_W64 | SF_FORMAT_PCM_U8) ;
348 empty_file_test ("empty_short.w64", SF_FORMAT_W64 | SF_FORMAT_PCM_16) ;
349 empty_file_test ("empty_float.w64", SF_FORMAT_W64 | SF_FORMAT_FLOAT) ;
350
351 test_count++ ;
352 } ;
353
354 if (do_all || ! strcmp (argv [1], "sds"))
355 { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_FALSE) ;
356 pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_FALSE) ;
357 pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_FALSE) ;
358
359 empty_file_test ("empty_char.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_S8) ;
360 empty_file_test ("empty_short.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_16) ;
361
362 test_count++ ;
363 } ;
364
365 if (do_all || ! strcmp (argv [1], "sd2"))
366 { pcm_test_char ("char.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_S8, SF_TRUE) ;
367 pcm_test_short ("short.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_16, SF_TRUE) ;
368 pcm_test_24bit ("24bit.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_24, SF_TRUE) ;
369 pcm_test_int ("32bit.sd2" , SF_FORMAT_SD2 | SF_FORMAT_PCM_32, SF_TRUE) ;
370 test_count++ ;
371 } ;
372
373 if (do_all || ! strcmp (argv [1], "flac"))
374 { if (HAVE_EXTERNAL_XIPH_LIBS)
375 { pcm_test_char ("char.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_S8, SF_TRUE) ;
376 pcm_test_short ("short.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_16, SF_TRUE) ;
377 pcm_test_24bit ("24bit.flac" , SF_FORMAT_FLAC | SF_FORMAT_PCM_24, SF_TRUE) ;
378 }
379 else
380 puts (" No FLAC tests because FLAC support was not compiled in.") ;
381 test_count++ ;
382 } ;
383
384 if (do_all || ! strcmp (argv [1], "rf64"))
385 { pcm_test_char ("char.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_U8, SF_FALSE) ;
386 pcm_test_short ("short.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_16, SF_FALSE) ;
387 pcm_test_24bit ("24bit.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_24, SF_FALSE) ;
388 pcm_test_int ("int.rf64" , SF_FORMAT_RF64 | SF_FORMAT_PCM_32, SF_FALSE) ;
389
390 /* Lite remove start */
391 pcm_test_float ("float.rf64" , SF_FORMAT_RF64 | SF_FORMAT_FLOAT , SF_FALSE) ;
392 pcm_test_double ("double.rf64" , SF_FORMAT_RF64 | SF_FORMAT_DOUBLE, SF_FALSE) ;
393 empty_file_test ("empty_char.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_U8) ;
394 empty_file_test ("empty_short.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
395 empty_file_test ("empty_float.rf64", SF_FORMAT_RF64 | SF_FORMAT_FLOAT) ;
396 /* Lite remove end */
397
398 test_count++ ;
399 } ;
400
401 if (test_count == 0)
402 { printf ("Mono : ************************************\n") ;
403 printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
404 printf ("Mono : ************************************\n") ;
405 return 1 ;
406 } ;
407
408 /* Only open file descriptors should be stdin, stdout and stderr. */
409 check_open_file_count_or_die (__LINE__) ;
410
411 return 0 ;
412 } /* main */
413
414 /*============================================================================================
415 ** Helper functions and macros.
416 */
417
418 static void create_short_file (const char *filename) ;
419
420 #define CHAR_ERROR(x, y) (abs ((x) - (y)) > 255)
421 #define INT_ERROR(x, y) (((x) - (y)) != 0)
422 #define BIT_20_ERROR(x, y) (abs ((x) - (y)) > 4095)
423 #define TRIBYTE_ERROR(x, y) (abs ((x) - (y)) > 255)
424 #define FLOAT_ERROR(x, y) (fabs ((x) - (y)) > 1e-5)
425
426 #define CONVERT_DATA(k, len, new, orig) \
427 { for ((k) = 0 ; (k) < (len) ; (k) ++) \
428 (new) [k] = (orig) [k] ; \
429 }
430
431
432 /*======================================================================================
433 */
434
435 static void mono_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
436 static void stereo_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
437 static void mono_rdwr_char_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
438 static void new_rdwr_char_test (const char *filename, int format, int allow_fd) ;
439 static void multi_seek_test (const char * filename, int format) ;
440 static void write_seek_extend_test (const char * filename, int format) ;
441
442 static void
pcm_test_char(const char * filename,int format,int long_file_ok)443 pcm_test_char (const char *filename, int format, int long_file_ok)
444 { SF_INFO sfinfo ;
445 short *orig ;
446 int k, allow_fd ;
447
448 /* Sd2 files cannot be opened from an existing file descriptor. */
449 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
450
451 print_test_name ("pcm_test_char", filename) ;
452
453 sfinfo.samplerate = 44100 ;
454 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
455 sfinfo.channels = 1 ;
456 sfinfo.format = format ;
457
458 test_sf_format_or_die (&sfinfo, __LINE__) ;
459
460 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
461
462 orig = orig_data.s ;
463
464 /* Make this a macro so gdb steps over it in one go. */
465 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
466
467 /* Some test broken out here. */
468
469 mono_char_test (filename, format, long_file_ok, allow_fd) ;
470
471 /* Sub format DWVW does not allow seeking. */
472 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
473 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
474 { unlink (filename) ;
475 printf ("no seek : ok\n") ;
476 return ;
477 } ;
478
479 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
480 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
481 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
482 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
483 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
484 )
485 mono_rdwr_char_test (filename, format, long_file_ok, allow_fd) ;
486
487 /* If the format doesn't support stereo we're done. */
488 sfinfo.channels = 2 ;
489 if (sf_format_check (&sfinfo) == 0)
490 { unlink (filename) ;
491 puts ("no stereo : ok") ;
492 return ;
493 } ;
494
495 stereo_char_test (filename, format, long_file_ok, allow_fd) ;
496
497 /* New read/write test. Not sure if this is needed yet. */
498
499 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
500 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
501 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
502 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
503 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
504 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
505 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
506 )
507 new_rdwr_char_test (filename, format, allow_fd) ;
508
509 delete_file (format, filename) ;
510
511 puts ("ok") ;
512 return ;
513 } /* pcm_test_char */
514
515 static void
mono_char_test(const char * filename,int format,int long_file_ok,int allow_fd)516 mono_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
517 { SNDFILE *file ;
518 SF_INFO sfinfo ;
519 short *orig, *test ;
520 sf_count_t count ;
521 int k, items, total ;
522
523 sfinfo.samplerate = 44100 ;
524 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
525 sfinfo.channels = 1 ;
526 sfinfo.format = format ;
527
528 orig = orig_data.s ;
529 test = test_data.s ;
530
531 items = DATA_LENGTH ;
532
533 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
534
535 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
536 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
537 exit (1) ;
538 } ;
539
540 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
541
542 test_write_short_or_die (file, 0, orig, items, __LINE__) ;
543 sf_write_sync (file) ;
544 test_write_short_or_die (file, 0, orig, items, __LINE__) ;
545 sf_write_sync (file) ;
546
547 /* Add non-audio data after the audio. */
548 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
549
550 sf_close (file) ;
551
552 memset (test, 0, items * sizeof (short)) ;
553
554 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
555 memset (&sfinfo, 0, sizeof (sfinfo)) ;
556
557 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
558
559 if (sfinfo.format != format)
560 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
561 exit (1) ;
562 } ;
563
564 if (sfinfo.frames < 2 * items)
565 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
566 exit (1) ;
567 } ;
568
569 if (! long_file_ok && sfinfo.frames > 2 * items)
570 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
571 exit (1) ;
572 } ;
573
574 if (sfinfo.channels != 1)
575 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
576 exit (1) ;
577 } ;
578
579 if (sfinfo.seekable != 1)
580 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
581 exit (1) ;
582 } ;
583
584 check_log_buffer_or_die (file, __LINE__) ;
585
586 test_read_short_or_die (file, 0, test, items, __LINE__) ;
587 for (k = 0 ; k < items ; k++)
588 if (CHAR_ERROR (orig [k], test [k]))
589 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
590 oct_save_short (orig, test, items) ;
591 exit (1) ;
592 } ;
593
594 /* Test multiple short reads. */
595 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
596
597 total = 0 ;
598 for (k = 1 ; k <= 32 ; k++)
599 { int ik ;
600
601 test_read_short_or_die (file, 0, test + total, k, __LINE__) ;
602 total += k ;
603
604 for (ik = 0 ; ik < total ; ik++)
605 if (CHAR_ERROR (orig [ik], test [ik]))
606 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, ik, orig [ik], test [ik]) ;
607 exit (1) ;
608 } ;
609 } ;
610
611 /* Seek to start of file. */
612 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
613
614 test_read_short_or_die (file, 0, test, 4, __LINE__) ;
615 for (k = 0 ; k < 4 ; k++)
616 if (CHAR_ERROR (orig [k], test [k]))
617 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
618 exit (1) ;
619 } ;
620
621 /* For some codecs we can't go past here. */
622 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
623 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
624 { sf_close (file) ;
625 unlink (filename) ;
626 printf ("no seek : ") ;
627 return ;
628 } ;
629
630 /* Seek to offset from start of file. */
631 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
632
633 test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
634 for (k = 10 ; k < 14 ; k++)
635 if (CHAR_ERROR (orig [k], test [k]))
636 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
637 exit (1) ;
638 } ;
639
640 /* Seek to offset from current position. */
641 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
642
643 test_read_short_or_die (file, 0, test + 20, 4, __LINE__) ;
644 for (k = 20 ; k < 24 ; k++)
645 if (CHAR_ERROR (orig [k], test [k]))
646 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
647 exit (1) ;
648 } ;
649
650 /* Seek to offset from end of file. */
651 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
652
653 test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
654 for (k = 10 ; k < 14 ; k++)
655 if (CHAR_ERROR (orig [k], test [k]))
656 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
657 exit (1) ;
658 } ;
659
660 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
661 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
662
663 count = 0 ;
664 while (count < sfinfo.frames)
665 count += sf_read_short (file, test, 311) ;
666
667 /* Check that no error has occurred. */
668 if (sf_error (file))
669 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
670 puts (sf_strerror (file)) ;
671 exit (1) ;
672 } ;
673
674 /* Check that we haven't read beyond EOF. */
675 if (count > sfinfo.frames)
676 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
677 exit (1) ;
678 } ;
679
680 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
681
682 sf_close (file) ;
683
684 multi_seek_test (filename, format) ;
685 write_seek_extend_test (filename, format) ;
686
687 } /* mono_char_test */
688
689 static void
stereo_char_test(const char * filename,int format,int long_file_ok,int allow_fd)690 stereo_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
691 { SNDFILE *file ;
692 SF_INFO sfinfo ;
693 short *orig, *test ;
694 int k, items, frames ;
695
696 sfinfo.samplerate = 44100 ;
697 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
698 sfinfo.channels = 2 ;
699 sfinfo.format = format ;
700
701 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
702
703 orig = orig_data.s ;
704 test = test_data.s ;
705
706 /* Make this a macro so gdb steps over it in one go. */
707 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
708
709 items = DATA_LENGTH ;
710 frames = items / sfinfo.channels ;
711
712 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
713
714 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
715
716 test_writef_short_or_die (file, 0, orig, frames, __LINE__) ;
717
718 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
719
720 sf_close (file) ;
721
722 memset (test, 0, items * sizeof (short)) ;
723
724 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
725 memset (&sfinfo, 0, sizeof (sfinfo)) ;
726
727 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
728
729 if (sfinfo.format != format)
730 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
731 __LINE__, format, sfinfo.format) ;
732 exit (1) ;
733 } ;
734
735 if (sfinfo.frames < frames)
736 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
737 __LINE__, sfinfo.frames, frames) ;
738 exit (1) ;
739 } ;
740
741 if (! long_file_ok && sfinfo.frames > frames)
742 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
743 __LINE__, sfinfo.frames, frames) ;
744 exit (1) ;
745 } ;
746
747 if (sfinfo.channels != 2)
748 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
749 exit (1) ;
750 } ;
751
752 check_log_buffer_or_die (file, __LINE__) ;
753
754 test_readf_short_or_die (file, 0, test, frames, __LINE__) ;
755 for (k = 0 ; k < items ; k++)
756 if (CHAR_ERROR (test [k], orig [k]))
757 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
758 exit (1) ;
759 } ;
760
761 /* Seek to start of file. */
762 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
763
764 test_readf_short_or_die (file, 0, test, 2, __LINE__) ;
765 for (k = 0 ; k < 4 ; k++)
766 if (CHAR_ERROR (test [k], orig [k]))
767 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
768 exit (1) ;
769 } ;
770
771 /* Seek to offset from start of file. */
772 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
773
774 /* Check for errors here. */
775 if (sf_error (file))
776 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
777 puts (sf_strerror (file)) ;
778 exit (1) ;
779 } ;
780
781 if (sf_read_short (file, test, 1) > 0)
782 { printf ("Line %d: Should return 0.\n", __LINE__) ;
783 exit (1) ;
784 } ;
785
786 if (! sf_error (file))
787 { printf ("Line %d: Should return an error.\n", __LINE__) ;
788 exit (1) ;
789 } ;
790 /*-----------------------*/
791
792 test_readf_short_or_die (file, 0, test + 10, 2, __LINE__) ;
793 for (k = 20 ; k < 24 ; k++)
794 if (CHAR_ERROR (test [k], orig [k]))
795 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
796 exit (1) ;
797 } ;
798
799 /* Seek to offset from current position. */
800 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
801
802 test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
803 for (k = 40 ; k < 44 ; k++)
804 if (CHAR_ERROR (test [k], orig [k]))
805 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
806 exit (1) ;
807 } ;
808
809 /* Seek to offset from end of file. */
810 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
811
812 test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
813 for (k = 20 ; k < 24 ; k++)
814 if (CHAR_ERROR (test [k], orig [k]))
815 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
816 exit (1) ;
817 } ;
818
819 sf_close (file) ;
820 } /* stereo_char_test */
821
822 static void
mono_rdwr_char_test(const char * filename,int format,int long_file_ok,int allow_fd)823 mono_rdwr_char_test (const char *filename, int format, int long_file_ok, int allow_fd)
824 { SNDFILE *file ;
825 SF_INFO sfinfo ;
826 short *orig, *test ;
827 int k, pass ;
828
829 switch (format & SF_FORMAT_SUBMASK)
830 { case SF_FORMAT_ALAC_16 :
831 case SF_FORMAT_ALAC_20 :
832 case SF_FORMAT_ALAC_24 :
833 case SF_FORMAT_ALAC_32 :
834 allow_fd = 0 ;
835 break ;
836
837 default :
838 break ;
839 } ;
840
841 orig = orig_data.s ;
842 test = test_data.s ;
843
844 sfinfo.samplerate = SAMPLE_RATE ;
845 sfinfo.frames = DATA_LENGTH ;
846 sfinfo.channels = 1 ;
847 sfinfo.format = format ;
848
849 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
850 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
851 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
852 unlink (filename) ;
853 else
854 { /* Create a short file. */
855 create_short_file (filename) ;
856
857 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
858 ** If this returns a valif pointer sf_open() screwed up.
859 */
860 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
861 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
862 exit (1) ;
863 } ;
864
865 /* Truncate the file to zero bytes. */
866 if (truncate_file_to_zero (filename) < 0)
867 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
868 perror (NULL) ;
869 exit (1) ;
870 } ;
871 } ;
872
873 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
874 ** all the usual data required when opening the file in WRITE mode.
875 */
876 sfinfo.samplerate = SAMPLE_RATE ;
877 sfinfo.frames = DATA_LENGTH ;
878 sfinfo.channels = 1 ;
879 sfinfo.format = format ;
880
881 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
882
883 /* Do 3 writes followed by reads. After each, check the data and the current
884 ** read and write offsets.
885 */
886 for (pass = 1 ; pass <= 3 ; pass ++)
887 { orig [20] = pass * 2 ;
888
889 /* Write some data. */
890 test_write_short_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
891
892 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
893
894 /* Read what we just wrote. */
895 test_read_short_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
896
897 /* Check the data. */
898 for (k = 0 ; k < DATA_LENGTH ; k++)
899 if (CHAR_ERROR (orig [k], test [k]))
900 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
901 oct_save_short (orig, test, DATA_LENGTH) ;
902 exit (1) ;
903 } ;
904
905 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
906 } ; /* for (pass ...) */
907
908 sf_close (file) ;
909
910 /* Open the file again to check the data. */
911 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
912
913 if (sfinfo.format != format)
914 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
915 exit (1) ;
916 } ;
917
918 if (sfinfo.frames < 3 * DATA_LENGTH)
919 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
920 exit (1) ;
921 }
922
923 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
924 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
925 exit (1) ;
926 } ;
927
928 if (sfinfo.channels != 1)
929 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
930 exit (1) ;
931 } ;
932
933 if (! long_file_ok)
934 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
935 else
936 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
937
938 for (pass = 1 ; pass <= 3 ; pass ++)
939 { orig [20] = pass * 2 ;
940
941 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
942
943 /* Read what we just wrote. */
944 test_read_short_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
945
946 /* Check the data. */
947 for (k = 0 ; k < DATA_LENGTH ; k++)
948 if (CHAR_ERROR (orig [k], test [k]))
949 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
950 oct_save_short (orig, test, DATA_LENGTH) ;
951 exit (1) ;
952 } ;
953
954 } ; /* for (pass ...) */
955
956 sf_close (file) ;
957 } /* mono_rdwr_short_test */
958
959 static void
new_rdwr_char_test(const char * filename,int format,int allow_fd)960 new_rdwr_char_test (const char *filename, int format, int allow_fd)
961 { SNDFILE *wfile, *rwfile ;
962 SF_INFO sfinfo ;
963 short *orig, *test ;
964 int items, frames ;
965
966 orig = orig_data.s ;
967 test = test_data.s ;
968
969 sfinfo.samplerate = 44100 ;
970 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
971 sfinfo.channels = 2 ;
972 sfinfo.format = format ;
973
974 items = DATA_LENGTH ;
975 frames = items / sfinfo.channels ;
976
977 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
978 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
979 test_writef_short_or_die (wfile, 1, orig, frames, __LINE__) ;
980 sf_write_sync (wfile) ;
981 test_writef_short_or_die (wfile, 2, orig, frames, __LINE__) ;
982 sf_write_sync (wfile) ;
983
984 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
985 if (sfinfo.frames != 2 * frames)
986 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
987 exit (1) ;
988 } ;
989
990 test_writef_short_or_die (wfile, 3, orig, frames, __LINE__) ;
991
992 test_readf_short_or_die (rwfile, 1, test, frames, __LINE__) ;
993 test_readf_short_or_die (rwfile, 2, test, frames, __LINE__) ;
994
995 sf_close (wfile) ;
996 sf_close (rwfile) ;
997 } /* new_rdwr_char_test */
998
999
1000 /*======================================================================================
1001 */
1002
1003 static void mono_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1004 static void stereo_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1005 static void mono_rdwr_short_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1006 static void new_rdwr_short_test (const char *filename, int format, int allow_fd) ;
1007 static void multi_seek_test (const char * filename, int format) ;
1008 static void write_seek_extend_test (const char * filename, int format) ;
1009
1010 static void
pcm_test_short(const char * filename,int format,int long_file_ok)1011 pcm_test_short (const char *filename, int format, int long_file_ok)
1012 { SF_INFO sfinfo ;
1013 short *orig ;
1014 int k, allow_fd ;
1015
1016 /* Sd2 files cannot be opened from an existing file descriptor. */
1017 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
1018
1019 print_test_name ("pcm_test_short", filename) ;
1020
1021 sfinfo.samplerate = 44100 ;
1022 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1023 sfinfo.channels = 1 ;
1024 sfinfo.format = format ;
1025
1026 test_sf_format_or_die (&sfinfo, __LINE__) ;
1027
1028 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
1029
1030 orig = orig_data.s ;
1031
1032 /* Make this a macro so gdb steps over it in one go. */
1033 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
1034
1035 /* Some test broken out here. */
1036
1037 mono_short_test (filename, format, long_file_ok, allow_fd) ;
1038
1039 /* Sub format DWVW does not allow seeking. */
1040 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
1041 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
1042 { unlink (filename) ;
1043 printf ("no seek : ok\n") ;
1044 return ;
1045 } ;
1046
1047 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
1048 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
1049 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
1050 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
1051 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
1052 )
1053 mono_rdwr_short_test (filename, format, long_file_ok, allow_fd) ;
1054
1055 /* If the format doesn't support stereo we're done. */
1056 sfinfo.channels = 2 ;
1057 if (sf_format_check (&sfinfo) == 0)
1058 { unlink (filename) ;
1059 puts ("no stereo : ok") ;
1060 return ;
1061 } ;
1062
1063 stereo_short_test (filename, format, long_file_ok, allow_fd) ;
1064
1065 /* New read/write test. Not sure if this is needed yet. */
1066
1067 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
1068 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
1069 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
1070 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
1071 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
1072 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
1073 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
1074 )
1075 new_rdwr_short_test (filename, format, allow_fd) ;
1076
1077 delete_file (format, filename) ;
1078
1079 puts ("ok") ;
1080 return ;
1081 } /* pcm_test_short */
1082
1083 static void
mono_short_test(const char * filename,int format,int long_file_ok,int allow_fd)1084 mono_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
1085 { SNDFILE *file ;
1086 SF_INFO sfinfo ;
1087 short *orig, *test ;
1088 sf_count_t count ;
1089 int k, items, total ;
1090
1091 sfinfo.samplerate = 44100 ;
1092 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1093 sfinfo.channels = 1 ;
1094 sfinfo.format = format ;
1095
1096 orig = orig_data.s ;
1097 test = test_data.s ;
1098
1099 items = DATA_LENGTH ;
1100
1101 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
1102
1103 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
1104 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
1105 exit (1) ;
1106 } ;
1107
1108 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
1109
1110 test_write_short_or_die (file, 0, orig, items, __LINE__) ;
1111 sf_write_sync (file) ;
1112 test_write_short_or_die (file, 0, orig, items, __LINE__) ;
1113 sf_write_sync (file) ;
1114
1115 /* Add non-audio data after the audio. */
1116 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
1117
1118 sf_close (file) ;
1119
1120 memset (test, 0, items * sizeof (short)) ;
1121
1122 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1123 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1124
1125 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
1126
1127 if (sfinfo.format != format)
1128 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
1129 exit (1) ;
1130 } ;
1131
1132 if (sfinfo.frames < 2 * items)
1133 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
1134 exit (1) ;
1135 } ;
1136
1137 if (! long_file_ok && sfinfo.frames > 2 * items)
1138 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
1139 exit (1) ;
1140 } ;
1141
1142 if (sfinfo.channels != 1)
1143 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
1144 exit (1) ;
1145 } ;
1146
1147 if (sfinfo.seekable != 1)
1148 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
1149 exit (1) ;
1150 } ;
1151
1152 check_log_buffer_or_die (file, __LINE__) ;
1153
1154 test_read_short_or_die (file, 0, test, items, __LINE__) ;
1155 for (k = 0 ; k < items ; k++)
1156 if (INT_ERROR (orig [k], test [k]))
1157 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1158 oct_save_short (orig, test, items) ;
1159 exit (1) ;
1160 } ;
1161
1162 /* Test multiple short reads. */
1163 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1164
1165 total = 0 ;
1166 for (k = 1 ; k <= 32 ; k++)
1167 { int ik ;
1168
1169 test_read_short_or_die (file, 0, test + total, k, __LINE__) ;
1170 total += k ;
1171
1172 for (ik = 0 ; ik < total ; ik++)
1173 if (INT_ERROR (orig [ik], test [ik]))
1174 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, ik, orig [ik], test [ik]) ;
1175 exit (1) ;
1176 } ;
1177 } ;
1178
1179 /* Seek to start of file. */
1180 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1181
1182 test_read_short_or_die (file, 0, test, 4, __LINE__) ;
1183 for (k = 0 ; k < 4 ; k++)
1184 if (INT_ERROR (orig [k], test [k]))
1185 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1186 exit (1) ;
1187 } ;
1188
1189 /* For some codecs we can't go past here. */
1190 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
1191 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
1192 { sf_close (file) ;
1193 unlink (filename) ;
1194 printf ("no seek : ") ;
1195 return ;
1196 } ;
1197
1198 /* Seek to offset from start of file. */
1199 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
1200
1201 test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
1202 for (k = 10 ; k < 14 ; k++)
1203 if (INT_ERROR (orig [k], test [k]))
1204 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1205 exit (1) ;
1206 } ;
1207
1208 /* Seek to offset from current position. */
1209 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
1210
1211 test_read_short_or_die (file, 0, test + 20, 4, __LINE__) ;
1212 for (k = 20 ; k < 24 ; k++)
1213 if (INT_ERROR (orig [k], test [k]))
1214 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1215 exit (1) ;
1216 } ;
1217
1218 /* Seek to offset from end of file. */
1219 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
1220
1221 test_read_short_or_die (file, 0, test + 10, 4, __LINE__) ;
1222 for (k = 10 ; k < 14 ; k++)
1223 if (INT_ERROR (orig [k], test [k]))
1224 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1225 exit (1) ;
1226 } ;
1227
1228 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
1229 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1230
1231 count = 0 ;
1232 while (count < sfinfo.frames)
1233 count += sf_read_short (file, test, 311) ;
1234
1235 /* Check that no error has occurred. */
1236 if (sf_error (file))
1237 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
1238 puts (sf_strerror (file)) ;
1239 exit (1) ;
1240 } ;
1241
1242 /* Check that we haven't read beyond EOF. */
1243 if (count > sfinfo.frames)
1244 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
1245 exit (1) ;
1246 } ;
1247
1248 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
1249
1250 sf_close (file) ;
1251
1252 multi_seek_test (filename, format) ;
1253 write_seek_extend_test (filename, format) ;
1254
1255 } /* mono_short_test */
1256
1257 static void
stereo_short_test(const char * filename,int format,int long_file_ok,int allow_fd)1258 stereo_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
1259 { SNDFILE *file ;
1260 SF_INFO sfinfo ;
1261 short *orig, *test ;
1262 int k, items, frames ;
1263
1264 sfinfo.samplerate = 44100 ;
1265 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1266 sfinfo.channels = 2 ;
1267 sfinfo.format = format ;
1268
1269 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
1270
1271 orig = orig_data.s ;
1272 test = test_data.s ;
1273
1274 /* Make this a macro so gdb steps over it in one go. */
1275 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
1276
1277 items = DATA_LENGTH ;
1278 frames = items / sfinfo.channels ;
1279
1280 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
1281
1282 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
1283
1284 test_writef_short_or_die (file, 0, orig, frames, __LINE__) ;
1285
1286 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
1287
1288 sf_close (file) ;
1289
1290 memset (test, 0, items * sizeof (short)) ;
1291
1292 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1293 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1294
1295 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
1296
1297 if (sfinfo.format != format)
1298 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
1299 __LINE__, format, sfinfo.format) ;
1300 exit (1) ;
1301 } ;
1302
1303 if (sfinfo.frames < frames)
1304 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
1305 __LINE__, sfinfo.frames, frames) ;
1306 exit (1) ;
1307 } ;
1308
1309 if (! long_file_ok && sfinfo.frames > frames)
1310 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
1311 __LINE__, sfinfo.frames, frames) ;
1312 exit (1) ;
1313 } ;
1314
1315 if (sfinfo.channels != 2)
1316 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
1317 exit (1) ;
1318 } ;
1319
1320 check_log_buffer_or_die (file, __LINE__) ;
1321
1322 test_readf_short_or_die (file, 0, test, frames, __LINE__) ;
1323 for (k = 0 ; k < items ; k++)
1324 if (INT_ERROR (test [k], orig [k]))
1325 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1326 exit (1) ;
1327 } ;
1328
1329 /* Seek to start of file. */
1330 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1331
1332 test_readf_short_or_die (file, 0, test, 2, __LINE__) ;
1333 for (k = 0 ; k < 4 ; k++)
1334 if (INT_ERROR (test [k], orig [k]))
1335 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1336 exit (1) ;
1337 } ;
1338
1339 /* Seek to offset from start of file. */
1340 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
1341
1342 /* Check for errors here. */
1343 if (sf_error (file))
1344 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
1345 puts (sf_strerror (file)) ;
1346 exit (1) ;
1347 } ;
1348
1349 if (sf_read_short (file, test, 1) > 0)
1350 { printf ("Line %d: Should return 0.\n", __LINE__) ;
1351 exit (1) ;
1352 } ;
1353
1354 if (! sf_error (file))
1355 { printf ("Line %d: Should return an error.\n", __LINE__) ;
1356 exit (1) ;
1357 } ;
1358 /*-----------------------*/
1359
1360 test_readf_short_or_die (file, 0, test + 10, 2, __LINE__) ;
1361 for (k = 20 ; k < 24 ; k++)
1362 if (INT_ERROR (test [k], orig [k]))
1363 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1364 exit (1) ;
1365 } ;
1366
1367 /* Seek to offset from current position. */
1368 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
1369
1370 test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
1371 for (k = 40 ; k < 44 ; k++)
1372 if (INT_ERROR (test [k], orig [k]))
1373 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1374 exit (1) ;
1375 } ;
1376
1377 /* Seek to offset from end of file. */
1378 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
1379
1380 test_readf_short_or_die (file, 0, test + 20, 2, __LINE__) ;
1381 for (k = 20 ; k < 24 ; k++)
1382 if (INT_ERROR (test [k], orig [k]))
1383 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1384 exit (1) ;
1385 } ;
1386
1387 sf_close (file) ;
1388 } /* stereo_short_test */
1389
1390 static void
mono_rdwr_short_test(const char * filename,int format,int long_file_ok,int allow_fd)1391 mono_rdwr_short_test (const char *filename, int format, int long_file_ok, int allow_fd)
1392 { SNDFILE *file ;
1393 SF_INFO sfinfo ;
1394 short *orig, *test ;
1395 int k, pass ;
1396
1397 switch (format & SF_FORMAT_SUBMASK)
1398 { case SF_FORMAT_ALAC_16 :
1399 case SF_FORMAT_ALAC_20 :
1400 case SF_FORMAT_ALAC_24 :
1401 case SF_FORMAT_ALAC_32 :
1402 allow_fd = 0 ;
1403 break ;
1404
1405 default :
1406 break ;
1407 } ;
1408
1409 orig = orig_data.s ;
1410 test = test_data.s ;
1411
1412 sfinfo.samplerate = SAMPLE_RATE ;
1413 sfinfo.frames = DATA_LENGTH ;
1414 sfinfo.channels = 1 ;
1415 sfinfo.format = format ;
1416
1417 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
1418 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
1419 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
1420 unlink (filename) ;
1421 else
1422 { /* Create a short file. */
1423 create_short_file (filename) ;
1424
1425 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
1426 ** If this returns a valif pointer sf_open() screwed up.
1427 */
1428 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
1429 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
1430 exit (1) ;
1431 } ;
1432
1433 /* Truncate the file to zero bytes. */
1434 if (truncate_file_to_zero (filename) < 0)
1435 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
1436 perror (NULL) ;
1437 exit (1) ;
1438 } ;
1439 } ;
1440
1441 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
1442 ** all the usual data required when opening the file in WRITE mode.
1443 */
1444 sfinfo.samplerate = SAMPLE_RATE ;
1445 sfinfo.frames = DATA_LENGTH ;
1446 sfinfo.channels = 1 ;
1447 sfinfo.format = format ;
1448
1449 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
1450
1451 /* Do 3 writes followed by reads. After each, check the data and the current
1452 ** read and write offsets.
1453 */
1454 for (pass = 1 ; pass <= 3 ; pass ++)
1455 { orig [20] = pass * 2 ;
1456
1457 /* Write some data. */
1458 test_write_short_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
1459
1460 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
1461
1462 /* Read what we just wrote. */
1463 test_read_short_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
1464
1465 /* Check the data. */
1466 for (k = 0 ; k < DATA_LENGTH ; k++)
1467 if (INT_ERROR (orig [k], test [k]))
1468 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
1469 oct_save_short (orig, test, DATA_LENGTH) ;
1470 exit (1) ;
1471 } ;
1472
1473 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
1474 } ; /* for (pass ...) */
1475
1476 sf_close (file) ;
1477
1478 /* Open the file again to check the data. */
1479 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
1480
1481 if (sfinfo.format != format)
1482 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
1483 exit (1) ;
1484 } ;
1485
1486 if (sfinfo.frames < 3 * DATA_LENGTH)
1487 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
1488 exit (1) ;
1489 }
1490
1491 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
1492 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
1493 exit (1) ;
1494 } ;
1495
1496 if (sfinfo.channels != 1)
1497 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
1498 exit (1) ;
1499 } ;
1500
1501 if (! long_file_ok)
1502 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
1503 else
1504 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
1505
1506 for (pass = 1 ; pass <= 3 ; pass ++)
1507 { orig [20] = pass * 2 ;
1508
1509 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
1510
1511 /* Read what we just wrote. */
1512 test_read_short_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
1513
1514 /* Check the data. */
1515 for (k = 0 ; k < DATA_LENGTH ; k++)
1516 if (INT_ERROR (orig [k], test [k]))
1517 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
1518 oct_save_short (orig, test, DATA_LENGTH) ;
1519 exit (1) ;
1520 } ;
1521
1522 } ; /* for (pass ...) */
1523
1524 sf_close (file) ;
1525 } /* mono_rdwr_short_test */
1526
1527 static void
new_rdwr_short_test(const char * filename,int format,int allow_fd)1528 new_rdwr_short_test (const char *filename, int format, int allow_fd)
1529 { SNDFILE *wfile, *rwfile ;
1530 SF_INFO sfinfo ;
1531 short *orig, *test ;
1532 int items, frames ;
1533
1534 orig = orig_data.s ;
1535 test = test_data.s ;
1536
1537 sfinfo.samplerate = 44100 ;
1538 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1539 sfinfo.channels = 2 ;
1540 sfinfo.format = format ;
1541
1542 items = DATA_LENGTH ;
1543 frames = items / sfinfo.channels ;
1544
1545 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
1546 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
1547 test_writef_short_or_die (wfile, 1, orig, frames, __LINE__) ;
1548 sf_write_sync (wfile) ;
1549 test_writef_short_or_die (wfile, 2, orig, frames, __LINE__) ;
1550 sf_write_sync (wfile) ;
1551
1552 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
1553 if (sfinfo.frames != 2 * frames)
1554 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
1555 exit (1) ;
1556 } ;
1557
1558 test_writef_short_or_die (wfile, 3, orig, frames, __LINE__) ;
1559
1560 test_readf_short_or_die (rwfile, 1, test, frames, __LINE__) ;
1561 test_readf_short_or_die (rwfile, 2, test, frames, __LINE__) ;
1562
1563 sf_close (wfile) ;
1564 sf_close (rwfile) ;
1565 } /* new_rdwr_short_test */
1566
1567
1568 /*======================================================================================
1569 */
1570
1571 static void mono_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1572 static void stereo_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1573 static void mono_rdwr_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
1574 static void new_rdwr_20bit_test (const char *filename, int format, int allow_fd) ;
1575 static void multi_seek_test (const char * filename, int format) ;
1576 static void write_seek_extend_test (const char * filename, int format) ;
1577
1578 static void
pcm_test_20bit(const char * filename,int format,int long_file_ok)1579 pcm_test_20bit (const char *filename, int format, int long_file_ok)
1580 { SF_INFO sfinfo ;
1581 int *orig ;
1582 int k, allow_fd ;
1583
1584 /* Sd2 files cannot be opened from an existing file descriptor. */
1585 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
1586
1587 print_test_name ("pcm_test_20bit", filename) ;
1588
1589 sfinfo.samplerate = 44100 ;
1590 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1591 sfinfo.channels = 1 ;
1592 sfinfo.format = format ;
1593
1594 test_sf_format_or_die (&sfinfo, __LINE__) ;
1595
1596 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F00000)) ;
1597
1598 orig = orig_data.i ;
1599
1600 /* Make this a macro so gdb steps over it in one go. */
1601 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
1602
1603 /* Some test broken out here. */
1604
1605 mono_20bit_test (filename, format, long_file_ok, allow_fd) ;
1606
1607 /* Sub format DWVW does not allow seeking. */
1608 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
1609 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
1610 { unlink (filename) ;
1611 printf ("no seek : ok\n") ;
1612 return ;
1613 } ;
1614
1615 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
1616 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
1617 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
1618 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
1619 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
1620 )
1621 mono_rdwr_20bit_test (filename, format, long_file_ok, allow_fd) ;
1622
1623 /* If the format doesn't support stereo we're done. */
1624 sfinfo.channels = 2 ;
1625 if (sf_format_check (&sfinfo) == 0)
1626 { unlink (filename) ;
1627 puts ("no stereo : ok") ;
1628 return ;
1629 } ;
1630
1631 stereo_20bit_test (filename, format, long_file_ok, allow_fd) ;
1632
1633 /* New read/write test. Not sure if this is needed yet. */
1634
1635 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
1636 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
1637 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
1638 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
1639 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
1640 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
1641 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
1642 )
1643 new_rdwr_20bit_test (filename, format, allow_fd) ;
1644
1645 delete_file (format, filename) ;
1646
1647 puts ("ok") ;
1648 return ;
1649 } /* pcm_test_20bit */
1650
1651 static void
mono_20bit_test(const char * filename,int format,int long_file_ok,int allow_fd)1652 mono_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
1653 { SNDFILE *file ;
1654 SF_INFO sfinfo ;
1655 int *orig, *test ;
1656 sf_count_t count ;
1657 int k, items, total ;
1658
1659 sfinfo.samplerate = 44100 ;
1660 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1661 sfinfo.channels = 1 ;
1662 sfinfo.format = format ;
1663
1664 orig = orig_data.i ;
1665 test = test_data.i ;
1666
1667 items = DATA_LENGTH ;
1668
1669 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
1670
1671 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
1672 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
1673 exit (1) ;
1674 } ;
1675
1676 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
1677
1678 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
1679 sf_write_sync (file) ;
1680 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
1681 sf_write_sync (file) ;
1682
1683 /* Add non-audio data after the audio. */
1684 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
1685
1686 sf_close (file) ;
1687
1688 memset (test, 0, items * sizeof (int)) ;
1689
1690 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1691 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1692
1693 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
1694
1695 if (sfinfo.format != format)
1696 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
1697 exit (1) ;
1698 } ;
1699
1700 if (sfinfo.frames < 2 * items)
1701 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
1702 exit (1) ;
1703 } ;
1704
1705 if (! long_file_ok && sfinfo.frames > 2 * items)
1706 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
1707 exit (1) ;
1708 } ;
1709
1710 if (sfinfo.channels != 1)
1711 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
1712 exit (1) ;
1713 } ;
1714
1715 if (sfinfo.seekable != 1)
1716 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
1717 exit (1) ;
1718 } ;
1719
1720 check_log_buffer_or_die (file, __LINE__) ;
1721
1722 test_read_int_or_die (file, 0, test, items, __LINE__) ;
1723 for (k = 0 ; k < items ; k++)
1724 if (BIT_20_ERROR (orig [k], test [k]))
1725 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1726 oct_save_int (orig, test, items) ;
1727 exit (1) ;
1728 } ;
1729
1730 /* Test multiple short reads. */
1731 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1732
1733 total = 0 ;
1734 for (k = 1 ; k <= 32 ; k++)
1735 { int ik ;
1736
1737 test_read_int_or_die (file, 0, test + total, k, __LINE__) ;
1738 total += k ;
1739
1740 for (ik = 0 ; ik < total ; ik++)
1741 if (BIT_20_ERROR (orig [ik], test [ik]))
1742 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, ik, orig [ik], test [ik]) ;
1743 exit (1) ;
1744 } ;
1745 } ;
1746
1747 /* Seek to start of file. */
1748 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1749
1750 test_read_int_or_die (file, 0, test, 4, __LINE__) ;
1751 for (k = 0 ; k < 4 ; k++)
1752 if (BIT_20_ERROR (orig [k], test [k]))
1753 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1754 exit (1) ;
1755 } ;
1756
1757 /* For some codecs we can't go past here. */
1758 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
1759 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
1760 { sf_close (file) ;
1761 unlink (filename) ;
1762 printf ("no seek : ") ;
1763 return ;
1764 } ;
1765
1766 /* Seek to offset from start of file. */
1767 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
1768
1769 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
1770 for (k = 10 ; k < 14 ; k++)
1771 if (BIT_20_ERROR (orig [k], test [k]))
1772 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1773 exit (1) ;
1774 } ;
1775
1776 /* Seek to offset from current position. */
1777 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
1778
1779 test_read_int_or_die (file, 0, test + 20, 4, __LINE__) ;
1780 for (k = 20 ; k < 24 ; k++)
1781 if (BIT_20_ERROR (orig [k], test [k]))
1782 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1783 exit (1) ;
1784 } ;
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
1789 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
1790 for (k = 10 ; k < 14 ; k++)
1791 if (BIT_20_ERROR (orig [k], test [k]))
1792 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
1793 exit (1) ;
1794 } ;
1795
1796 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
1797 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1798
1799 count = 0 ;
1800 while (count < sfinfo.frames)
1801 count += sf_read_int (file, test, 311) ;
1802
1803 /* Check that no error has occurred. */
1804 if (sf_error (file))
1805 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
1806 puts (sf_strerror (file)) ;
1807 exit (1) ;
1808 } ;
1809
1810 /* Check that we haven't read beyond EOF. */
1811 if (count > sfinfo.frames)
1812 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
1813 exit (1) ;
1814 } ;
1815
1816 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
1817
1818 sf_close (file) ;
1819
1820 multi_seek_test (filename, format) ;
1821 write_seek_extend_test (filename, format) ;
1822
1823 } /* mono_20bit_test */
1824
1825 static void
stereo_20bit_test(const char * filename,int format,int long_file_ok,int allow_fd)1826 stereo_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
1827 { SNDFILE *file ;
1828 SF_INFO sfinfo ;
1829 int *orig, *test ;
1830 int k, items, frames ;
1831
1832 sfinfo.samplerate = 44100 ;
1833 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
1834 sfinfo.channels = 2 ;
1835 sfinfo.format = format ;
1836
1837 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F00000)) ;
1838
1839 orig = orig_data.i ;
1840 test = test_data.i ;
1841
1842 /* Make this a macro so gdb steps over it in one go. */
1843 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
1844
1845 items = DATA_LENGTH ;
1846 frames = items / sfinfo.channels ;
1847
1848 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
1849
1850 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
1851
1852 test_writef_int_or_die (file, 0, orig, frames, __LINE__) ;
1853
1854 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
1855
1856 sf_close (file) ;
1857
1858 memset (test, 0, items * sizeof (int)) ;
1859
1860 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1861 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1862
1863 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
1864
1865 if (sfinfo.format != format)
1866 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
1867 __LINE__, format, sfinfo.format) ;
1868 exit (1) ;
1869 } ;
1870
1871 if (sfinfo.frames < frames)
1872 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
1873 __LINE__, sfinfo.frames, frames) ;
1874 exit (1) ;
1875 } ;
1876
1877 if (! long_file_ok && sfinfo.frames > frames)
1878 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
1879 __LINE__, sfinfo.frames, frames) ;
1880 exit (1) ;
1881 } ;
1882
1883 if (sfinfo.channels != 2)
1884 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
1885 exit (1) ;
1886 } ;
1887
1888 check_log_buffer_or_die (file, __LINE__) ;
1889
1890 test_readf_int_or_die (file, 0, test, frames, __LINE__) ;
1891 for (k = 0 ; k < items ; k++)
1892 if (BIT_20_ERROR (test [k], orig [k]))
1893 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1894 exit (1) ;
1895 } ;
1896
1897 /* Seek to start of file. */
1898 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
1899
1900 test_readf_int_or_die (file, 0, test, 2, __LINE__) ;
1901 for (k = 0 ; k < 4 ; k++)
1902 if (BIT_20_ERROR (test [k], orig [k]))
1903 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1904 exit (1) ;
1905 } ;
1906
1907 /* Seek to offset from start of file. */
1908 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
1909
1910 /* Check for errors here. */
1911 if (sf_error (file))
1912 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
1913 puts (sf_strerror (file)) ;
1914 exit (1) ;
1915 } ;
1916
1917 if (sf_read_int (file, test, 1) > 0)
1918 { printf ("Line %d: Should return 0.\n", __LINE__) ;
1919 exit (1) ;
1920 } ;
1921
1922 if (! sf_error (file))
1923 { printf ("Line %d: Should return an error.\n", __LINE__) ;
1924 exit (1) ;
1925 } ;
1926 /*-----------------------*/
1927
1928 test_readf_int_or_die (file, 0, test + 10, 2, __LINE__) ;
1929 for (k = 20 ; k < 24 ; k++)
1930 if (BIT_20_ERROR (test [k], orig [k]))
1931 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1932 exit (1) ;
1933 } ;
1934
1935 /* Seek to offset from current position. */
1936 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
1937
1938 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
1939 for (k = 40 ; k < 44 ; k++)
1940 if (BIT_20_ERROR (test [k], orig [k]))
1941 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1942 exit (1) ;
1943 } ;
1944
1945 /* Seek to offset from end of file. */
1946 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
1947
1948 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
1949 for (k = 20 ; k < 24 ; k++)
1950 if (BIT_20_ERROR (test [k], orig [k]))
1951 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
1952 exit (1) ;
1953 } ;
1954
1955 sf_close (file) ;
1956 } /* stereo_20bit_test */
1957
1958 static void
mono_rdwr_20bit_test(const char * filename,int format,int long_file_ok,int allow_fd)1959 mono_rdwr_20bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
1960 { SNDFILE *file ;
1961 SF_INFO sfinfo ;
1962 int *orig, *test ;
1963 int k, pass ;
1964
1965 switch (format & SF_FORMAT_SUBMASK)
1966 { case SF_FORMAT_ALAC_16 :
1967 case SF_FORMAT_ALAC_20 :
1968 case SF_FORMAT_ALAC_24 :
1969 case SF_FORMAT_ALAC_32 :
1970 allow_fd = 0 ;
1971 break ;
1972
1973 default :
1974 break ;
1975 } ;
1976
1977 orig = orig_data.i ;
1978 test = test_data.i ;
1979
1980 sfinfo.samplerate = SAMPLE_RATE ;
1981 sfinfo.frames = DATA_LENGTH ;
1982 sfinfo.channels = 1 ;
1983 sfinfo.format = format ;
1984
1985 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
1986 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
1987 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
1988 unlink (filename) ;
1989 else
1990 { /* Create a short file. */
1991 create_short_file (filename) ;
1992
1993 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
1994 ** If this returns a valif pointer sf_open() screwed up.
1995 */
1996 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
1997 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
1998 exit (1) ;
1999 } ;
2000
2001 /* Truncate the file to zero bytes. */
2002 if (truncate_file_to_zero (filename) < 0)
2003 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
2004 perror (NULL) ;
2005 exit (1) ;
2006 } ;
2007 } ;
2008
2009 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
2010 ** all the usual data required when opening the file in WRITE mode.
2011 */
2012 sfinfo.samplerate = SAMPLE_RATE ;
2013 sfinfo.frames = DATA_LENGTH ;
2014 sfinfo.channels = 1 ;
2015 sfinfo.format = format ;
2016
2017 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2018
2019 /* Do 3 writes followed by reads. After each, check the data and the current
2020 ** read and write offsets.
2021 */
2022 for (pass = 1 ; pass <= 3 ; pass ++)
2023 { orig [20] = pass * 2 ;
2024
2025 /* Write some data. */
2026 test_write_int_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
2027
2028 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
2029
2030 /* Read what we just wrote. */
2031 test_read_int_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
2032
2033 /* Check the data. */
2034 for (k = 0 ; k < DATA_LENGTH ; k++)
2035 if (BIT_20_ERROR (orig [k], test [k]))
2036 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
2037 oct_save_int (orig, test, DATA_LENGTH) ;
2038 exit (1) ;
2039 } ;
2040
2041 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
2042 } ; /* for (pass ...) */
2043
2044 sf_close (file) ;
2045
2046 /* Open the file again to check the data. */
2047 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2048
2049 if (sfinfo.format != format)
2050 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
2051 exit (1) ;
2052 } ;
2053
2054 if (sfinfo.frames < 3 * DATA_LENGTH)
2055 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
2056 exit (1) ;
2057 }
2058
2059 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
2060 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
2061 exit (1) ;
2062 } ;
2063
2064 if (sfinfo.channels != 1)
2065 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
2066 exit (1) ;
2067 } ;
2068
2069 if (! long_file_ok)
2070 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
2071 else
2072 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
2073
2074 for (pass = 1 ; pass <= 3 ; pass ++)
2075 { orig [20] = pass * 2 ;
2076
2077 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
2078
2079 /* Read what we just wrote. */
2080 test_read_int_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
2081
2082 /* Check the data. */
2083 for (k = 0 ; k < DATA_LENGTH ; k++)
2084 if (BIT_20_ERROR (orig [k], test [k]))
2085 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
2086 oct_save_int (orig, test, DATA_LENGTH) ;
2087 exit (1) ;
2088 } ;
2089
2090 } ; /* for (pass ...) */
2091
2092 sf_close (file) ;
2093 } /* mono_rdwr_int_test */
2094
2095 static void
new_rdwr_20bit_test(const char * filename,int format,int allow_fd)2096 new_rdwr_20bit_test (const char *filename, int format, int allow_fd)
2097 { SNDFILE *wfile, *rwfile ;
2098 SF_INFO sfinfo ;
2099 int *orig, *test ;
2100 int items, frames ;
2101
2102 orig = orig_data.i ;
2103 test = test_data.i ;
2104
2105 sfinfo.samplerate = 44100 ;
2106 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2107 sfinfo.channels = 2 ;
2108 sfinfo.format = format ;
2109
2110 items = DATA_LENGTH ;
2111 frames = items / sfinfo.channels ;
2112
2113 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2114 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
2115 test_writef_int_or_die (wfile, 1, orig, frames, __LINE__) ;
2116 sf_write_sync (wfile) ;
2117 test_writef_int_or_die (wfile, 2, orig, frames, __LINE__) ;
2118 sf_write_sync (wfile) ;
2119
2120 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2121 if (sfinfo.frames != 2 * frames)
2122 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
2123 exit (1) ;
2124 } ;
2125
2126 test_writef_int_or_die (wfile, 3, orig, frames, __LINE__) ;
2127
2128 test_readf_int_or_die (rwfile, 1, test, frames, __LINE__) ;
2129 test_readf_int_or_die (rwfile, 2, test, frames, __LINE__) ;
2130
2131 sf_close (wfile) ;
2132 sf_close (rwfile) ;
2133 } /* new_rdwr_20bit_test */
2134
2135
2136 /*======================================================================================
2137 */
2138
2139 static void mono_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2140 static void stereo_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2141 static void mono_rdwr_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2142 static void new_rdwr_24bit_test (const char *filename, int format, int allow_fd) ;
2143 static void multi_seek_test (const char * filename, int format) ;
2144 static void write_seek_extend_test (const char * filename, int format) ;
2145
2146 static void
pcm_test_24bit(const char * filename,int format,int long_file_ok)2147 pcm_test_24bit (const char *filename, int format, int long_file_ok)
2148 { SF_INFO sfinfo ;
2149 int *orig ;
2150 int k, allow_fd ;
2151
2152 /* Sd2 files cannot be opened from an existing file descriptor. */
2153 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
2154
2155 print_test_name ("pcm_test_24bit", filename) ;
2156
2157 sfinfo.samplerate = 44100 ;
2158 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2159 sfinfo.channels = 1 ;
2160 sfinfo.format = format ;
2161
2162 test_sf_format_or_die (&sfinfo, __LINE__) ;
2163
2164 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
2165
2166 orig = orig_data.i ;
2167
2168 /* Make this a macro so gdb steps over it in one go. */
2169 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
2170
2171 /* Some test broken out here. */
2172
2173 mono_24bit_test (filename, format, long_file_ok, allow_fd) ;
2174
2175 /* Sub format DWVW does not allow seeking. */
2176 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
2177 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
2178 { unlink (filename) ;
2179 printf ("no seek : ok\n") ;
2180 return ;
2181 } ;
2182
2183 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
2184 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
2185 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
2186 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
2187 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
2188 )
2189 mono_rdwr_24bit_test (filename, format, long_file_ok, allow_fd) ;
2190
2191 /* If the format doesn't support stereo we're done. */
2192 sfinfo.channels = 2 ;
2193 if (sf_format_check (&sfinfo) == 0)
2194 { unlink (filename) ;
2195 puts ("no stereo : ok") ;
2196 return ;
2197 } ;
2198
2199 stereo_24bit_test (filename, format, long_file_ok, allow_fd) ;
2200
2201 /* New read/write test. Not sure if this is needed yet. */
2202
2203 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
2204 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
2205 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
2206 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
2207 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
2208 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
2209 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
2210 )
2211 new_rdwr_24bit_test (filename, format, allow_fd) ;
2212
2213 delete_file (format, filename) ;
2214
2215 puts ("ok") ;
2216 return ;
2217 } /* pcm_test_24bit */
2218
2219 static void
mono_24bit_test(const char * filename,int format,int long_file_ok,int allow_fd)2220 mono_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
2221 { SNDFILE *file ;
2222 SF_INFO sfinfo ;
2223 int *orig, *test ;
2224 sf_count_t count ;
2225 int k, items, total ;
2226
2227 sfinfo.samplerate = 44100 ;
2228 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2229 sfinfo.channels = 1 ;
2230 sfinfo.format = format ;
2231
2232 orig = orig_data.i ;
2233 test = test_data.i ;
2234
2235 items = DATA_LENGTH ;
2236
2237 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2238
2239 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
2240 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
2241 exit (1) ;
2242 } ;
2243
2244 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
2245
2246 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
2247 sf_write_sync (file) ;
2248 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
2249 sf_write_sync (file) ;
2250
2251 /* Add non-audio data after the audio. */
2252 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
2253
2254 sf_close (file) ;
2255
2256 memset (test, 0, items * sizeof (int)) ;
2257
2258 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2259 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2260
2261 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
2262
2263 if (sfinfo.format != format)
2264 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
2265 exit (1) ;
2266 } ;
2267
2268 if (sfinfo.frames < 2 * items)
2269 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
2270 exit (1) ;
2271 } ;
2272
2273 if (! long_file_ok && sfinfo.frames > 2 * items)
2274 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
2275 exit (1) ;
2276 } ;
2277
2278 if (sfinfo.channels != 1)
2279 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
2280 exit (1) ;
2281 } ;
2282
2283 if (sfinfo.seekable != 1)
2284 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
2285 exit (1) ;
2286 } ;
2287
2288 check_log_buffer_or_die (file, __LINE__) ;
2289
2290 test_read_int_or_die (file, 0, test, items, __LINE__) ;
2291 for (k = 0 ; k < items ; k++)
2292 if (TRIBYTE_ERROR (orig [k], test [k]))
2293 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2294 oct_save_int (orig, test, items) ;
2295 exit (1) ;
2296 } ;
2297
2298 /* Test multiple short reads. */
2299 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2300
2301 total = 0 ;
2302 for (k = 1 ; k <= 32 ; k++)
2303 { int ik ;
2304
2305 test_read_int_or_die (file, 0, test + total, k, __LINE__) ;
2306 total += k ;
2307
2308 for (ik = 0 ; ik < total ; ik++)
2309 if (TRIBYTE_ERROR (orig [ik], test [ik]))
2310 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, ik, orig [ik], test [ik]) ;
2311 exit (1) ;
2312 } ;
2313 } ;
2314
2315 /* Seek to start of file. */
2316 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2317
2318 test_read_int_or_die (file, 0, test, 4, __LINE__) ;
2319 for (k = 0 ; k < 4 ; k++)
2320 if (TRIBYTE_ERROR (orig [k], test [k]))
2321 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2322 exit (1) ;
2323 } ;
2324
2325 /* For some codecs we can't go past here. */
2326 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
2327 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
2328 { sf_close (file) ;
2329 unlink (filename) ;
2330 printf ("no seek : ") ;
2331 return ;
2332 } ;
2333
2334 /* Seek to offset from start of file. */
2335 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
2336
2337 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
2338 for (k = 10 ; k < 14 ; k++)
2339 if (TRIBYTE_ERROR (orig [k], test [k]))
2340 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2341 exit (1) ;
2342 } ;
2343
2344 /* Seek to offset from current position. */
2345 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
2346
2347 test_read_int_or_die (file, 0, test + 20, 4, __LINE__) ;
2348 for (k = 20 ; k < 24 ; k++)
2349 if (TRIBYTE_ERROR (orig [k], test [k]))
2350 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2351 exit (1) ;
2352 } ;
2353
2354 /* Seek to offset from end of file. */
2355 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
2356
2357 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
2358 for (k = 10 ; k < 14 ; k++)
2359 if (TRIBYTE_ERROR (orig [k], test [k]))
2360 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2361 exit (1) ;
2362 } ;
2363
2364 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
2365 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2366
2367 count = 0 ;
2368 while (count < sfinfo.frames)
2369 count += sf_read_int (file, test, 311) ;
2370
2371 /* Check that no error has occurred. */
2372 if (sf_error (file))
2373 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
2374 puts (sf_strerror (file)) ;
2375 exit (1) ;
2376 } ;
2377
2378 /* Check that we haven't read beyond EOF. */
2379 if (count > sfinfo.frames)
2380 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
2381 exit (1) ;
2382 } ;
2383
2384 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
2385
2386 sf_close (file) ;
2387
2388 multi_seek_test (filename, format) ;
2389 write_seek_extend_test (filename, format) ;
2390
2391 } /* mono_24bit_test */
2392
2393 static void
stereo_24bit_test(const char * filename,int format,int long_file_ok,int allow_fd)2394 stereo_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
2395 { SNDFILE *file ;
2396 SF_INFO sfinfo ;
2397 int *orig, *test ;
2398 int k, items, frames ;
2399
2400 sfinfo.samplerate = 44100 ;
2401 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2402 sfinfo.channels = 2 ;
2403 sfinfo.format = format ;
2404
2405 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
2406
2407 orig = orig_data.i ;
2408 test = test_data.i ;
2409
2410 /* Make this a macro so gdb steps over it in one go. */
2411 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
2412
2413 items = DATA_LENGTH ;
2414 frames = items / sfinfo.channels ;
2415
2416 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2417
2418 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
2419
2420 test_writef_int_or_die (file, 0, orig, frames, __LINE__) ;
2421
2422 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
2423
2424 sf_close (file) ;
2425
2426 memset (test, 0, items * sizeof (int)) ;
2427
2428 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2429 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2430
2431 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
2432
2433 if (sfinfo.format != format)
2434 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
2435 __LINE__, format, sfinfo.format) ;
2436 exit (1) ;
2437 } ;
2438
2439 if (sfinfo.frames < frames)
2440 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
2441 __LINE__, sfinfo.frames, frames) ;
2442 exit (1) ;
2443 } ;
2444
2445 if (! long_file_ok && sfinfo.frames > frames)
2446 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
2447 __LINE__, sfinfo.frames, frames) ;
2448 exit (1) ;
2449 } ;
2450
2451 if (sfinfo.channels != 2)
2452 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
2453 exit (1) ;
2454 } ;
2455
2456 check_log_buffer_or_die (file, __LINE__) ;
2457
2458 test_readf_int_or_die (file, 0, test, frames, __LINE__) ;
2459 for (k = 0 ; k < items ; k++)
2460 if (TRIBYTE_ERROR (test [k], orig [k]))
2461 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2462 exit (1) ;
2463 } ;
2464
2465 /* Seek to start of file. */
2466 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2467
2468 test_readf_int_or_die (file, 0, test, 2, __LINE__) ;
2469 for (k = 0 ; k < 4 ; k++)
2470 if (TRIBYTE_ERROR (test [k], orig [k]))
2471 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2472 exit (1) ;
2473 } ;
2474
2475 /* Seek to offset from start of file. */
2476 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
2477
2478 /* Check for errors here. */
2479 if (sf_error (file))
2480 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
2481 puts (sf_strerror (file)) ;
2482 exit (1) ;
2483 } ;
2484
2485 if (sf_read_int (file, test, 1) > 0)
2486 { printf ("Line %d: Should return 0.\n", __LINE__) ;
2487 exit (1) ;
2488 } ;
2489
2490 if (! sf_error (file))
2491 { printf ("Line %d: Should return an error.\n", __LINE__) ;
2492 exit (1) ;
2493 } ;
2494 /*-----------------------*/
2495
2496 test_readf_int_or_die (file, 0, test + 10, 2, __LINE__) ;
2497 for (k = 20 ; k < 24 ; k++)
2498 if (TRIBYTE_ERROR (test [k], orig [k]))
2499 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2500 exit (1) ;
2501 } ;
2502
2503 /* Seek to offset from current position. */
2504 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
2505
2506 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
2507 for (k = 40 ; k < 44 ; k++)
2508 if (TRIBYTE_ERROR (test [k], orig [k]))
2509 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2510 exit (1) ;
2511 } ;
2512
2513 /* Seek to offset from end of file. */
2514 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
2515
2516 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
2517 for (k = 20 ; k < 24 ; k++)
2518 if (TRIBYTE_ERROR (test [k], orig [k]))
2519 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2520 exit (1) ;
2521 } ;
2522
2523 sf_close (file) ;
2524 } /* stereo_24bit_test */
2525
2526 static void
mono_rdwr_24bit_test(const char * filename,int format,int long_file_ok,int allow_fd)2527 mono_rdwr_24bit_test (const char *filename, int format, int long_file_ok, int allow_fd)
2528 { SNDFILE *file ;
2529 SF_INFO sfinfo ;
2530 int *orig, *test ;
2531 int k, pass ;
2532
2533 switch (format & SF_FORMAT_SUBMASK)
2534 { case SF_FORMAT_ALAC_16 :
2535 case SF_FORMAT_ALAC_20 :
2536 case SF_FORMAT_ALAC_24 :
2537 case SF_FORMAT_ALAC_32 :
2538 allow_fd = 0 ;
2539 break ;
2540
2541 default :
2542 break ;
2543 } ;
2544
2545 orig = orig_data.i ;
2546 test = test_data.i ;
2547
2548 sfinfo.samplerate = SAMPLE_RATE ;
2549 sfinfo.frames = DATA_LENGTH ;
2550 sfinfo.channels = 1 ;
2551 sfinfo.format = format ;
2552
2553 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
2554 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
2555 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
2556 unlink (filename) ;
2557 else
2558 { /* Create a short file. */
2559 create_short_file (filename) ;
2560
2561 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
2562 ** If this returns a valif pointer sf_open() screwed up.
2563 */
2564 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
2565 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
2566 exit (1) ;
2567 } ;
2568
2569 /* Truncate the file to zero bytes. */
2570 if (truncate_file_to_zero (filename) < 0)
2571 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
2572 perror (NULL) ;
2573 exit (1) ;
2574 } ;
2575 } ;
2576
2577 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
2578 ** all the usual data required when opening the file in WRITE mode.
2579 */
2580 sfinfo.samplerate = SAMPLE_RATE ;
2581 sfinfo.frames = DATA_LENGTH ;
2582 sfinfo.channels = 1 ;
2583 sfinfo.format = format ;
2584
2585 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2586
2587 /* Do 3 writes followed by reads. After each, check the data and the current
2588 ** read and write offsets.
2589 */
2590 for (pass = 1 ; pass <= 3 ; pass ++)
2591 { orig [20] = pass * 2 ;
2592
2593 /* Write some data. */
2594 test_write_int_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
2595
2596 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
2597
2598 /* Read what we just wrote. */
2599 test_read_int_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
2600
2601 /* Check the data. */
2602 for (k = 0 ; k < DATA_LENGTH ; k++)
2603 if (TRIBYTE_ERROR (orig [k], test [k]))
2604 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
2605 oct_save_int (orig, test, DATA_LENGTH) ;
2606 exit (1) ;
2607 } ;
2608
2609 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
2610 } ; /* for (pass ...) */
2611
2612 sf_close (file) ;
2613
2614 /* Open the file again to check the data. */
2615 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2616
2617 if (sfinfo.format != format)
2618 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
2619 exit (1) ;
2620 } ;
2621
2622 if (sfinfo.frames < 3 * DATA_LENGTH)
2623 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
2624 exit (1) ;
2625 }
2626
2627 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
2628 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
2629 exit (1) ;
2630 } ;
2631
2632 if (sfinfo.channels != 1)
2633 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
2634 exit (1) ;
2635 } ;
2636
2637 if (! long_file_ok)
2638 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
2639 else
2640 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
2641
2642 for (pass = 1 ; pass <= 3 ; pass ++)
2643 { orig [20] = pass * 2 ;
2644
2645 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
2646
2647 /* Read what we just wrote. */
2648 test_read_int_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
2649
2650 /* Check the data. */
2651 for (k = 0 ; k < DATA_LENGTH ; k++)
2652 if (TRIBYTE_ERROR (orig [k], test [k]))
2653 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
2654 oct_save_int (orig, test, DATA_LENGTH) ;
2655 exit (1) ;
2656 } ;
2657
2658 } ; /* for (pass ...) */
2659
2660 sf_close (file) ;
2661 } /* mono_rdwr_int_test */
2662
2663 static void
new_rdwr_24bit_test(const char * filename,int format,int allow_fd)2664 new_rdwr_24bit_test (const char *filename, int format, int allow_fd)
2665 { SNDFILE *wfile, *rwfile ;
2666 SF_INFO sfinfo ;
2667 int *orig, *test ;
2668 int items, frames ;
2669
2670 orig = orig_data.i ;
2671 test = test_data.i ;
2672
2673 sfinfo.samplerate = 44100 ;
2674 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2675 sfinfo.channels = 2 ;
2676 sfinfo.format = format ;
2677
2678 items = DATA_LENGTH ;
2679 frames = items / sfinfo.channels ;
2680
2681 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2682 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
2683 test_writef_int_or_die (wfile, 1, orig, frames, __LINE__) ;
2684 sf_write_sync (wfile) ;
2685 test_writef_int_or_die (wfile, 2, orig, frames, __LINE__) ;
2686 sf_write_sync (wfile) ;
2687
2688 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
2689 if (sfinfo.frames != 2 * frames)
2690 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
2691 exit (1) ;
2692 } ;
2693
2694 test_writef_int_or_die (wfile, 3, orig, frames, __LINE__) ;
2695
2696 test_readf_int_or_die (rwfile, 1, test, frames, __LINE__) ;
2697 test_readf_int_or_die (rwfile, 2, test, frames, __LINE__) ;
2698
2699 sf_close (wfile) ;
2700 sf_close (rwfile) ;
2701 } /* new_rdwr_24bit_test */
2702
2703
2704 /*======================================================================================
2705 */
2706
2707 static void mono_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2708 static void stereo_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2709 static void mono_rdwr_int_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
2710 static void new_rdwr_int_test (const char *filename, int format, int allow_fd) ;
2711 static void multi_seek_test (const char * filename, int format) ;
2712 static void write_seek_extend_test (const char * filename, int format) ;
2713
2714 static void
pcm_test_int(const char * filename,int format,int long_file_ok)2715 pcm_test_int (const char *filename, int format, int long_file_ok)
2716 { SF_INFO sfinfo ;
2717 int *orig ;
2718 int k, allow_fd ;
2719
2720 /* Sd2 files cannot be opened from an existing file descriptor. */
2721 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
2722
2723 print_test_name ("pcm_test_int", filename) ;
2724
2725 sfinfo.samplerate = 44100 ;
2726 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2727 sfinfo.channels = 1 ;
2728 sfinfo.format = format ;
2729
2730 test_sf_format_or_die (&sfinfo, __LINE__) ;
2731
2732 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
2733
2734 orig = orig_data.i ;
2735
2736 /* Make this a macro so gdb steps over it in one go. */
2737 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
2738
2739 /* Some test broken out here. */
2740
2741 mono_int_test (filename, format, long_file_ok, allow_fd) ;
2742
2743 /* Sub format DWVW does not allow seeking. */
2744 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
2745 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
2746 { unlink (filename) ;
2747 printf ("no seek : ok\n") ;
2748 return ;
2749 } ;
2750
2751 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
2752 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
2753 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
2754 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
2755 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
2756 )
2757 mono_rdwr_int_test (filename, format, long_file_ok, allow_fd) ;
2758
2759 /* If the format doesn't support stereo we're done. */
2760 sfinfo.channels = 2 ;
2761 if (sf_format_check (&sfinfo) == 0)
2762 { unlink (filename) ;
2763 puts ("no stereo : ok") ;
2764 return ;
2765 } ;
2766
2767 stereo_int_test (filename, format, long_file_ok, allow_fd) ;
2768
2769 /* New read/write test. Not sure if this is needed yet. */
2770
2771 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
2772 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
2773 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
2774 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
2775 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
2776 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
2777 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
2778 )
2779 new_rdwr_int_test (filename, format, allow_fd) ;
2780
2781 delete_file (format, filename) ;
2782
2783 puts ("ok") ;
2784 return ;
2785 } /* pcm_test_int */
2786
2787 static void
mono_int_test(const char * filename,int format,int long_file_ok,int allow_fd)2788 mono_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
2789 { SNDFILE *file ;
2790 SF_INFO sfinfo ;
2791 int *orig, *test ;
2792 sf_count_t count ;
2793 int k, items, total ;
2794
2795 sfinfo.samplerate = 44100 ;
2796 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2797 sfinfo.channels = 1 ;
2798 sfinfo.format = format ;
2799
2800 orig = orig_data.i ;
2801 test = test_data.i ;
2802
2803 items = DATA_LENGTH ;
2804
2805 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2806
2807 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
2808 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
2809 exit (1) ;
2810 } ;
2811
2812 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
2813
2814 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
2815 sf_write_sync (file) ;
2816 test_write_int_or_die (file, 0, orig, items, __LINE__) ;
2817 sf_write_sync (file) ;
2818
2819 /* Add non-audio data after the audio. */
2820 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
2821
2822 sf_close (file) ;
2823
2824 memset (test, 0, items * sizeof (int)) ;
2825
2826 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2827 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2828
2829 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
2830
2831 if (sfinfo.format != format)
2832 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
2833 exit (1) ;
2834 } ;
2835
2836 if (sfinfo.frames < 2 * items)
2837 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
2838 exit (1) ;
2839 } ;
2840
2841 if (! long_file_ok && sfinfo.frames > 2 * items)
2842 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
2843 exit (1) ;
2844 } ;
2845
2846 if (sfinfo.channels != 1)
2847 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
2848 exit (1) ;
2849 } ;
2850
2851 if (sfinfo.seekable != 1)
2852 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
2853 exit (1) ;
2854 } ;
2855
2856 check_log_buffer_or_die (file, __LINE__) ;
2857
2858 test_read_int_or_die (file, 0, test, items, __LINE__) ;
2859 for (k = 0 ; k < items ; k++)
2860 if (INT_ERROR (orig [k], test [k]))
2861 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2862 oct_save_int (orig, test, items) ;
2863 exit (1) ;
2864 } ;
2865
2866 /* Test multiple short reads. */
2867 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2868
2869 total = 0 ;
2870 for (k = 1 ; k <= 32 ; k++)
2871 { int ik ;
2872
2873 test_read_int_or_die (file, 0, test + total, k, __LINE__) ;
2874 total += k ;
2875
2876 for (ik = 0 ; ik < total ; ik++)
2877 if (INT_ERROR (orig [ik], test [ik]))
2878 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, ik, orig [ik], test [ik]) ;
2879 exit (1) ;
2880 } ;
2881 } ;
2882
2883 /* Seek to start of file. */
2884 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2885
2886 test_read_int_or_die (file, 0, test, 4, __LINE__) ;
2887 for (k = 0 ; k < 4 ; k++)
2888 if (INT_ERROR (orig [k], test [k]))
2889 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
2890 exit (1) ;
2891 } ;
2892
2893 /* For some codecs we can't go past here. */
2894 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
2895 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
2896 { sf_close (file) ;
2897 unlink (filename) ;
2898 printf ("no seek : ") ;
2899 return ;
2900 } ;
2901
2902 /* Seek to offset from start of file. */
2903 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
2904
2905 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
2906 for (k = 10 ; k < 14 ; k++)
2907 if (INT_ERROR (orig [k], test [k]))
2908 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2909 exit (1) ;
2910 } ;
2911
2912 /* Seek to offset from current position. */
2913 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
2914
2915 test_read_int_or_die (file, 0, test + 20, 4, __LINE__) ;
2916 for (k = 20 ; k < 24 ; k++)
2917 if (INT_ERROR (orig [k], test [k]))
2918 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2919 exit (1) ;
2920 } ;
2921
2922 /* Seek to offset from end of file. */
2923 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
2924
2925 test_read_int_or_die (file, 0, test + 10, 4, __LINE__) ;
2926 for (k = 10 ; k < 14 ; k++)
2927 if (INT_ERROR (orig [k], test [k]))
2928 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : 0x%X => 0x%X).\n", __LINE__, k, test [k], orig [k]) ;
2929 exit (1) ;
2930 } ;
2931
2932 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
2933 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
2934
2935 count = 0 ;
2936 while (count < sfinfo.frames)
2937 count += sf_read_int (file, test, 311) ;
2938
2939 /* Check that no error has occurred. */
2940 if (sf_error (file))
2941 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
2942 puts (sf_strerror (file)) ;
2943 exit (1) ;
2944 } ;
2945
2946 /* Check that we haven't read beyond EOF. */
2947 if (count > sfinfo.frames)
2948 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
2949 exit (1) ;
2950 } ;
2951
2952 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
2953
2954 sf_close (file) ;
2955
2956 multi_seek_test (filename, format) ;
2957 write_seek_extend_test (filename, format) ;
2958
2959 } /* mono_int_test */
2960
2961 static void
stereo_int_test(const char * filename,int format,int long_file_ok,int allow_fd)2962 stereo_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
2963 { SNDFILE *file ;
2964 SF_INFO sfinfo ;
2965 int *orig, *test ;
2966 int k, items, frames ;
2967
2968 sfinfo.samplerate = 44100 ;
2969 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
2970 sfinfo.channels = 2 ;
2971 sfinfo.format = format ;
2972
2973 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
2974
2975 orig = orig_data.i ;
2976 test = test_data.i ;
2977
2978 /* Make this a macro so gdb steps over it in one go. */
2979 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
2980
2981 items = DATA_LENGTH ;
2982 frames = items / sfinfo.channels ;
2983
2984 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
2985
2986 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
2987
2988 test_writef_int_or_die (file, 0, orig, frames, __LINE__) ;
2989
2990 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
2991
2992 sf_close (file) ;
2993
2994 memset (test, 0, items * sizeof (int)) ;
2995
2996 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2997 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2998
2999 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
3000
3001 if (sfinfo.format != format)
3002 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
3003 __LINE__, format, sfinfo.format) ;
3004 exit (1) ;
3005 } ;
3006
3007 if (sfinfo.frames < frames)
3008 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
3009 __LINE__, sfinfo.frames, frames) ;
3010 exit (1) ;
3011 } ;
3012
3013 if (! long_file_ok && sfinfo.frames > frames)
3014 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
3015 __LINE__, sfinfo.frames, frames) ;
3016 exit (1) ;
3017 } ;
3018
3019 if (sfinfo.channels != 2)
3020 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
3021 exit (1) ;
3022 } ;
3023
3024 check_log_buffer_or_die (file, __LINE__) ;
3025
3026 test_readf_int_or_die (file, 0, test, frames, __LINE__) ;
3027 for (k = 0 ; k < items ; k++)
3028 if (INT_ERROR (test [k], orig [k]))
3029 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
3030 exit (1) ;
3031 } ;
3032
3033 /* Seek to start of file. */
3034 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
3035
3036 test_readf_int_or_die (file, 0, test, 2, __LINE__) ;
3037 for (k = 0 ; k < 4 ; k++)
3038 if (INT_ERROR (test [k], orig [k]))
3039 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
3040 exit (1) ;
3041 } ;
3042
3043 /* Seek to offset from start of file. */
3044 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
3045
3046 /* Check for errors here. */
3047 if (sf_error (file))
3048 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
3049 puts (sf_strerror (file)) ;
3050 exit (1) ;
3051 } ;
3052
3053 if (sf_read_int (file, test, 1) > 0)
3054 { printf ("Line %d: Should return 0.\n", __LINE__) ;
3055 exit (1) ;
3056 } ;
3057
3058 if (! sf_error (file))
3059 { printf ("Line %d: Should return an error.\n", __LINE__) ;
3060 exit (1) ;
3061 } ;
3062 /*-----------------------*/
3063
3064 test_readf_int_or_die (file, 0, test + 10, 2, __LINE__) ;
3065 for (k = 20 ; k < 24 ; k++)
3066 if (INT_ERROR (test [k], orig [k]))
3067 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
3068 exit (1) ;
3069 } ;
3070
3071 /* Seek to offset from current position. */
3072 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
3073
3074 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
3075 for (k = 40 ; k < 44 ; k++)
3076 if (INT_ERROR (test [k], orig [k]))
3077 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
3078 exit (1) ;
3079 } ;
3080
3081 /* Seek to offset from end of file. */
3082 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
3083
3084 test_readf_int_or_die (file, 0, test + 20, 2, __LINE__) ;
3085 for (k = 20 ; k < 24 ; k++)
3086 if (INT_ERROR (test [k], orig [k]))
3087 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : 0x%X => 0x%X).\n", __LINE__, k, orig [k], test [k]) ;
3088 exit (1) ;
3089 } ;
3090
3091 sf_close (file) ;
3092 } /* stereo_int_test */
3093
3094 static void
mono_rdwr_int_test(const char * filename,int format,int long_file_ok,int allow_fd)3095 mono_rdwr_int_test (const char *filename, int format, int long_file_ok, int allow_fd)
3096 { SNDFILE *file ;
3097 SF_INFO sfinfo ;
3098 int *orig, *test ;
3099 int k, pass ;
3100
3101 switch (format & SF_FORMAT_SUBMASK)
3102 { case SF_FORMAT_ALAC_16 :
3103 case SF_FORMAT_ALAC_20 :
3104 case SF_FORMAT_ALAC_24 :
3105 case SF_FORMAT_ALAC_32 :
3106 allow_fd = 0 ;
3107 break ;
3108
3109 default :
3110 break ;
3111 } ;
3112
3113 orig = orig_data.i ;
3114 test = test_data.i ;
3115
3116 sfinfo.samplerate = SAMPLE_RATE ;
3117 sfinfo.frames = DATA_LENGTH ;
3118 sfinfo.channels = 1 ;
3119 sfinfo.format = format ;
3120
3121 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
3122 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
3123 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
3124 unlink (filename) ;
3125 else
3126 { /* Create a short file. */
3127 create_short_file (filename) ;
3128
3129 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
3130 ** If this returns a valif pointer sf_open() screwed up.
3131 */
3132 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
3133 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
3134 exit (1) ;
3135 } ;
3136
3137 /* Truncate the file to zero bytes. */
3138 if (truncate_file_to_zero (filename) < 0)
3139 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
3140 perror (NULL) ;
3141 exit (1) ;
3142 } ;
3143 } ;
3144
3145 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
3146 ** all the usual data required when opening the file in WRITE mode.
3147 */
3148 sfinfo.samplerate = SAMPLE_RATE ;
3149 sfinfo.frames = DATA_LENGTH ;
3150 sfinfo.channels = 1 ;
3151 sfinfo.format = format ;
3152
3153 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3154
3155 /* Do 3 writes followed by reads. After each, check the data and the current
3156 ** read and write offsets.
3157 */
3158 for (pass = 1 ; pass <= 3 ; pass ++)
3159 { orig [20] = pass * 2 ;
3160
3161 /* Write some data. */
3162 test_write_int_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
3163
3164 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
3165
3166 /* Read what we just wrote. */
3167 test_read_int_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
3168
3169 /* Check the data. */
3170 for (k = 0 ; k < DATA_LENGTH ; k++)
3171 if (INT_ERROR (orig [k], test [k]))
3172 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
3173 oct_save_int (orig, test, DATA_LENGTH) ;
3174 exit (1) ;
3175 } ;
3176
3177 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
3178 } ; /* for (pass ...) */
3179
3180 sf_close (file) ;
3181
3182 /* Open the file again to check the data. */
3183 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3184
3185 if (sfinfo.format != format)
3186 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
3187 exit (1) ;
3188 } ;
3189
3190 if (sfinfo.frames < 3 * DATA_LENGTH)
3191 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
3192 exit (1) ;
3193 }
3194
3195 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
3196 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
3197 exit (1) ;
3198 } ;
3199
3200 if (sfinfo.channels != 1)
3201 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
3202 exit (1) ;
3203 } ;
3204
3205 if (! long_file_ok)
3206 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
3207 else
3208 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
3209
3210 for (pass = 1 ; pass <= 3 ; pass ++)
3211 { orig [20] = pass * 2 ;
3212
3213 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
3214
3215 /* Read what we just wrote. */
3216 test_read_int_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
3217
3218 /* Check the data. */
3219 for (k = 0 ; k < DATA_LENGTH ; k++)
3220 if (INT_ERROR (orig [k], test [k]))
3221 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (0x%X => 0x%X).\n", __LINE__, pass, k, orig [k], test [k]) ;
3222 oct_save_int (orig, test, DATA_LENGTH) ;
3223 exit (1) ;
3224 } ;
3225
3226 } ; /* for (pass ...) */
3227
3228 sf_close (file) ;
3229 } /* mono_rdwr_int_test */
3230
3231 static void
new_rdwr_int_test(const char * filename,int format,int allow_fd)3232 new_rdwr_int_test (const char *filename, int format, int allow_fd)
3233 { SNDFILE *wfile, *rwfile ;
3234 SF_INFO sfinfo ;
3235 int *orig, *test ;
3236 int items, frames ;
3237
3238 orig = orig_data.i ;
3239 test = test_data.i ;
3240
3241 sfinfo.samplerate = 44100 ;
3242 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3243 sfinfo.channels = 2 ;
3244 sfinfo.format = format ;
3245
3246 items = DATA_LENGTH ;
3247 frames = items / sfinfo.channels ;
3248
3249 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
3250 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
3251 test_writef_int_or_die (wfile, 1, orig, frames, __LINE__) ;
3252 sf_write_sync (wfile) ;
3253 test_writef_int_or_die (wfile, 2, orig, frames, __LINE__) ;
3254 sf_write_sync (wfile) ;
3255
3256 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3257 if (sfinfo.frames != 2 * frames)
3258 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
3259 exit (1) ;
3260 } ;
3261
3262 test_writef_int_or_die (wfile, 3, orig, frames, __LINE__) ;
3263
3264 test_readf_int_or_die (rwfile, 1, test, frames, __LINE__) ;
3265 test_readf_int_or_die (rwfile, 2, test, frames, __LINE__) ;
3266
3267 sf_close (wfile) ;
3268 sf_close (rwfile) ;
3269 } /* new_rdwr_int_test */
3270
3271
3272 /*======================================================================================
3273 */
3274
3275 static void mono_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3276 static void stereo_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3277 static void mono_rdwr_float_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3278 static void new_rdwr_float_test (const char *filename, int format, int allow_fd) ;
3279 static void multi_seek_test (const char * filename, int format) ;
3280 static void write_seek_extend_test (const char * filename, int format) ;
3281
3282 static void
pcm_test_float(const char * filename,int format,int long_file_ok)3283 pcm_test_float (const char *filename, int format, int long_file_ok)
3284 { SF_INFO sfinfo ;
3285 float *orig ;
3286 int k, allow_fd ;
3287
3288 /* Sd2 files cannot be opened from an existing file descriptor. */
3289 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
3290
3291 print_test_name ("pcm_test_float", filename) ;
3292
3293 sfinfo.samplerate = 44100 ;
3294 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3295 sfinfo.channels = 1 ;
3296 sfinfo.format = format ;
3297
3298 test_sf_format_or_die (&sfinfo, __LINE__) ;
3299
3300 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
3301
3302 orig = orig_data.f ;
3303
3304 /* Make this a macro so gdb steps over it in one go. */
3305 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
3306
3307 /* Some test broken out here. */
3308
3309 mono_float_test (filename, format, long_file_ok, allow_fd) ;
3310
3311 /* Sub format DWVW does not allow seeking. */
3312 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
3313 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
3314 { unlink (filename) ;
3315 printf ("no seek : ok\n") ;
3316 return ;
3317 } ;
3318
3319 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
3320 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
3321 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
3322 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
3323 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
3324 )
3325 mono_rdwr_float_test (filename, format, long_file_ok, allow_fd) ;
3326
3327 /* If the format doesn't support stereo we're done. */
3328 sfinfo.channels = 2 ;
3329 if (sf_format_check (&sfinfo) == 0)
3330 { unlink (filename) ;
3331 puts ("no stereo : ok") ;
3332 return ;
3333 } ;
3334
3335 stereo_float_test (filename, format, long_file_ok, allow_fd) ;
3336
3337 /* New read/write test. Not sure if this is needed yet. */
3338
3339 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
3340 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
3341 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
3342 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
3343 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
3344 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
3345 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
3346 )
3347 new_rdwr_float_test (filename, format, allow_fd) ;
3348
3349 delete_file (format, filename) ;
3350
3351 puts ("ok") ;
3352 return ;
3353 } /* pcm_test_float */
3354
3355 static void
mono_float_test(const char * filename,int format,int long_file_ok,int allow_fd)3356 mono_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
3357 { SNDFILE *file ;
3358 SF_INFO sfinfo ;
3359 float *orig, *test ;
3360 sf_count_t count ;
3361 int k, items, total ;
3362
3363 sfinfo.samplerate = 44100 ;
3364 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3365 sfinfo.channels = 1 ;
3366 sfinfo.format = format ;
3367
3368 orig = orig_data.f ;
3369 test = test_data.f ;
3370
3371 items = DATA_LENGTH ;
3372
3373 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
3374
3375 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
3376 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
3377 exit (1) ;
3378 } ;
3379
3380 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
3381
3382 test_write_float_or_die (file, 0, orig, items, __LINE__) ;
3383 sf_write_sync (file) ;
3384 test_write_float_or_die (file, 0, orig, items, __LINE__) ;
3385 sf_write_sync (file) ;
3386
3387 /* Add non-audio data after the audio. */
3388 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
3389
3390 sf_close (file) ;
3391
3392 memset (test, 0, items * sizeof (float)) ;
3393
3394 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
3395 memset (&sfinfo, 0, sizeof (sfinfo)) ;
3396
3397 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
3398
3399 if (sfinfo.format != format)
3400 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
3401 exit (1) ;
3402 } ;
3403
3404 if (sfinfo.frames < 2 * items)
3405 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
3406 exit (1) ;
3407 } ;
3408
3409 if (! long_file_ok && sfinfo.frames > 2 * items)
3410 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
3411 exit (1) ;
3412 } ;
3413
3414 if (sfinfo.channels != 1)
3415 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
3416 exit (1) ;
3417 } ;
3418
3419 if (sfinfo.seekable != 1)
3420 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
3421 exit (1) ;
3422 } ;
3423
3424 check_log_buffer_or_die (file, __LINE__) ;
3425
3426 test_read_float_or_die (file, 0, test, items, __LINE__) ;
3427 for (k = 0 ; k < items ; k++)
3428 if (FLOAT_ERROR (orig [k], test [k]))
3429 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3430 oct_save_float (orig, test, items) ;
3431 exit (1) ;
3432 } ;
3433
3434 /* Test multiple short reads. */
3435 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
3436
3437 total = 0 ;
3438 for (k = 1 ; k <= 32 ; k++)
3439 { int ik ;
3440
3441 test_read_float_or_die (file, 0, test + total, k, __LINE__) ;
3442 total += k ;
3443
3444 for (ik = 0 ; ik < total ; ik++)
3445 if (FLOAT_ERROR (orig [ik], test [ik]))
3446 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, ik, orig [ik], test [ik]) ;
3447 exit (1) ;
3448 } ;
3449 } ;
3450
3451 /* Seek to start of file. */
3452 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
3453
3454 test_read_float_or_die (file, 0, test, 4, __LINE__) ;
3455 for (k = 0 ; k < 4 ; k++)
3456 if (FLOAT_ERROR (orig [k], test [k]))
3457 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3458 exit (1) ;
3459 } ;
3460
3461 /* For some codecs we can't go past here. */
3462 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
3463 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
3464 { sf_close (file) ;
3465 unlink (filename) ;
3466 printf ("no seek : ") ;
3467 return ;
3468 } ;
3469
3470 /* Seek to offset from start of file. */
3471 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
3472
3473 test_read_float_or_die (file, 0, test + 10, 4, __LINE__) ;
3474 for (k = 10 ; k < 14 ; k++)
3475 if (FLOAT_ERROR (orig [k], test [k]))
3476 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
3477 exit (1) ;
3478 } ;
3479
3480 /* Seek to offset from current position. */
3481 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
3482
3483 test_read_float_or_die (file, 0, test + 20, 4, __LINE__) ;
3484 for (k = 20 ; k < 24 ; k++)
3485 if (FLOAT_ERROR (orig [k], test [k]))
3486 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
3487 exit (1) ;
3488 } ;
3489
3490 /* Seek to offset from end of file. */
3491 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
3492
3493 test_read_float_or_die (file, 0, test + 10, 4, __LINE__) ;
3494 for (k = 10 ; k < 14 ; k++)
3495 if (FLOAT_ERROR (orig [k], test [k]))
3496 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
3497 exit (1) ;
3498 } ;
3499
3500 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
3501 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
3502
3503 count = 0 ;
3504 while (count < sfinfo.frames)
3505 count += sf_read_float (file, test, 311) ;
3506
3507 /* Check that no error has occurred. */
3508 if (sf_error (file))
3509 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
3510 puts (sf_strerror (file)) ;
3511 exit (1) ;
3512 } ;
3513
3514 /* Check that we haven't read beyond EOF. */
3515 if (count > sfinfo.frames)
3516 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
3517 exit (1) ;
3518 } ;
3519
3520 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
3521
3522 sf_close (file) ;
3523
3524 multi_seek_test (filename, format) ;
3525 write_seek_extend_test (filename, format) ;
3526
3527 } /* mono_float_test */
3528
3529 static void
stereo_float_test(const char * filename,int format,int long_file_ok,int allow_fd)3530 stereo_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
3531 { SNDFILE *file ;
3532 SF_INFO sfinfo ;
3533 float *orig, *test ;
3534 int k, items, frames ;
3535
3536 sfinfo.samplerate = 44100 ;
3537 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3538 sfinfo.channels = 2 ;
3539 sfinfo.format = format ;
3540
3541 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
3542
3543 orig = orig_data.f ;
3544 test = test_data.f ;
3545
3546 /* Make this a macro so gdb steps over it in one go. */
3547 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
3548
3549 items = DATA_LENGTH ;
3550 frames = items / sfinfo.channels ;
3551
3552 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
3553
3554 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
3555
3556 test_writef_float_or_die (file, 0, orig, frames, __LINE__) ;
3557
3558 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
3559
3560 sf_close (file) ;
3561
3562 memset (test, 0, items * sizeof (float)) ;
3563
3564 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
3565 memset (&sfinfo, 0, sizeof (sfinfo)) ;
3566
3567 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
3568
3569 if (sfinfo.format != format)
3570 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
3571 __LINE__, format, sfinfo.format) ;
3572 exit (1) ;
3573 } ;
3574
3575 if (sfinfo.frames < frames)
3576 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
3577 __LINE__, sfinfo.frames, frames) ;
3578 exit (1) ;
3579 } ;
3580
3581 if (! long_file_ok && sfinfo.frames > frames)
3582 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
3583 __LINE__, sfinfo.frames, frames) ;
3584 exit (1) ;
3585 } ;
3586
3587 if (sfinfo.channels != 2)
3588 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
3589 exit (1) ;
3590 } ;
3591
3592 check_log_buffer_or_die (file, __LINE__) ;
3593
3594 test_readf_float_or_die (file, 0, test, frames, __LINE__) ;
3595 for (k = 0 ; k < items ; k++)
3596 if (FLOAT_ERROR (test [k], orig [k]))
3597 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3598 exit (1) ;
3599 } ;
3600
3601 /* Seek to start of file. */
3602 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
3603
3604 test_readf_float_or_die (file, 0, test, 2, __LINE__) ;
3605 for (k = 0 ; k < 4 ; k++)
3606 if (FLOAT_ERROR (test [k], orig [k]))
3607 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3608 exit (1) ;
3609 } ;
3610
3611 /* Seek to offset from start of file. */
3612 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
3613
3614 /* Check for errors here. */
3615 if (sf_error (file))
3616 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
3617 puts (sf_strerror (file)) ;
3618 exit (1) ;
3619 } ;
3620
3621 if (sf_read_float (file, test, 1) > 0)
3622 { printf ("Line %d: Should return 0.\n", __LINE__) ;
3623 exit (1) ;
3624 } ;
3625
3626 if (! sf_error (file))
3627 { printf ("Line %d: Should return an error.\n", __LINE__) ;
3628 exit (1) ;
3629 } ;
3630 /*-----------------------*/
3631
3632 test_readf_float_or_die (file, 0, test + 10, 2, __LINE__) ;
3633 for (k = 20 ; k < 24 ; k++)
3634 if (FLOAT_ERROR (test [k], orig [k]))
3635 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3636 exit (1) ;
3637 } ;
3638
3639 /* Seek to offset from current position. */
3640 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
3641
3642 test_readf_float_or_die (file, 0, test + 20, 2, __LINE__) ;
3643 for (k = 40 ; k < 44 ; k++)
3644 if (FLOAT_ERROR (test [k], orig [k]))
3645 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3646 exit (1) ;
3647 } ;
3648
3649 /* Seek to offset from end of file. */
3650 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
3651
3652 test_readf_float_or_die (file, 0, test + 20, 2, __LINE__) ;
3653 for (k = 20 ; k < 24 ; k++)
3654 if (FLOAT_ERROR (test [k], orig [k]))
3655 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3656 exit (1) ;
3657 } ;
3658
3659 sf_close (file) ;
3660 } /* stereo_float_test */
3661
3662 static void
mono_rdwr_float_test(const char * filename,int format,int long_file_ok,int allow_fd)3663 mono_rdwr_float_test (const char *filename, int format, int long_file_ok, int allow_fd)
3664 { SNDFILE *file ;
3665 SF_INFO sfinfo ;
3666 float *orig, *test ;
3667 int k, pass ;
3668
3669 switch (format & SF_FORMAT_SUBMASK)
3670 { case SF_FORMAT_ALAC_16 :
3671 case SF_FORMAT_ALAC_20 :
3672 case SF_FORMAT_ALAC_24 :
3673 case SF_FORMAT_ALAC_32 :
3674 allow_fd = 0 ;
3675 break ;
3676
3677 default :
3678 break ;
3679 } ;
3680
3681 orig = orig_data.f ;
3682 test = test_data.f ;
3683
3684 sfinfo.samplerate = SAMPLE_RATE ;
3685 sfinfo.frames = DATA_LENGTH ;
3686 sfinfo.channels = 1 ;
3687 sfinfo.format = format ;
3688
3689 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
3690 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
3691 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
3692 unlink (filename) ;
3693 else
3694 { /* Create a short file. */
3695 create_short_file (filename) ;
3696
3697 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
3698 ** If this returns a valif pointer sf_open() screwed up.
3699 */
3700 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
3701 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
3702 exit (1) ;
3703 } ;
3704
3705 /* Truncate the file to zero bytes. */
3706 if (truncate_file_to_zero (filename) < 0)
3707 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
3708 perror (NULL) ;
3709 exit (1) ;
3710 } ;
3711 } ;
3712
3713 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
3714 ** all the usual data required when opening the file in WRITE mode.
3715 */
3716 sfinfo.samplerate = SAMPLE_RATE ;
3717 sfinfo.frames = DATA_LENGTH ;
3718 sfinfo.channels = 1 ;
3719 sfinfo.format = format ;
3720
3721 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3722
3723 /* Do 3 writes followed by reads. After each, check the data and the current
3724 ** read and write offsets.
3725 */
3726 for (pass = 1 ; pass <= 3 ; pass ++)
3727 { orig [20] = pass * 2 ;
3728
3729 /* Write some data. */
3730 test_write_float_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
3731
3732 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
3733
3734 /* Read what we just wrote. */
3735 test_read_float_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
3736
3737 /* Check the data. */
3738 for (k = 0 ; k < DATA_LENGTH ; k++)
3739 if (FLOAT_ERROR (orig [k], test [k]))
3740 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (%g => %g).\n", __LINE__, pass, k, orig [k], test [k]) ;
3741 oct_save_float (orig, test, DATA_LENGTH) ;
3742 exit (1) ;
3743 } ;
3744
3745 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
3746 } ; /* for (pass ...) */
3747
3748 sf_close (file) ;
3749
3750 /* Open the file again to check the data. */
3751 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3752
3753 if (sfinfo.format != format)
3754 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
3755 exit (1) ;
3756 } ;
3757
3758 if (sfinfo.frames < 3 * DATA_LENGTH)
3759 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
3760 exit (1) ;
3761 }
3762
3763 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
3764 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
3765 exit (1) ;
3766 } ;
3767
3768 if (sfinfo.channels != 1)
3769 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
3770 exit (1) ;
3771 } ;
3772
3773 if (! long_file_ok)
3774 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
3775 else
3776 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
3777
3778 for (pass = 1 ; pass <= 3 ; pass ++)
3779 { orig [20] = pass * 2 ;
3780
3781 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
3782
3783 /* Read what we just wrote. */
3784 test_read_float_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
3785
3786 /* Check the data. */
3787 for (k = 0 ; k < DATA_LENGTH ; k++)
3788 if (FLOAT_ERROR (orig [k], test [k]))
3789 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (%g => %g).\n", __LINE__, pass, k, orig [k], test [k]) ;
3790 oct_save_float (orig, test, DATA_LENGTH) ;
3791 exit (1) ;
3792 } ;
3793
3794 } ; /* for (pass ...) */
3795
3796 sf_close (file) ;
3797 } /* mono_rdwr_float_test */
3798
3799 static void
new_rdwr_float_test(const char * filename,int format,int allow_fd)3800 new_rdwr_float_test (const char *filename, int format, int allow_fd)
3801 { SNDFILE *wfile, *rwfile ;
3802 SF_INFO sfinfo ;
3803 float *orig, *test ;
3804 int items, frames ;
3805
3806 orig = orig_data.f ;
3807 test = test_data.f ;
3808
3809 sfinfo.samplerate = 44100 ;
3810 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3811 sfinfo.channels = 2 ;
3812 sfinfo.format = format ;
3813
3814 items = DATA_LENGTH ;
3815 frames = items / sfinfo.channels ;
3816
3817 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
3818 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
3819 test_writef_float_or_die (wfile, 1, orig, frames, __LINE__) ;
3820 sf_write_sync (wfile) ;
3821 test_writef_float_or_die (wfile, 2, orig, frames, __LINE__) ;
3822 sf_write_sync (wfile) ;
3823
3824 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
3825 if (sfinfo.frames != 2 * frames)
3826 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
3827 exit (1) ;
3828 } ;
3829
3830 test_writef_float_or_die (wfile, 3, orig, frames, __LINE__) ;
3831
3832 test_readf_float_or_die (rwfile, 1, test, frames, __LINE__) ;
3833 test_readf_float_or_die (rwfile, 2, test, frames, __LINE__) ;
3834
3835 sf_close (wfile) ;
3836 sf_close (rwfile) ;
3837 } /* new_rdwr_float_test */
3838
3839
3840 /*======================================================================================
3841 */
3842
3843 static void mono_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3844 static void stereo_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3845 static void mono_rdwr_double_test (const char *filename, int format, int long_file_ok, int allow_fd) ;
3846 static void new_rdwr_double_test (const char *filename, int format, int allow_fd) ;
3847 static void multi_seek_test (const char * filename, int format) ;
3848 static void write_seek_extend_test (const char * filename, int format) ;
3849
3850 static void
pcm_test_double(const char * filename,int format,int long_file_ok)3851 pcm_test_double (const char *filename, int format, int long_file_ok)
3852 { SF_INFO sfinfo ;
3853 double *orig ;
3854 int k, allow_fd ;
3855
3856 /* Sd2 files cannot be opened from an existing file descriptor. */
3857 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
3858
3859 print_test_name ("pcm_test_double", filename) ;
3860
3861 sfinfo.samplerate = 44100 ;
3862 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3863 sfinfo.channels = 1 ;
3864 sfinfo.format = format ;
3865
3866 test_sf_format_or_die (&sfinfo, __LINE__) ;
3867
3868 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
3869
3870 orig = orig_data.d ;
3871
3872 /* Make this a macro so gdb steps over it in one go. */
3873 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
3874
3875 /* Some test broken out here. */
3876
3877 mono_double_test (filename, format, long_file_ok, allow_fd) ;
3878
3879 /* Sub format DWVW does not allow seeking. */
3880 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
3881 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
3882 { unlink (filename) ;
3883 printf ("no seek : ok\n") ;
3884 return ;
3885 } ;
3886
3887 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
3888 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
3889 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
3890 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
3891 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
3892 )
3893 mono_rdwr_double_test (filename, format, long_file_ok, allow_fd) ;
3894
3895 /* If the format doesn't support stereo we're done. */
3896 sfinfo.channels = 2 ;
3897 if (sf_format_check (&sfinfo) == 0)
3898 { unlink (filename) ;
3899 puts ("no stereo : ok") ;
3900 return ;
3901 } ;
3902
3903 stereo_double_test (filename, format, long_file_ok, allow_fd) ;
3904
3905 /* New read/write test. Not sure if this is needed yet. */
3906
3907 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF
3908 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC
3909 && (format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC
3910 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_16
3911 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_20
3912 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_24
3913 && (format & SF_FORMAT_SUBMASK) != SF_FORMAT_ALAC_32
3914 )
3915 new_rdwr_double_test (filename, format, allow_fd) ;
3916
3917 delete_file (format, filename) ;
3918
3919 puts ("ok") ;
3920 return ;
3921 } /* pcm_test_double */
3922
3923 static void
mono_double_test(const char * filename,int format,int long_file_ok,int allow_fd)3924 mono_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
3925 { SNDFILE *file ;
3926 SF_INFO sfinfo ;
3927 double *orig, *test ;
3928 sf_count_t count ;
3929 int k, items, total ;
3930
3931 sfinfo.samplerate = 44100 ;
3932 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
3933 sfinfo.channels = 1 ;
3934 sfinfo.format = format ;
3935
3936 orig = orig_data.d ;
3937 test = test_data.d ;
3938
3939 items = DATA_LENGTH ;
3940
3941 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
3942
3943 if (sfinfo.frames || sfinfo.sections || sfinfo.seekable)
3944 { printf ("\n\nLine %d : Weird SF_INFO fields.\n", __LINE__) ;
3945 exit (1) ;
3946 } ;
3947
3948 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
3949
3950 test_write_double_or_die (file, 0, orig, items, __LINE__) ;
3951 sf_write_sync (file) ;
3952 test_write_double_or_die (file, 0, orig, items, __LINE__) ;
3953 sf_write_sync (file) ;
3954
3955 /* Add non-audio data after the audio. */
3956 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
3957
3958 sf_close (file) ;
3959
3960 memset (test, 0, items * sizeof (double)) ;
3961
3962 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
3963 memset (&sfinfo, 0, sizeof (sfinfo)) ;
3964
3965 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
3966
3967 if (sfinfo.format != format)
3968 { printf ("\n\nLine %d : Mono : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
3969 exit (1) ;
3970 } ;
3971
3972 if (sfinfo.frames < 2 * items)
3973 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
3974 exit (1) ;
3975 } ;
3976
3977 if (! long_file_ok && sfinfo.frames > 2 * items)
3978 { printf ("\n\nLine %d : Mono : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, items) ;
3979 exit (1) ;
3980 } ;
3981
3982 if (sfinfo.channels != 1)
3983 { printf ("\n\nLine %d : Mono : Incorrect number of channels in file.\n", __LINE__) ;
3984 exit (1) ;
3985 } ;
3986
3987 if (sfinfo.seekable != 1)
3988 { printf ("\n\nLine %d : File should be seekable.\n", __LINE__) ;
3989 exit (1) ;
3990 } ;
3991
3992 check_log_buffer_or_die (file, __LINE__) ;
3993
3994 test_read_double_or_die (file, 0, test, items, __LINE__) ;
3995 for (k = 0 ; k < items ; k++)
3996 if (FLOAT_ERROR (orig [k], test [k]))
3997 { printf ("\n\nLine %d: Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
3998 oct_save_double (orig, test, items) ;
3999 exit (1) ;
4000 } ;
4001
4002 /* Test multiple short reads. */
4003 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
4004
4005 total = 0 ;
4006 for (k = 1 ; k <= 32 ; k++)
4007 { int ik ;
4008
4009 test_read_double_or_die (file, 0, test + total, k, __LINE__) ;
4010 total += k ;
4011
4012 for (ik = 0 ; ik < total ; ik++)
4013 if (FLOAT_ERROR (orig [ik], test [ik]))
4014 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, ik, orig [ik], test [ik]) ;
4015 exit (1) ;
4016 } ;
4017 } ;
4018
4019 /* Seek to start of file. */
4020 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
4021
4022 test_read_double_or_die (file, 0, test, 4, __LINE__) ;
4023 for (k = 0 ; k < 4 ; k++)
4024 if (FLOAT_ERROR (orig [k], test [k]))
4025 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4026 exit (1) ;
4027 } ;
4028
4029 /* For some codecs we can't go past here. */
4030 if ((format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_16 ||
4031 (format & SF_FORMAT_SUBMASK) == SF_FORMAT_DWVW_24)
4032 { sf_close (file) ;
4033 unlink (filename) ;
4034 printf ("no seek : ") ;
4035 return ;
4036 } ;
4037
4038 /* Seek to offset from start of file. */
4039 test_seek_or_die (file, items + 10, SEEK_SET, items + 10, sfinfo.channels, __LINE__) ;
4040
4041 test_read_double_or_die (file, 0, test + 10, 4, __LINE__) ;
4042 for (k = 10 ; k < 14 ; k++)
4043 if (FLOAT_ERROR (orig [k], test [k]))
4044 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
4045 exit (1) ;
4046 } ;
4047
4048 /* Seek to offset from current position. */
4049 test_seek_or_die (file, 6, SEEK_CUR, items + 20, sfinfo.channels, __LINE__) ;
4050
4051 test_read_double_or_die (file, 0, test + 20, 4, __LINE__) ;
4052 for (k = 20 ; k < 24 ; k++)
4053 if (FLOAT_ERROR (orig [k], test [k]))
4054 { printf ("\n\nLine %d : Mono : Incorrect sample A (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
4055 exit (1) ;
4056 } ;
4057
4058 /* Seek to offset from end of file. */
4059 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
4060
4061 test_read_double_or_die (file, 0, test + 10, 4, __LINE__) ;
4062 for (k = 10 ; k < 14 ; k++)
4063 if (FLOAT_ERROR (orig [k], test [k]))
4064 { printf ("\n\nLine %d : Mono : Incorrect sample D (#%d : %g => %g).\n", __LINE__, k, test [k], orig [k]) ;
4065 exit (1) ;
4066 } ;
4067
4068 /* Check read past end of file followed by sf_seek (sndfile, 0, SEEK_CUR). */
4069 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
4070
4071 count = 0 ;
4072 while (count < sfinfo.frames)
4073 count += sf_read_double (file, test, 311) ;
4074
4075 /* Check that no error has occurred. */
4076 if (sf_error (file))
4077 { printf ("\n\nLine %d : Mono : error where there shouldn't have been one.\n", __LINE__) ;
4078 puts (sf_strerror (file)) ;
4079 exit (1) ;
4080 } ;
4081
4082 /* Check that we haven't read beyond EOF. */
4083 if (count > sfinfo.frames)
4084 { printf ("\n\nLines %d : read past end of file (%" PRId64 " should be %" PRId64 ")\n", __LINE__, count, sfinfo.frames) ;
4085 exit (1) ;
4086 } ;
4087
4088 test_seek_or_die (file, 0, SEEK_CUR, sfinfo.frames, sfinfo.channels, __LINE__) ;
4089
4090 sf_close (file) ;
4091
4092 multi_seek_test (filename, format) ;
4093 write_seek_extend_test (filename, format) ;
4094
4095 } /* mono_double_test */
4096
4097 static void
stereo_double_test(const char * filename,int format,int long_file_ok,int allow_fd)4098 stereo_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
4099 { SNDFILE *file ;
4100 SF_INFO sfinfo ;
4101 double *orig, *test ;
4102 int k, items, frames ;
4103
4104 sfinfo.samplerate = 44100 ;
4105 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
4106 sfinfo.channels = 2 ;
4107 sfinfo.format = format ;
4108
4109 gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
4110
4111 orig = orig_data.d ;
4112 test = test_data.d ;
4113
4114 /* Make this a macro so gdb steps over it in one go. */
4115 CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
4116
4117 items = DATA_LENGTH ;
4118 frames = items / sfinfo.channels ;
4119
4120 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
4121
4122 sf_set_string (file, SF_STR_ARTIST, "Your name here") ;
4123
4124 test_writef_double_or_die (file, 0, orig, frames, __LINE__) ;
4125
4126 sf_set_string (file, SF_STR_COPYRIGHT, "Copyright (c) 2003") ;
4127
4128 sf_close (file) ;
4129
4130 memset (test, 0, items * sizeof (double)) ;
4131
4132 if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
4133 memset (&sfinfo, 0, sizeof (sfinfo)) ;
4134
4135 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
4136
4137 if (sfinfo.format != format)
4138 { printf ("\n\nLine %d : Stereo : Returned format incorrect (0x%08X => 0x%08X).\n",
4139 __LINE__, format, sfinfo.format) ;
4140 exit (1) ;
4141 } ;
4142
4143 if (sfinfo.frames < frames)
4144 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n",
4145 __LINE__, sfinfo.frames, frames) ;
4146 exit (1) ;
4147 } ;
4148
4149 if (! long_file_ok && sfinfo.frames > frames)
4150 { printf ("\n\nLine %d : Stereo : Incorrect number of frames in file (too long). (%" PRId64 " should be %d)\n",
4151 __LINE__, sfinfo.frames, frames) ;
4152 exit (1) ;
4153 } ;
4154
4155 if (sfinfo.channels != 2)
4156 { printf ("\n\nLine %d : Stereo : Incorrect number of channels in file.\n", __LINE__) ;
4157 exit (1) ;
4158 } ;
4159
4160 check_log_buffer_or_die (file, __LINE__) ;
4161
4162 test_readf_double_or_die (file, 0, test, frames, __LINE__) ;
4163 for (k = 0 ; k < items ; k++)
4164 if (FLOAT_ERROR (test [k], orig [k]))
4165 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4166 exit (1) ;
4167 } ;
4168
4169 /* Seek to start of file. */
4170 test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ;
4171
4172 test_readf_double_or_die (file, 0, test, 2, __LINE__) ;
4173 for (k = 0 ; k < 4 ; k++)
4174 if (FLOAT_ERROR (test [k], orig [k]))
4175 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4176 exit (1) ;
4177 } ;
4178
4179 /* Seek to offset from start of file. */
4180 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
4181
4182 /* Check for errors here. */
4183 if (sf_error (file))
4184 { printf ("Line %d: Should NOT return an error.\n", __LINE__) ;
4185 puts (sf_strerror (file)) ;
4186 exit (1) ;
4187 } ;
4188
4189 if (sf_read_double (file, test, 1) > 0)
4190 { printf ("Line %d: Should return 0.\n", __LINE__) ;
4191 exit (1) ;
4192 } ;
4193
4194 if (! sf_error (file))
4195 { printf ("Line %d: Should return an error.\n", __LINE__) ;
4196 exit (1) ;
4197 } ;
4198 /*-----------------------*/
4199
4200 test_readf_double_or_die (file, 0, test + 10, 2, __LINE__) ;
4201 for (k = 20 ; k < 24 ; k++)
4202 if (FLOAT_ERROR (test [k], orig [k]))
4203 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4204 exit (1) ;
4205 } ;
4206
4207 /* Seek to offset from current position. */
4208 test_seek_or_die (file, 8, SEEK_CUR, 20, sfinfo.channels, __LINE__) ;
4209
4210 test_readf_double_or_die (file, 0, test + 20, 2, __LINE__) ;
4211 for (k = 40 ; k < 44 ; k++)
4212 if (FLOAT_ERROR (test [k], orig [k]))
4213 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4214 exit (1) ;
4215 } ;
4216
4217 /* Seek to offset from end of file. */
4218 test_seek_or_die (file, -1 * (sfinfo.frames - 10), SEEK_END, 10, sfinfo.channels, __LINE__) ;
4219
4220 test_readf_double_or_die (file, 0, test + 20, 2, __LINE__) ;
4221 for (k = 20 ; k < 24 ; k++)
4222 if (FLOAT_ERROR (test [k], orig [k]))
4223 { printf ("\n\nLine %d : Stereo : Incorrect sample (#%d : %g => %g).\n", __LINE__, k, orig [k], test [k]) ;
4224 exit (1) ;
4225 } ;
4226
4227 sf_close (file) ;
4228 } /* stereo_double_test */
4229
4230 static void
mono_rdwr_double_test(const char * filename,int format,int long_file_ok,int allow_fd)4231 mono_rdwr_double_test (const char *filename, int format, int long_file_ok, int allow_fd)
4232 { SNDFILE *file ;
4233 SF_INFO sfinfo ;
4234 double *orig, *test ;
4235 int k, pass ;
4236
4237 switch (format & SF_FORMAT_SUBMASK)
4238 { case SF_FORMAT_ALAC_16 :
4239 case SF_FORMAT_ALAC_20 :
4240 case SF_FORMAT_ALAC_24 :
4241 case SF_FORMAT_ALAC_32 :
4242 allow_fd = 0 ;
4243 break ;
4244
4245 default :
4246 break ;
4247 } ;
4248
4249 orig = orig_data.d ;
4250 test = test_data.d ;
4251
4252 sfinfo.samplerate = SAMPLE_RATE ;
4253 sfinfo.frames = DATA_LENGTH ;
4254 sfinfo.channels = 1 ;
4255 sfinfo.format = format ;
4256
4257 if ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW
4258 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AU
4259 || (format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
4260 unlink (filename) ;
4261 else
4262 { /* Create a short file. */
4263 create_short_file (filename) ;
4264
4265 /* Opening a already existing short file (ie invalid header) RDWR is disallowed.
4266 ** If this returns a valif pointer sf_open() screwed up.
4267 */
4268 if ((file = sf_open (filename, SFM_RDWR, &sfinfo)))
4269 { printf ("\n\nLine %d: sf_open should (SFM_RDWR) have failed but didn't.\n", __LINE__) ;
4270 exit (1) ;
4271 } ;
4272
4273 /* Truncate the file to zero bytes. */
4274 if (truncate_file_to_zero (filename) < 0)
4275 { printf ("\n\nLine %d: truncate_file_to_zero (%s) failed", __LINE__, filename) ;
4276 perror (NULL) ;
4277 exit (1) ;
4278 } ;
4279 } ;
4280
4281 /* Opening a zero length file RDWR is allowed, but the SF_INFO struct must contain
4282 ** all the usual data required when opening the file in WRITE mode.
4283 */
4284 sfinfo.samplerate = SAMPLE_RATE ;
4285 sfinfo.frames = DATA_LENGTH ;
4286 sfinfo.channels = 1 ;
4287 sfinfo.format = format ;
4288
4289 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
4290
4291 /* Do 3 writes followed by reads. After each, check the data and the current
4292 ** read and write offsets.
4293 */
4294 for (pass = 1 ; pass <= 3 ; pass ++)
4295 { orig [20] = pass * 2 ;
4296
4297 /* Write some data. */
4298 test_write_double_or_die (file, pass, orig, DATA_LENGTH, __LINE__) ;
4299
4300 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, pass * DATA_LENGTH) ;
4301
4302 /* Read what we just wrote. */
4303 test_read_double_or_die (file, 0, test, DATA_LENGTH, __LINE__) ;
4304
4305 /* Check the data. */
4306 for (k = 0 ; k < DATA_LENGTH ; k++)
4307 if (FLOAT_ERROR (orig [k], test [k]))
4308 { printf ("\n\nLine %d (pass %d) A : Error at sample %d (%g => %g).\n", __LINE__, pass, k, orig [k], test [k]) ;
4309 oct_save_double (orig, test, DATA_LENGTH) ;
4310 exit (1) ;
4311 } ;
4312
4313 test_read_write_position_or_die (file, __LINE__, pass, pass * DATA_LENGTH, pass * DATA_LENGTH) ;
4314 } ; /* for (pass ...) */
4315
4316 sf_close (file) ;
4317
4318 /* Open the file again to check the data. */
4319 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
4320
4321 if (sfinfo.format != format)
4322 { printf ("\n\nLine %d : Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, format, sfinfo.format) ;
4323 exit (1) ;
4324 } ;
4325
4326 if (sfinfo.frames < 3 * DATA_LENGTH)
4327 { printf ("\n\nLine %d : Not enough frames in file. (%" PRId64 " < %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
4328 exit (1) ;
4329 }
4330
4331 if (! long_file_ok && sfinfo.frames != 3 * DATA_LENGTH)
4332 { printf ("\n\nLine %d : Incorrect number of frames in file. (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, 3 * DATA_LENGTH) ;
4333 exit (1) ;
4334 } ;
4335
4336 if (sfinfo.channels != 1)
4337 { printf ("\n\nLine %d : Incorrect number of channels in file.\n", __LINE__) ;
4338 exit (1) ;
4339 } ;
4340
4341 if (! long_file_ok)
4342 test_read_write_position_or_die (file, __LINE__, 0, 0, 3 * DATA_LENGTH) ;
4343 else
4344 test_seek_or_die (file, 3 * DATA_LENGTH, SFM_WRITE | SEEK_SET, 3 * DATA_LENGTH, sfinfo.channels, __LINE__) ;
4345
4346 for (pass = 1 ; pass <= 3 ; pass ++)
4347 { orig [20] = pass * 2 ;
4348
4349 test_read_write_position_or_die (file, __LINE__, pass, (pass - 1) * DATA_LENGTH, 3 * DATA_LENGTH) ;
4350
4351 /* Read what we just wrote. */
4352 test_read_double_or_die (file, pass, test, DATA_LENGTH, __LINE__) ;
4353
4354 /* Check the data. */
4355 for (k = 0 ; k < DATA_LENGTH ; k++)
4356 if (FLOAT_ERROR (orig [k], test [k]))
4357 { printf ("\n\nLine %d (pass %d) B : Error at sample %d (%g => %g).\n", __LINE__, pass, k, orig [k], test [k]) ;
4358 oct_save_double (orig, test, DATA_LENGTH) ;
4359 exit (1) ;
4360 } ;
4361
4362 } ; /* for (pass ...) */
4363
4364 sf_close (file) ;
4365 } /* mono_rdwr_double_test */
4366
4367 static void
new_rdwr_double_test(const char * filename,int format,int allow_fd)4368 new_rdwr_double_test (const char *filename, int format, int allow_fd)
4369 { SNDFILE *wfile, *rwfile ;
4370 SF_INFO sfinfo ;
4371 double *orig, *test ;
4372 int items, frames ;
4373
4374 orig = orig_data.d ;
4375 test = test_data.d ;
4376
4377 sfinfo.samplerate = 44100 ;
4378 sfinfo.frames = SILLY_WRITE_COUNT ; /* Wrong length. Library should correct this on sf_close. */
4379 sfinfo.channels = 2 ;
4380 sfinfo.format = format ;
4381
4382 items = DATA_LENGTH ;
4383 frames = items / sfinfo.channels ;
4384
4385 wfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
4386 sf_command (wfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
4387 test_writef_double_or_die (wfile, 1, orig, frames, __LINE__) ;
4388 sf_write_sync (wfile) ;
4389 test_writef_double_or_die (wfile, 2, orig, frames, __LINE__) ;
4390 sf_write_sync (wfile) ;
4391
4392 rwfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, allow_fd, __LINE__) ;
4393 if (sfinfo.frames != 2 * frames)
4394 { printf ("\n\nLine %d : incorrect number of frames in file (%" PRId64 " should be %d)\n\n", __LINE__, sfinfo.frames, 2 * frames) ;
4395 exit (1) ;
4396 } ;
4397
4398 test_writef_double_or_die (wfile, 3, orig, frames, __LINE__) ;
4399
4400 test_readf_double_or_die (rwfile, 1, test, frames, __LINE__) ;
4401 test_readf_double_or_die (rwfile, 2, test, frames, __LINE__) ;
4402
4403 sf_close (wfile) ;
4404 sf_close (rwfile) ;
4405 } /* new_rdwr_double_test */
4406
4407
4408
4409 /*----------------------------------------------------------------------------------------
4410 */
4411
4412 static void
empty_file_test(const char * filename,int format)4413 empty_file_test (const char *filename, int format)
4414 { SNDFILE *file ;
4415 SF_INFO info ;
4416 int allow_fd ;
4417
4418 /* Sd2 files cannot be opened from an existing file descriptor. */
4419 allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
4420
4421 print_test_name ("empty_file_test", filename) ;
4422
4423 unlink (filename) ;
4424
4425 info.samplerate = 48000 ;
4426 info.channels = 2 ;
4427 info.format = format ;
4428 info.frames = 0 ;
4429
4430 if (sf_format_check (&info) == SF_FALSE)
4431 { info.channels = 1 ;
4432 if (sf_format_check (&info) == SF_FALSE)
4433 { puts ("invalid file format") ;
4434 return ;
4435 } ;
4436 } ;
4437
4438 /* Create an empty file. */
4439 file = test_open_file_or_die (filename, SFM_WRITE, &info, allow_fd, __LINE__) ;
4440 sf_close (file) ;
4441
4442 /* Open for read and check the length. */
4443 file = test_open_file_or_die (filename, SFM_READ, &info, allow_fd, __LINE__) ;
4444
4445 if (info.frames != 0)
4446 { printf ("\n\nError : frame count (%" PRId64 ") should be zero.\n", info.frames) ;
4447 exit (1) ;
4448 } ;
4449
4450 sf_close (file) ;
4451
4452 /* Open for read/write and check the length. */
4453 file = test_open_file_or_die (filename, SFM_RDWR, &info, allow_fd, __LINE__) ;
4454
4455 if (info.frames != 0)
4456 { printf ("\n\nError : frame count (%" PRId64 ") should be zero.\n", info.frames) ;
4457 exit (1) ;
4458 } ;
4459
4460 sf_close (file) ;
4461
4462 /* Open for read and check the length. */
4463 file = test_open_file_or_die (filename, SFM_READ, &info, allow_fd, __LINE__) ;
4464
4465 if (info.frames != 0)
4466 { printf ("\n\nError : frame count (%" PRId64 ") should be zero.\n", info.frames) ;
4467 exit (1) ;
4468 } ;
4469
4470 sf_close (file) ;
4471
4472 check_open_file_count_or_die (__LINE__) ;
4473
4474 unlink (filename) ;
4475 puts ("ok") ;
4476
4477 return ;
4478 } /* empty_file_test */
4479
4480
4481 /*----------------------------------------------------------------------------------------
4482 */
4483
4484 static void
create_short_file(const char * filename)4485 create_short_file (const char *filename)
4486 { FILE *file ;
4487
4488 if (! (file = fopen (filename, "w")))
4489 { printf ("create_short_file : fopen (%s, \"w\") failed.", filename) ;
4490 fflush (stdout) ;
4491 perror (NULL) ;
4492 exit (1) ;
4493 } ;
4494
4495 fprintf (file, "This is the file data.\n") ;
4496
4497 fclose (file) ;
4498 } /* create_short_file */
4499
4500
4501 static void
multi_seek_test(const char * filename,int format)4502 multi_seek_test (const char * filename, int format)
4503 { SNDFILE * file ;
4504 SF_INFO info ;
4505 sf_count_t pos ;
4506 int k ;
4507
4508 /* This test doesn't work on the following. */
4509 switch (format & SF_FORMAT_TYPEMASK)
4510 { case SF_FORMAT_RAW :
4511 return ;
4512
4513 default :
4514 break ;
4515 } ;
4516
4517 memset (&info, 0, sizeof (info)) ;
4518
4519 generate_file (filename, format, 88200) ;
4520
4521 file = test_open_file_or_die (filename, SFM_READ, &info, SF_FALSE, __LINE__) ;
4522
4523 for (k = 0 ; k < 10 ; k++)
4524 { pos = info.frames / (k + 2) ;
4525 test_seek_or_die (file, pos, SEEK_SET, pos, info.channels, __LINE__) ;
4526 } ;
4527
4528 sf_close (file) ;
4529 } /* multi_seek_test */
4530
4531 static void
write_seek_extend_test(const char * filename,int format)4532 write_seek_extend_test (const char * filename, int format)
4533 { SNDFILE * file ;
4534 SF_INFO info ;
4535 short *orig, *test ;
4536 unsigned items, k ;
4537
4538 /* This test doesn't work on the following container formats. */
4539 switch (format & SF_FORMAT_TYPEMASK)
4540 { case SF_FORMAT_FLAC :
4541 case SF_FORMAT_HTK :
4542 case SF_FORMAT_PAF :
4543 case SF_FORMAT_SDS :
4544 case SF_FORMAT_SVX :
4545 return ;
4546
4547 default :
4548 break ;
4549 } ;
4550
4551 /* This test doesn't work on the following codec formats. */
4552 switch (format & SF_FORMAT_SUBMASK)
4553 { case SF_FORMAT_ALAC_16 :
4554 case SF_FORMAT_ALAC_20 :
4555 case SF_FORMAT_ALAC_24 :
4556 case SF_FORMAT_ALAC_32 :
4557 return ;
4558
4559 default :
4560 break ;
4561 } ;
4562
4563 memset (&info, 0, sizeof (info)) ;
4564
4565 info.samplerate = 48000 ;
4566 info.channels = 1 ;
4567 info.format = format ;
4568
4569 items = 512 ;
4570 exit_if_true (items > ARRAY_LEN (orig_data.s), "Line %d : Bad assumption.\n", __LINE__) ;
4571
4572 orig = orig_data.s ;
4573 test = test_data.s ;
4574
4575 for (k = 0 ; k < ARRAY_LEN (orig_data.s) ; k++)
4576 orig [k] = 0x3fff ;
4577
4578 file = test_open_file_or_die (filename, SFM_WRITE, &info, SF_FALSE, __LINE__) ;
4579 test_write_short_or_die (file, 0, orig, items, __LINE__) ;
4580
4581 /* Extend the file using a seek. */
4582 test_seek_or_die (file, 2 * items, SEEK_SET, 2 * items, info.channels, __LINE__) ;
4583
4584 test_writef_short_or_die (file, 0, orig, items, __LINE__) ;
4585 sf_close (file) ;
4586
4587 file = test_open_file_or_die (filename, SFM_READ, &info, SF_FALSE, __LINE__) ;
4588 test_read_short_or_die (file, 0, test, 3 * items, __LINE__) ;
4589 sf_close (file) ;
4590
4591 if (info.frames < 3 * items)
4592 { printf ("\n\nLine %d : Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, info.frames, 3 * items) ;
4593 exit (1) ;
4594 } ;
4595
4596 /* Can't do these formats due to scaling. */
4597 switch (format & SF_FORMAT_SUBMASK)
4598 { case SF_FORMAT_PCM_S8 :
4599 case SF_FORMAT_PCM_U8 :
4600 return ;
4601 default :
4602 break ;
4603 } ;
4604
4605 for (k = 0 ; k < items ; k++)
4606 { exit_if_true (test [k] != 0x3fff, "Line %d : test [%d] == %d, should be 0x3fff.\n", __LINE__, k, test [k]) ;
4607 exit_if_true (test [items + k] != 0, "Line %d : test [%d] == %d, should be 0.\n", __LINE__, items + k, test [items + k]) ;
4608 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]) ;
4609 } ;
4610
4611 return ;
4612 } /* write_seek_extend_test */
4613
4614
4615