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