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