comparison src/libsndfile-1.0.27/tests/write_read_test.c @ 40:1df64224f5ac

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