1 /*
2 ** Copyright (C) 1999-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ** GNU General Public License for more details.
13 **
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 
19 #include "sfconfig.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include <inttypes.h>
26 
27 
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #else
31 #include "sf_unistd.h"
32 #endif
33 
34 #include <sndfile.h>
35 
36 #include "utils.h"
37 
38 #define	BUFFER_SIZE		(1 << 14)
39 #define	SAMPLE_RATE		11025
40 
41 #ifndef		M_PI
42 #define		M_PI		3.14159265358979323846264338
43 #endif
44 
45 #define		LCT_MAX(x, y)	((x) > (y) ? (x) : (y))
46 
47 static	void	lcomp_test_short	(const char *filename, int filetype, int chan, double margin) ;
48 static	void	lcomp_test_int		(const char *filename, int filetype, int chan, double margin) ;
49 static	void	lcomp_test_float	(const char *filename, int filetype, int chan, double margin) ;
50 static	void	lcomp_test_double	(const char *filename, int filetype, int chan, double margin) ;
51 
52 static	void	sdlcomp_test_short	(const char *filename, int filetype, int chan, double margin) ;
53 static	void	sdlcomp_test_int	(const char *filename, int filetype, int chan, double margin) ;
54 static	void	sdlcomp_test_float	(const char *filename, int filetype, int chan, double margin) ;
55 static	void	sdlcomp_test_double	(const char *filename, int filetype, int chan, double margin) ;
56 
57 static void		read_raw_test (const char *filename, int filetype, int chan) ;
58 
59 static	int		error_function (double data, double orig, double margin) ;
60 static	int		decay_response (int k) ;
61 
62 static	void	gen_signal_double (double *data, double scale, int channels, int datalen) ;
63 
64 static	void	smoothed_diff_short (short *data, unsigned int datalen) ;
65 static	void	smoothed_diff_int (int *data, unsigned int datalen) ;
66 static	void	smoothed_diff_float (float *data, unsigned int datalen) ;
67 static	void	smoothed_diff_double (double *data, unsigned int datalen) ;
68 
69 static void		check_comment (SNDFILE * file, int format, int lineno) ;
70 
71 static int		is_lossy (int filetype) ;
72 
73 static int		check_opus_version (SNDFILE *file) ;
74 
75 /*
76 ** Force the start of these buffers to be double aligned. Sparc-solaris will
77 ** choke if they are not.
78 */
79 typedef union
80 {	double	d [BUFFER_SIZE + 1] ;
81 	float	f [BUFFER_SIZE + 1] ;
82 	int		i [BUFFER_SIZE + 1] ;
83 	short	s [BUFFER_SIZE + 1] ;
84 	char	c [BUFFER_SIZE + 1] ;
85 } BUFFER ;
86 
87 static	BUFFER	data_buffer ;
88 static	BUFFER	orig_buffer ;
89 static	BUFFER	smooth_buffer ;
90 
91 static const char *long_comment =
92 	"This is really quite a long comment. It is designed to be long enough "
93 	"to screw up the encoders and decoders if the file container format does "
94 	"not handle things correctly. If everything is working correctly, the "
95 	"decoder will only decode the actual audio data, and not this string at "
96 	"the end of the file." ;
97 
98 int
main(int argc,char * argv[])99 main (int argc, char *argv [])
100 {	int		do_all = 0 ;
101 	int		test_count = 0 ;
102 
103 	if (argc != 2)
104 	{	printf ("Usage : %s <test>\n", argv [0]) ;
105 		printf ("    Where <test> is one of the following:\n") ;
106 		printf ("           wav_ima     - test IMA ADPCM WAV file functions\n") ;
107 		printf ("           wav_msadpcm - test MS ADPCM WAV file functions\n") ;
108 		printf ("           wav_gsm610  - test GSM 6.10 WAV file functions\n") ;
109 		printf ("           wav_ulaw    - test u-law WAV file functions\n") ;
110 		printf ("           wav_alaw    - test A-law WAV file functions\n") ;
111 		printf ("           wve         - test Psion WVE file functions\n") ;
112 		printf ("           all         - perform all tests\n") ;
113 		exit (1) ;
114 		} ;
115 
116 	do_all = ! strcmp (argv [1], "all") ;
117 
118 	if (do_all || strcmp (argv [1], "wav_pcm") == 0)
119 	{	/* This is just a sanity test for PCM encoding. */
120 		lcomp_test_short	("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ;
121 		lcomp_test_int		("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ;
122 		lcomp_test_short	("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ;
123 		lcomp_test_int		("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ;
124 		/* Lite remove start */
125 		lcomp_test_float	("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT, 2, 1e-50) ;
126 		lcomp_test_double	("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_DOUBLE, 2, 1e-50) ;
127 		/* Lite remove end */
128 
129 		read_raw_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 2) ;
130 		test_count++ ;
131 		} ;
132 
133 	/* For all the rest, if the file format supports more than 1 channel, use stereo. */
134 	/* Lite remove start */
135 	if (do_all || strcmp (argv [1], "wav_ima") == 0)
136 	{	lcomp_test_short	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
137 		lcomp_test_int		("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.65) ;
138 		lcomp_test_float	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
139 		lcomp_test_double	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
140 
141 		lcomp_test_short	("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
142 		lcomp_test_int		("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
143 		lcomp_test_float	("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
144 		lcomp_test_double	("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
145 
146 		sdlcomp_test_short	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
147 		sdlcomp_test_int	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
148 		sdlcomp_test_float	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
149 		sdlcomp_test_double	("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
150 		test_count++ ;
151 		} ;
152 
153 	if (do_all || strcmp (argv [1], "wav_msadpcm") == 0)
154 	{	lcomp_test_short	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
155 		lcomp_test_int		("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
156 		lcomp_test_float	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
157 		lcomp_test_double	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
158 
159 		lcomp_test_short	("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
160 		lcomp_test_int		("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
161 		lcomp_test_float	("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
162 		lcomp_test_double	("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
163 
164 		sdlcomp_test_short	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
165 		sdlcomp_test_int	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
166 		sdlcomp_test_float	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
167 		sdlcomp_test_double	("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
168 
169 		test_count++ ;
170 		} ;
171 
172 	if (do_all || strcmp (argv [1], "wav_g721") == 0)
173 	{	printf ("**** Fix this later : error bound should be 0.06 ****\n") ;
174 		lcomp_test_short	("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
175 		lcomp_test_int		("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
176 
177 		lcomp_test_short	("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
178 		lcomp_test_int		("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
179 
180 		test_count++ ;
181 		} ;
182 	/* Lite remove end */
183 
184 	if (do_all || strcmp (argv [1], "wav_ulaw") == 0)
185 	{	lcomp_test_short	("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
186 		lcomp_test_int		("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
187 
188 		lcomp_test_short	("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
189 		lcomp_test_int		("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
190 
191 		/* Lite remove start */
192 		lcomp_test_float	("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
193 		lcomp_test_double	("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
194 		/* Lite remove end */
195 
196 		read_raw_test ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2) ;
197 		test_count++ ;
198 		} ;
199 
200 	if (do_all || strcmp (argv [1], "wav_alaw") == 0)
201 	{	lcomp_test_short	("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
202 		lcomp_test_int		("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
203 		/* Lite remove start */
204 		lcomp_test_float	("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
205 		lcomp_test_double	("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
206 		/* Lite remove end */
207 
208 		read_raw_test ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2) ;
209 		test_count++ ;
210 		} ;
211 
212 	if (do_all || strcmp (argv [1], "wav_gsm610") == 0)
213 	{	/* Don't do lcomp_test_XXX as the errors are too big. */
214 		sdlcomp_test_short	("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
215 		sdlcomp_test_int	("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
216 
217 		sdlcomp_test_short	("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
218 		sdlcomp_test_int	("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
219 
220 		/* Lite remove start */
221 		sdlcomp_test_float	("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
222 		sdlcomp_test_double	("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
223 		/* Lite remove end */
224 		test_count++ ;
225 		} ;
226 
227 	/* Lite remove start */
228 	if (do_all || strcmp (argv [1], "wav_nmsadpcm") == 0)
229 	{	lcomp_test_short	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.37) ;
230 		lcomp_test_int		("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.31) ;
231 		lcomp_test_float	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ;
232 		lcomp_test_double	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ;
233 
234 		lcomp_test_short	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.15) ;
235 		lcomp_test_int		("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.10) ;
236 		lcomp_test_float	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ;
237 		lcomp_test_double	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ;
238 
239 		lcomp_test_short	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.036) ;
240 		lcomp_test_int		("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.045) ;
241 		lcomp_test_float	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ;
242 		lcomp_test_double	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ;
243 
244 		sdlcomp_test_short	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
245 		sdlcomp_test_int	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
246 		sdlcomp_test_float	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
247 		sdlcomp_test_double	("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
248 
249 		sdlcomp_test_short	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
250 		sdlcomp_test_int	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
251 		sdlcomp_test_float	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
252 		sdlcomp_test_double	("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
253 
254 		sdlcomp_test_short	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.017) ;
255 		sdlcomp_test_int	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
256 		sdlcomp_test_float	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
257 		sdlcomp_test_double	("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
258 
259 		test_count++ ;
260 		} ;
261 	/* Lite remove end */
262 
263 	if (do_all || strcmp (argv [1], "aiff_ulaw") == 0)
264 	{	lcomp_test_short	("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
265 		lcomp_test_int		("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
266 		/* Lite remove start */
267 		lcomp_test_float	("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
268 		lcomp_test_double	("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
269 		/* Lite remove end */
270 
271 		read_raw_test ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2) ;
272 		test_count++ ;
273 		} ;
274 
275 	if (do_all || strcmp (argv [1], "aiff_alaw") == 0)
276 	{	lcomp_test_short	("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
277 		lcomp_test_int		("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
278 		/* Lite remove start */
279 		lcomp_test_float	("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
280 		lcomp_test_double	("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
281 		/* Lite remove end */
282 
283 		read_raw_test ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2) ;
284 		test_count++ ;
285 		} ;
286 
287 	if (do_all || strcmp (argv [1], "aiff_gsm610") == 0)
288 	{	/* Don't do lcomp_test_XXX as the errors are too big. */
289 		sdlcomp_test_short	("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
290 		sdlcomp_test_int	("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
291 		/* Lite remove start */
292 		sdlcomp_test_float	("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
293 		sdlcomp_test_double	("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
294 		/* Lite remove end */
295 		test_count++ ;
296 		} ;
297 
298 	if (strcmp (argv [1], "aiff_ima") == 0)
299 	{	lcomp_test_short	("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
300 		lcomp_test_int		("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
301 		/* Lite remove start */
302 		lcomp_test_float	("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
303 		lcomp_test_double	("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
304 		/* Lite remove end */
305 		} ;
306 
307 	if (do_all || strcmp (argv [1], "au_ulaw") == 0)
308 	{	lcomp_test_short	("ulaw.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
309 		lcomp_test_int		("ulaw.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
310 		/* Lite remove start */
311 		lcomp_test_float	("ulaw.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
312 		lcomp_test_double	("ulaw.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
313 		/* Lite remove end */
314 		test_count++ ;
315 		} ;
316 
317 	if (do_all || strcmp (argv [1], "au_alaw") == 0)
318 	{	lcomp_test_short	("alaw.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
319 		lcomp_test_int		("alaw.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
320 		/* Lite remove start */
321 		lcomp_test_float	("alaw.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
322 		lcomp_test_double	("alaw.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
323 		/* Lite remove end */
324 		test_count++ ;
325 		} ;
326 
327 	/* Lite remove start */
328 	if (do_all || strcmp (argv [1], "au_g721") == 0)
329 	{	printf ("**** Fix this later : error bound should be 0.06 ****\n") ;
330 		lcomp_test_short	("g721.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
331 		lcomp_test_int		("g721.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
332 		lcomp_test_float	("g721.au", SF_ENDIAN_LITTLE 	| SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
333 		lcomp_test_double	("g721.au", SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
334 
335 /*-		sdlcomp_test_short	("g721.au", SF_ENDIAN_BIG    | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
336 		sdlcomp_test_int	("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
337 		sdlcomp_test_float  ("g721.au", SF_ENDIAN_BIG    | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
338 		sdlcomp_test_double	("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.12) ;
339 -*/
340 		test_count++ ;
341 		} ;
342 
343 	if (do_all || strcmp (argv [1], "au_g723") == 0)
344 	{	printf ("**** Fix this later : error bound should be 0.16 ****\n") ;
345 		lcomp_test_short	("g723_24.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
346 		lcomp_test_int		("g723_24.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
347 		lcomp_test_float	("g723_24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
348 		lcomp_test_double	("g723_24.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
349 
350 		lcomp_test_short	("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.85) ;
351 		lcomp_test_int		("g723_40.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.84) ;
352 		lcomp_test_float	("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ;
353 		lcomp_test_double	("g723_40.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ;
354 
355 /*-		sdlcomp_test_short	("g723.au", SF_ENDIAN_BIG    | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
356 		sdlcomp_test_int	("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
357 		sdlcomp_test_float	("g723.au", SF_ENDIAN_BIG    | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
358 		sdlcomp_test_double	("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
359 -*/
360 		test_count++ ;
361 		} ;
362 	/* Lite remove end */
363 
364 	if (do_all || strcmp (argv [1], "caf_ulaw") == 0)
365 	{	lcomp_test_short	("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
366 		lcomp_test_int		("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
367 		/* Lite remove start */
368 		lcomp_test_float	("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
369 		lcomp_test_double	("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
370 		/* Lite remove end */
371 
372 		read_raw_test ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2) ;
373 		test_count++ ;
374 		} ;
375 
376 	if (do_all || strcmp (argv [1], "caf_alaw") == 0)
377 	{	lcomp_test_short	("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
378 		lcomp_test_int		("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
379 		/* Lite remove start */
380 		lcomp_test_float	("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
381 		lcomp_test_double	("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
382 		/* Lite remove end */
383 
384 		read_raw_test ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2) ;
385 		test_count++ ;
386 		} ;
387 
388 
389 	if (do_all || strcmp (argv [1], "raw_ulaw") == 0)
390 	{	lcomp_test_short	("ulaw.raw", SF_ENDIAN_LITTLE	| SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
391 		lcomp_test_int		("ulaw.raw", SF_ENDIAN_BIG		| SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
392 		/* Lite remove start */
393 		lcomp_test_float	("ulaw.raw", SF_ENDIAN_LITTLE	| SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
394 		lcomp_test_double	("ulaw.raw", SF_ENDIAN_BIG		| SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
395 		/* Lite remove end */
396 		test_count++ ;
397 		} ;
398 
399 	if (do_all || strcmp (argv [1], "raw_alaw") == 0)
400 	{	lcomp_test_short	("alaw.raw", SF_ENDIAN_LITTLE	| SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
401 		lcomp_test_int		("alaw.raw", SF_ENDIAN_BIG		| SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
402 		/* Lite remove start */
403 		lcomp_test_float	("alaw.raw", SF_ENDIAN_LITTLE	| SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
404 		lcomp_test_double	("alaw.raw", SF_ENDIAN_BIG		| SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
405 		/* Lite remove end */
406 		test_count++ ;
407 		} ;
408 
409 	if (do_all || strcmp (argv [1], "raw_gsm610") == 0)
410 	{	/* Don't do lcomp_test_XXX as the errors are too big. */
411 		sdlcomp_test_short	("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
412 		sdlcomp_test_int	("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
413 		sdlcomp_test_float	("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
414 		sdlcomp_test_double	("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
415 		test_count++ ;
416 		} ;
417 
418 	/* Lite remove start */
419 	if (do_all || strcmp (argv [1], "raw_nmsadpcm") == 0)
420 	{	lcomp_test_short	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.37) ;
421 		lcomp_test_int		("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.31) ;
422 		lcomp_test_float	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ;
423 		lcomp_test_double	("raw.vce16", SF_FORMAT_RAW	| SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ;
424 
425 		lcomp_test_short	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.15) ;
426 		lcomp_test_int		("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.10) ;
427 		lcomp_test_float	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ;
428 		lcomp_test_double	("raw.vce24", SF_FORMAT_RAW	| SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ;
429 
430 		lcomp_test_short	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.036) ;
431 		lcomp_test_int		("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.045) ;
432 		lcomp_test_float	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ;
433 		lcomp_test_double	("raw.vce32", SF_FORMAT_RAW	| SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ;
434 
435 		sdlcomp_test_short	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
436 		sdlcomp_test_int	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
437 		sdlcomp_test_float	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
438 		sdlcomp_test_double	("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ;
439 
440 		sdlcomp_test_short	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
441 		sdlcomp_test_int	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
442 		sdlcomp_test_float	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
443 		sdlcomp_test_double	("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ;
444 
445 		sdlcomp_test_short	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.017) ;
446 		sdlcomp_test_int	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
447 		sdlcomp_test_float	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
448 		sdlcomp_test_double	("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ;
449 
450 		test_count++ ;
451 		} ;
452 	/* Lite remove end */
453 
454 	if (do_all || strcmp (argv [1], "ogg_vorbis") == 0)
455 	{	if (HAVE_EXTERNAL_XIPH_LIBS)
456 		{	/* Don't do lcomp_test_XXX as the errors are too big. */
457 			sdlcomp_test_short	("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
458 			sdlcomp_test_int	("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
459 			sdlcomp_test_float	("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
460 			sdlcomp_test_double	("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
461 			}
462 		else
463 			puts ("    No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
464 
465 		test_count++ ;
466 		} ;
467 
468 	if (do_all || strcmp (argv [1], "ogg_opus") == 0)
469 	{	if (HAVE_EXTERNAL_XIPH_LIBS)
470 		{	/* Don't do lcomp_test_XXX as the errors are too big. */
471 			sdlcomp_test_short	("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.57) ;
472 			sdlcomp_test_int	("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.54) ;
473 			sdlcomp_test_float	("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.55) ;
474 			sdlcomp_test_double	("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.55) ;
475 			}
476 		else
477 			puts ("    No Ogg/Opus tests because Ogg/Opus support was not compiled in.") ;
478 
479 		test_count++ ;
480 		} ;
481 
482 	/* Lite remove start */
483 	if (do_all || strcmp (argv [1], "ircam_ulaw") == 0)
484 	{	lcomp_test_short	("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
485 		lcomp_test_int		("ulaw.ircam", SF_ENDIAN_BIG	| SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
486 		lcomp_test_float	("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
487 		lcomp_test_double	("ulaw.ircam", SF_ENDIAN_BIG	| SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
488 		test_count++ ;
489 		} ;
490 
491 	if (do_all || strcmp (argv [1], "ircam_alaw") == 0)
492 	{	lcomp_test_short	("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
493 		lcomp_test_int		("alaw.ircam", SF_ENDIAN_BIG	| SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
494 		lcomp_test_float	("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
495 		lcomp_test_double	("alaw.ircam", SF_ENDIAN_BIG	| SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
496 		test_count++ ;
497 		} ;
498 
499 	if (do_all || strcmp (argv [1], "nist_ulaw") == 0)
500 	{	lcomp_test_short	("ulaw.nist", SF_ENDIAN_LITTLE	| SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
501 		lcomp_test_int		("ulaw.nist", SF_ENDIAN_BIG		| SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
502 		lcomp_test_float	("ulaw.nist", SF_ENDIAN_LITTLE	| SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
503 		lcomp_test_double	("ulaw.nist", SF_ENDIAN_BIG		| SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
504 		test_count++ ;
505 		} ;
506 
507 	if (do_all || strcmp (argv [1], "nist_alaw") == 0)
508 	{	lcomp_test_short	("alaw.nist", SF_ENDIAN_LITTLE	| SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
509 		lcomp_test_int		("alaw.nist", SF_ENDIAN_BIG		| SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
510 		lcomp_test_float	("alaw.nist", SF_ENDIAN_LITTLE	| SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
511 		lcomp_test_double	("alaw.nist", SF_ENDIAN_BIG		| SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
512 		test_count++ ;
513 		} ;
514 
515 	if (do_all || strcmp (argv [1], "voc_ulaw") == 0)
516 	{	lcomp_test_short	("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
517 		lcomp_test_int		("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
518 		lcomp_test_float	("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
519 		lcomp_test_double	("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
520 		test_count++ ;
521 		} ;
522 
523 	if (do_all || strcmp (argv [1], "voc_alaw") == 0)
524 	{	lcomp_test_short	("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
525 		lcomp_test_int		("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
526 		lcomp_test_float	("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
527 		lcomp_test_double	("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
528 		test_count++ ;
529 		} ;
530 	/* Lite remove end */
531 
532 	if (do_all || strcmp (argv [1], "w64_ulaw") == 0)
533 	{	lcomp_test_short	("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
534 		lcomp_test_int		("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
535 		/* Lite remove start */
536 		lcomp_test_float	("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
537 		lcomp_test_double	("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
538 		/* Lite remove end */
539 
540 		read_raw_test ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2) ;
541 		test_count++ ;
542 		} ;
543 
544 	if (do_all || strcmp (argv [1], "w64_alaw") == 0)
545 	{	lcomp_test_short	("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
546 		lcomp_test_int		("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
547 		/* Lite remove start */
548 		lcomp_test_float	("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
549 		lcomp_test_double	("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
550 		/* Lite remove end */
551 
552 		read_raw_test ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2) ;
553 		test_count++ ;
554 		} ;
555 
556 	/* Lite remove start */
557 	if (do_all || strcmp (argv [1], "w64_ima") == 0)
558 	{	lcomp_test_short	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
559 		lcomp_test_int		("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
560 		lcomp_test_float	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
561 		lcomp_test_double	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
562 
563 		sdlcomp_test_short	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
564 		sdlcomp_test_int	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
565 		sdlcomp_test_float	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
566 		sdlcomp_test_double	("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
567 		test_count++ ;
568 		} ;
569 
570 	if (do_all || strcmp (argv [1], "w64_msadpcm") == 0)
571 	{	lcomp_test_short	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
572 		lcomp_test_int		("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
573 		lcomp_test_float	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
574 		lcomp_test_double	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
575 
576 		sdlcomp_test_short	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
577 		sdlcomp_test_int	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
578 		sdlcomp_test_float	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
579 		sdlcomp_test_double	("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
580 		test_count++ ;
581 		} ;
582 
583 	if (do_all || strcmp (argv [1], "wve") == 0)
584 	{	lcomp_test_short	("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
585 		lcomp_test_int		("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
586 		/* Lite remove start */
587 		lcomp_test_float	("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
588 		lcomp_test_double	("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
589 		/* Lite remove end */
590 		test_count++ ;
591 		} ;
592 
593 	/* Lite remove end */
594 
595 	if (do_all || strcmp (argv [1], "w64_gsm610") == 0)
596 	{	/* Don't do lcomp_test_XXX as the errors are too big. */
597 		sdlcomp_test_short	("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
598 		sdlcomp_test_int	("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
599 		/* Lite remove start */
600 		sdlcomp_test_float	("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
601 		sdlcomp_test_double	("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
602 		/* Lite remove end */
603 		test_count++ ;
604 		} ;
605 
606 	/* Lite remove start */
607 	if (do_all || strcmp (argv [1], "vox_adpcm") == 0)
608 	{	lcomp_test_short	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
609 		lcomp_test_int		("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
610 		lcomp_test_float	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
611 		lcomp_test_double	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
612 
613 		sdlcomp_test_short	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
614 		sdlcomp_test_int	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
615 		sdlcomp_test_float	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
616 		sdlcomp_test_double	("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
617 		test_count++ ;
618 		} ;
619 
620 	if (do_all || strcmp (argv [1], "xi_dpcm") == 0)
621 	{	lcomp_test_short	("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ;
622 		lcomp_test_int		("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ;
623 
624 		lcomp_test_short	("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
625 		lcomp_test_int		("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
626 		lcomp_test_float	("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
627 		lcomp_test_double	("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
628 		test_count++ ;
629 		} ;
630 	/* Lite remove end */
631 
632 	if (test_count == 0)
633 	{	printf ("************************************\n") ;
634 		printf ("*  No '%s' test defined.\n", argv [1]) ;
635 		printf ("************************************\n") ;
636 		return 1 ;
637 		} ;
638 
639 	return 0 ;
640 } /* main */
641 
642 /*============================================================================================
643 **	Here are the test functions.
644 */
645 
646 static void
lcomp_test_short(const char * filename,int filetype,int channels,double margin)647 lcomp_test_short (const char *filename, int filetype, int channels, double margin)
648 {	SNDFILE			*file ;
649 	SF_INFO			sfinfo ;
650 	int				k, m, seekpos, half_max_abs ;
651 	sf_count_t		datalen ;
652 	short			*orig, *data ;
653 
654 	print_test_name ("lcomp_test_short", filename) ;
655 
656 	datalen = BUFFER_SIZE / channels ;
657 
658 	data = data_buffer.s ;
659 	orig = orig_buffer.s ;
660 
661 	gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
662 	for (k = 0 ; k < channels * datalen ; k++)
663 		orig [k] = (short) (orig_buffer.d [k]) ;
664 
665 	sfinfo.samplerate	= SAMPLE_RATE ;
666 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
667 	sfinfo.channels		= channels ;
668 	sfinfo.format		= filetype ;
669 
670 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
671 	test_writef_short_or_die (file, 0, orig, datalen, __LINE__) ;
672 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
673 	sf_close (file) ;
674 
675 	memset (data, 0, datalen * sizeof (short)) ;
676 
677 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
678 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
679 
680 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
681 
682 	if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
683 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
684 		exit (1) ;
685 		} ;
686 
687 	if (sfinfo.frames < datalen / channels)
688 	{	printf ("Too few frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
689 		exit (1) ;
690 		} ;
691 
692 	if (sfinfo.frames > (datalen + datalen / 20))
693 	{	printf ("Too many frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
694 		exit (1) ;
695 		} ;
696 
697 	if (sfinfo.channels != channels)
698 	{	printf ("Incorrect number of channels in file.\n") ;
699 		exit (1) ;
700 		} ;
701 
702 	check_log_buffer_or_die (file, __LINE__) ;
703 
704 	check_comment (file, filetype, __LINE__) ;
705 
706 	test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
707 
708 	half_max_abs = 0 ;
709 	for (k = 0 ; k < datalen ; k++)
710 	{	if (error_function (data [k], orig [k], margin))
711 		{	printf ("\n\nLine %d: Incorrect sample A (#%d : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ;
712 			oct_save_short (orig, data, datalen) ;
713 			exit (1) ;
714 			} ;
715 		half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
716 		} ;
717 
718 	if (half_max_abs < 1.0)
719 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
720 		exit (1) ;
721 		} ;
722 
723 	if ((k = sf_readf_short (file, data, datalen)) != sfinfo.frames - datalen)
724 	{	printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
725 			channels * sfinfo.frames - datalen, k) ;
726 		exit (1) ;
727 		} ;
728 
729 	/*	This check is only for block based encoders which must append silence
730 	**	to the end of a file so as to fill out a block.
731 	*/
732 	for (k = 0 ; k < sfinfo.frames - datalen ; k++)
733 		if (abs (data [channels * k]) > decay_response (channels * k))
734 		{	printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
735 			exit (1) ;
736 			} ;
737 
738 	if (! sfinfo.seekable)
739 	{	sf_close (file) ;
740 		unlink (filename) ;
741 		printf ("ok\n") ;
742 		return ;
743 		} ;
744 
745 	/* Now test sf_seek function. */
746 
747 	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
748 	{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
749 		exit (1) ;
750 		} ;
751 
752 	for (m = 0 ; m < 3 ; m++)
753 	{	test_readf_short_or_die (file, m, data, 11, __LINE__) ;
754 
755 		for (k = 0 ; k < channels * 11 ; k++)
756 			if (error_function (1.0 * data [k], 1.0 * orig [k + channels * m * 11], margin))
757 			{	printf ("\n\nLine %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
758 				for (m = 0 ; m < channels ; m++)
759 					printf ("%d ", data [m]) ;
760 				printf ("\n") ;
761 				exit (1) ;
762 				} ;
763 		} ;
764 
765 	seekpos = BUFFER_SIZE / 10 ;
766 
767 	/* Check seek from start of file. */
768 	if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
769 	{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
770 		exit (1) ;
771 		} ;
772 
773 	test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
774 
775 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
776 	{	printf ("\n\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
777 		exit (1) ;
778 		} ;
779 
780 	if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
781 	{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
782 		exit (1) ;
783 		} ;
784 
785 	seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
786 	k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
787 	test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
788 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
789 	{	printf ("\n\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
790 		oct_save_short (orig, data, datalen) ;
791 		exit (1) ;
792 		} ;
793 
794 	seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
795 	/* Check seek backward from current position. */
796 	k = sf_seek (file, -20, SEEK_CUR) ;
797 	test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
798 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
799 	{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
800 		exit (1) ;
801 		} ;
802 
803 	/* Check that read past end of file returns number of items. */
804 	sf_seek (file, sfinfo.frames, SEEK_SET) ;
805 
806  	if ((k = sf_readf_short (file, data, datalen)) != 0)
807  	{	printf ("\n\nLine %d: Return value from sf_readf_short past end of file incorrect (%d).\n", __LINE__, k) ;
808  		exit (1) ;
809  		} ;
810 
811 	/* Check seek backward from end. */
812 	if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
813 	{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
814 		exit (1) ;
815 		} ;
816 
817 	test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
818 	if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin))
819 	{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ;
820 		exit (1) ;
821 		} ;
822 
823 	sf_close (file) ;
824 
825 	unlink (filename) ;
826 	printf ("ok\n") ;
827 } /* lcomp_test_short */
828 
829 /*--------------------------------------------------------------------------------------------
830 */
831 
832 static void
lcomp_test_int(const char * filename,int filetype,int channels,double margin)833 lcomp_test_int (const char *filename, int filetype, int channels, double margin)
834 {	SNDFILE			*file ;
835 	SF_INFO			sfinfo ;
836 	int				k, m, half_max_abs ;
837 	sf_count_t		datalen, seekpos ;
838 	double			scale, max_val ;
839 	int				*orig, *data ;
840 
841 	print_test_name ("lcomp_test_int", filename) ;
842 
843 	datalen = BUFFER_SIZE / channels ;
844 
845 	if (is_lossy (filetype))
846 	{	scale = 1.0 * 0x10000 ;
847 		max_val = 32000.0 * scale ;
848 		}
849 	else
850 	{	scale = 1.0 ;
851 		max_val = 0x7fffffff * scale ;
852 		} ;
853 
854 	data = data_buffer.i ;
855 	orig = orig_buffer.i ;
856 
857 	gen_signal_double (orig_buffer.d, max_val, channels, datalen) ;
858 
859 	for (k = 0 ; k < channels * datalen ; k++)
860 		orig [k] = lrint (orig_buffer.d [k]) ;
861 
862 	sfinfo.samplerate	= SAMPLE_RATE ;
863 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
864 	sfinfo.channels		= channels ;
865 	sfinfo.format		= filetype ;
866 
867 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
868 	test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ;
869 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
870 	sf_close (file) ;
871 
872 	memset (data, 0, datalen * sizeof (int)) ;
873 
874 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
875 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
876 
877 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
878 
879 	if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
880 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
881 		exit (1) ;
882 		} ;
883 
884 	if (sfinfo.frames < datalen / channels)
885 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
886 		exit (1) ;
887 		} ;
888 
889 	if (sfinfo.frames > (datalen + datalen / 20))
890 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
891 		exit (1) ;
892 		} ;
893 
894 	if (sfinfo.channels != channels)
895 	{	printf ("Incorrect number of channels in file.\n") ;
896 		exit (1) ;
897 		} ;
898 
899 	check_log_buffer_or_die (file, __LINE__) ;
900 
901 	check_comment (file, filetype, __LINE__) ;
902 
903 	test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
904 
905 	half_max_abs = 0 ;
906 	for (k = 0 ; k < datalen ; k++)
907 	{	if (error_function (data [k] / scale, orig [k] / scale, margin))
908 		{	printf ("\nLine %d: Incorrect sample (#%d : %f should be %f).\n", __LINE__, k, data [k] / scale, orig [k] / scale) ;
909 			oct_save_int (orig, data, datalen) ;
910 			exit (1) ;
911 			} ;
912 		half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
913 		} ;
914 
915 	if (half_max_abs < 1.0)
916 	{	printf ("\n\nLine %d: Signal is all zeros (%d, 0x%X).\n", __LINE__, half_max_abs, half_max_abs) ;
917 		exit (1) ;
918 		} ;
919 
920 	if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
921 	{	printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
922 			channels * sfinfo.frames - datalen, k) ;
923 		exit (1) ;
924 		} ;
925 
926 	/*	This check is only for block based encoders which must append silence
927 	**	to the end of a file so as to fill out a block.
928 	*/
929 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
930 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
931 			if (ABS (data [channels * k] / scale) > decay_response (channels * k))
932 			{	printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
933 				exit (1) ;
934 				} ;
935 
936 	if (! sfinfo.seekable)
937 	{	sf_close (file) ;
938 		unlink (filename) ;
939 		printf ("ok\n") ;
940 		return ;
941 		} ;
942 
943 	/* Now test sf_seek function. */
944 
945 	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
946 	{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
947 		exit (1) ;
948 		} ;
949 
950 	for (m = 0 ; m < 3 ; m++)
951 	{	test_readf_int_or_die (file, m, data, 11, __LINE__) ;
952 
953 		for (k = 0 ; k < channels * 11 ; k++)
954 			if (error_function (data [k] / scale, orig [k + channels * m * 11] / scale, margin))
955 			{	printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
956 				for (m = 0 ; m < channels ; m++)
957 					printf ("%d ", data [m]) ;
958 				printf ("\n") ;
959 				exit (1) ;
960 				} ;
961 		} ;
962 
963 	seekpos = BUFFER_SIZE / 10 ;
964 
965 	/* Check seek from start of file. */
966 	if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
967 	{	printf ("Seek to start of file + %" PRId64 " failed (%d).\n", seekpos, k) ;
968 		exit (1) ;
969 		} ;
970 
971 	test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
972 
973 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
974 	{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
975 		exit (1) ;
976 		} ;
977 
978 	if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
979 	{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %" PRId64 ")\n", __LINE__, k, seekpos + 1) ;
980 		exit (1) ;
981 		} ;
982 
983 	seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
984 	k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
985 	test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
986 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
987 	{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
988 		exit (1) ;
989 		} ;
990 
991 	seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
992 	/* Check seek backward from current position. */
993 	k = sf_seek (file, -20, SEEK_CUR) ;
994 	test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
995 	if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
996 	{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
997 		exit (1) ;
998 		} ;
999 
1000 	/* Check that read past end of file returns number of items. */
1001 	sf_seek (file, sfinfo.frames, SEEK_SET) ;
1002 
1003  	if ((k = sf_readf_int (file, data, datalen)) != 0)
1004  	{	printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
1005  		exit (1) ;
1006  		} ;
1007 
1008 	/* Check seek backward from end. */
1009 	if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
1010 	{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
1011 		exit (1) ;
1012 		} ;
1013 
1014 	test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
1015 	if (error_function (data [0] / scale, orig [5 * channels] / scale, margin))
1016 	{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ;
1017 		exit (1) ;
1018 		} ;
1019 
1020 	sf_close (file) ;
1021 
1022 	unlink (filename) ;
1023 	printf ("ok\n") ;
1024 } /* lcomp_test_int */
1025 
1026 /*--------------------------------------------------------------------------------------------
1027 */
1028 
1029 static void
lcomp_test_float(const char * filename,int filetype,int channels,double margin)1030 lcomp_test_float (const char *filename, int filetype, int channels, double margin)
1031 {	SNDFILE			*file ;
1032 	SF_INFO			sfinfo ;
1033 	int				k, m, seekpos ;
1034 	sf_count_t		datalen ;
1035 	float			*orig, *data ;
1036 	double			half_max_abs ;
1037 
1038 	print_test_name ("lcomp_test_float", filename) ;
1039 
1040 	datalen = BUFFER_SIZE / channels ;
1041 
1042 	data = data_buffer.f ;
1043 	orig = orig_buffer.f ;
1044 
1045 	gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
1046 	for (k = 0 ; k < channels * datalen ; k++)
1047 		orig [k] = orig_buffer.d [k] ;
1048 
1049 	sfinfo.samplerate	= SAMPLE_RATE ;
1050 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
1051 	sfinfo.channels		= channels ;
1052 	sfinfo.format		= filetype ;
1053 
1054 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
1055 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1056 	test_writef_float_or_die (file, 0, orig, datalen, __LINE__) ;
1057 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1058 	sf_close (file) ;
1059 
1060 	memset (data, 0, datalen * sizeof (float)) ;
1061 
1062 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1063 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
1064 
1065 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1066 
1067 	if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1068 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
1069 		exit (1) ;
1070 		} ;
1071 
1072 	if (sfinfo.frames < datalen / channels)
1073 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1074 		exit (1) ;
1075 		} ;
1076 
1077 	if (sfinfo.frames > (datalen + datalen / 20))
1078 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1079 		exit (1) ;
1080 		} ;
1081 
1082 	if (sfinfo.channels != channels)
1083 	{	printf ("Incorrect number of channels in file.\n") ;
1084 		exit (1) ;
1085 		} ;
1086 
1087 	check_comment (file, filetype, __LINE__) ;
1088 
1089 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1090 
1091 	check_log_buffer_or_die (file, __LINE__) ;
1092 
1093 	check_comment (file, filetype, __LINE__) ;
1094 
1095 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1096 
1097 	test_readf_float_or_die (file, 0, data, datalen, __LINE__) ;
1098 
1099 	half_max_abs = 0.0 ;
1100 	for (k = 0 ; k < datalen ; k++)
1101 	{	if (error_function (data [k], orig [k], margin))
1102 		{	printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
1103 			oct_save_float (orig, data, datalen) ;
1104 			exit (1) ;
1105 			} ;
1106 		half_max_abs = LCT_MAX (half_max_abs, fabs (0.5 * data [k])) ;
1107 		} ;
1108 
1109 	if (half_max_abs < 1.0)
1110 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
1111 		exit (1) ;
1112 		} ;
1113 
1114 	if ((k = sf_readf_float (file, data, datalen)) != sfinfo.frames - datalen)
1115 	{	printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
1116 			channels * sfinfo.frames - datalen, k) ;
1117 		exit (1) ;
1118 		} ;
1119 
1120 	/*	This check is only for block based encoders which must append silence
1121 	**	to the end of a file so as to fill out a block.
1122 	*/
1123 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
1124 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
1125 			if (ABS (data [channels * k]) > decay_response (channels * k))
1126 			{	printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
1127 				exit (1) ;
1128 				} ;
1129 
1130 	if (! sfinfo.seekable)
1131 	{	sf_close (file) ;
1132 		unlink (filename) ;
1133 		printf ("ok\n") ;
1134 		return ;
1135 		} ;
1136 
1137 	/* Now test sf_seek function. */
1138 
1139 	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
1140 	{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
1141 		exit (1) ;
1142 		} ;
1143 
1144 	for (m = 0 ; m < 3 ; m++)
1145 	{	test_readf_float_or_die (file, 0, data, 11, __LINE__) ;
1146 
1147 		for (k = 0 ; k < channels * 11 ; k++)
1148 			if (error_function (data [k], orig [k + channels * m * 11], margin))
1149 			{	printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
1150 				for (m = 0 ; m < channels ; m++)
1151 					printf ("%f ", data [m]) ;
1152 				printf ("\n") ;
1153 				exit (1) ;
1154 				} ;
1155 		} ;
1156 
1157 	seekpos = BUFFER_SIZE / 10 ;
1158 
1159 	/* Check seek from start of file. */
1160 	if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
1161 	{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
1162 		exit (1) ;
1163 		} ;
1164 
1165 	test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
1166 
1167 	if (error_function (data [0], orig [seekpos * channels], margin))
1168 	{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_float failed (%f, %f).\n", __LINE__, orig [1], data [0]) ;
1169 		exit (1) ;
1170 		} ;
1171 
1172 	if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
1173 	{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
1174 		exit (1) ;
1175 		} ;
1176 
1177 	seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
1178 	k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
1179 	test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
1180 	if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
1181 	{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
1182 		exit (1) ;
1183 		} ;
1184 
1185 	seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
1186 	/* Check seek backward from current position. */
1187 	k = sf_seek (file, -20, SEEK_CUR) ;
1188 	test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
1189 	if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
1190 	{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
1191 		exit (1) ;
1192 		} ;
1193 
1194 	/* Check that read past end of file returns number of items. */
1195 	sf_seek (file, sfinfo.frames, SEEK_SET) ;
1196 
1197  	if ((k = sf_readf_float (file, data, datalen)) != 0)
1198  	{	printf ("\n\nLine %d: Return value from sf_readf_float past end of file incorrect (%d).\n", __LINE__, k) ;
1199  		exit (1) ;
1200  		} ;
1201 
1202 	/* Check seek backward from end. */
1203 	if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
1204 	{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
1205 		exit (1) ;
1206 		} ;
1207 
1208 	test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
1209 	if (error_function (data [0], orig [5 * channels], margin))
1210 	{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
1211 		exit (1) ;
1212 		} ;
1213 
1214 	sf_close (file) ;
1215 
1216 	unlink (filename) ;
1217 	printf ("ok\n") ;
1218 } /* lcomp_test_float */
1219 
1220 /*--------------------------------------------------------------------------------------------
1221 */
1222 
1223 static void
lcomp_test_double(const char * filename,int filetype,int channels,double margin)1224 lcomp_test_double (const char *filename, int filetype, int channels, double margin)
1225 {	SNDFILE			*file ;
1226 	SF_INFO			sfinfo ;
1227 	int				k, m, seekpos ;
1228 	sf_count_t		datalen ;
1229 	double			*orig, *data ;
1230 	double			half_max_abs ;
1231 
1232 	print_test_name ("lcomp_test_double", filename) ;
1233 
1234 	datalen = BUFFER_SIZE / channels ;
1235 
1236 	data = data_buffer.d ;
1237 	orig = orig_buffer.d ;
1238 
1239 	gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
1240 	for (k = 0 ; k < channels * datalen ; k++)
1241 		orig [k] = orig_buffer.d [k] ;
1242 
1243 	sfinfo.samplerate	= SAMPLE_RATE ;
1244 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
1245 	sfinfo.channels		= channels ;
1246 	sfinfo.format		= filetype ;
1247 
1248 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
1249 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1250 	test_writef_double_or_die (file, 0, orig, datalen, __LINE__) ;
1251 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1252 	sf_close (file) ;
1253 
1254 	memset (data, 0, datalen * sizeof (double)) ;
1255 
1256 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1257 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
1258 
1259 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1260 
1261 	if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1262 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
1263 		exit (1) ;
1264 		} ;
1265 
1266 	if (sfinfo.frames < datalen / channels)
1267 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1268 		exit (1) ;
1269 		} ;
1270 
1271 	if (sfinfo.frames > (datalen + datalen / 20))
1272 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1273 		exit (1) ;
1274 		} ;
1275 
1276 	if (sfinfo.channels != channels)
1277 	{	printf ("Incorrect number of channels in file.\n") ;
1278 		exit (1) ;
1279 		} ;
1280 
1281 	check_comment (file, filetype, __LINE__) ;
1282 
1283 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1284 
1285 	check_log_buffer_or_die (file, __LINE__) ;
1286 
1287 	check_comment (file, filetype, __LINE__) ;
1288 
1289 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1290 
1291 	test_readf_double_or_die (file, 0, data, datalen, __LINE__) ;
1292 
1293 	half_max_abs = 0.0 ;
1294 	for (k = 0 ; k < datalen ; k++)
1295 	{	if (error_function (data [k], orig [k], margin))
1296 		{	printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
1297 			oct_save_double (orig, data, datalen) ;
1298 			exit (1) ;
1299 			} ;
1300 		half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
1301 		} ;
1302 
1303 	if (half_max_abs < 1.0)
1304 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
1305 		exit (1) ;
1306 		} ;
1307 
1308 	if ((k = sf_readf_double (file, data, datalen)) != sfinfo.frames - datalen)
1309 	{	printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
1310 			channels * sfinfo.frames - datalen, k) ;
1311 		exit (1) ;
1312 		} ;
1313 
1314 	/*	This check is only for block based encoders which must append silence
1315 	**	to the end of a file so as to fill out a block.
1316 	*/
1317 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
1318 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
1319 			if (ABS (data [channels * k]) > decay_response (channels * k))
1320 			{	printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
1321 				exit (1) ;
1322 				} ;
1323 
1324 	if (! sfinfo.seekable)
1325 	{	sf_close (file) ;
1326 		unlink (filename) ;
1327 		printf ("ok\n") ;
1328 		return ;
1329 		} ;
1330 
1331 	/* Now test sf_seek function. */
1332 
1333 	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
1334 	{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
1335 		exit (1) ;
1336 		} ;
1337 
1338 	for (m = 0 ; m < 3 ; m++)
1339 	{	test_readf_double_or_die (file, m, data, 11, __LINE__) ;
1340 
1341 		for (k = 0 ; k < channels * 11 ; k++)
1342 			if (error_function (data [k], orig [k + channels * m * 11], margin))
1343 			{	printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
1344 				for (m = 0 ; m < channels ; m++)
1345 					printf ("%f ", data [m]) ;
1346 				printf ("\n") ;
1347 				exit (1) ;
1348 				} ;
1349 		} ;
1350 
1351 	seekpos = BUFFER_SIZE / 10 ;
1352 
1353 	/* Check seek from start of file. */
1354 	if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
1355 	{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
1356 		exit (1) ;
1357 		} ;
1358 
1359 	test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
1360 
1361 	if (error_function (data [0], orig [seekpos * channels], margin))
1362 	{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_double failed (%f, %f).\n", __LINE__, orig [1], data [0]) ;
1363 		exit (1) ;
1364 		} ;
1365 
1366 	if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
1367 	{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
1368 		exit (1) ;
1369 		} ;
1370 
1371 	seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
1372 	k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
1373 	test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
1374 	if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
1375 	{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
1376 		exit (1) ;
1377 		} ;
1378 
1379 	seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
1380 	/* Check seek backward from current position. */
1381 	k = sf_seek (file, -20, SEEK_CUR) ;
1382 	test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
1383 	if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
1384 	{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
1385 		exit (1) ;
1386 		} ;
1387 
1388 	/* Check that read past end of file returns number of items. */
1389 	sf_seek (file, sfinfo.frames, SEEK_SET) ;
1390 
1391  	if ((k = sf_readf_double (file, data, datalen)) != 0)
1392  	{	printf ("\n\nLine %d: Return value from sf_readf_double past end of file incorrect (%d).\n", __LINE__, k) ;
1393  		exit (1) ;
1394  		} ;
1395 
1396 	/* Check seek backward from end. */
1397 	if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
1398 	{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
1399 		exit (1) ;
1400 		} ;
1401 
1402 	test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
1403 	if (error_function (data [0], orig [5 * channels], margin))
1404 	{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
1405 		exit (1) ;
1406 		} ;
1407 
1408 	sf_close (file) ;
1409 
1410 	unlink (filename) ;
1411 	printf ("ok\n") ;
1412 } /* lcomp_test_double */
1413 
1414 /*========================================================================================
1415 **	Smoothed differential loss compression tests.
1416 */
1417 
1418 static void
sdlcomp_test_short(const char * filename,int filetype,int channels,double margin)1419 sdlcomp_test_short	(const char *filename, int filetype, int channels, double margin)
1420 {	SNDFILE			*file ;
1421 	SF_INFO			sfinfo ;
1422 	int				k, m, seekpos, half_max_abs ;
1423 	sf_count_t		datalen ;
1424 	short			*orig, *data, *smooth ;
1425 
1426 channels = 1 ;
1427 	print_test_name ("sdlcomp_test_short", filename) ;
1428 
1429 	datalen = BUFFER_SIZE ;
1430 
1431 	orig = orig_buffer.s ;
1432 	data = data_buffer.s ;
1433 	smooth = smooth_buffer.s ;
1434 
1435 	gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
1436 	for (k = 0 ; k < datalen ; k++)
1437 		orig [k] = lrint (orig_buffer.d [k]) ;
1438 
1439 	sfinfo.samplerate	= SAMPLE_RATE ;
1440 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
1441 	sfinfo.channels		= channels ;
1442 	sfinfo.format		= filetype ;
1443 
1444 	/*	The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
1445 	**	<= 22050. Increasing the sample rate to 32000 avoids triggering it.
1446 	**	See https://trac.xiph.org/ticket/1229
1447 	**
1448 	**	Opus only supports discrete sample rates. Choose supported 12000.
1449 	*/
1450 	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1451 	{	const char * errstr ;
1452 
1453 		errstr = sf_strerror (NULL) ;
1454 		if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL)
1455 		{	printf ("\n                                  Sample rate -> 32kHz    ") ;
1456 			sfinfo.samplerate = 32000 ;
1457 			}
1458 		else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1459 		{	printf ("\n                                  Sample rate -> 12kHz    ") ;
1460 			sfinfo.samplerate = 12000 ;
1461 			}
1462 		else
1463 		{	printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1464 			dump_log_buffer (NULL) ;
1465 			exit (1) ;
1466 			} ;
1467 
1468 		file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1469 		} ;
1470 
1471 	if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
1472 	{	sf_close (file) ;
1473 		return ;
1474 		} ;
1475 
1476 	test_write_short_or_die (file, 0, orig, datalen, __LINE__) ;
1477 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1478 	sf_close (file) ;
1479 
1480 	memset (data, 0, datalen * sizeof (short)) ;
1481 
1482 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1483 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
1484 
1485 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1486 
1487 	if (sfinfo.format != filetype)
1488 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
1489 		exit (1) ;
1490 		} ;
1491 
1492 	if (sfinfo.frames < datalen / channels)
1493 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1494 		exit (1) ;
1495 		} ;
1496 
1497 	if (sfinfo.frames > (datalen + 400))
1498 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
1499 		exit (1) ;
1500 		} ;
1501 
1502 	if (sfinfo.channels != channels)
1503 	{	printf ("Incorrect number of channels in file.\n") ;
1504 		exit (1) ;
1505 		} ;
1506 
1507 	check_comment (file, filetype, __LINE__) ;
1508 
1509 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1510 
1511 	check_log_buffer_or_die (file, __LINE__) ;
1512 
1513 	test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
1514 
1515 	memcpy (smooth, orig, datalen * sizeof (short)) ;
1516 	smoothed_diff_short (data, datalen) ;
1517 	smoothed_diff_short (smooth, datalen) ;
1518 
1519 	half_max_abs = 0.0 ;
1520 	for (k = 0 ; k < datalen ; k++)
1521 	{	if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
1522 		{	printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
1523 			oct_save_short (orig, smooth, datalen) ;
1524 			exit (1) ;
1525 			} ;
1526 		half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
1527 		} ;
1528 
1529 	if (half_max_abs < 1)
1530 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
1531 		exit (1) ;
1532 		} ;
1533 
1534 	if ((k = sf_read_short (file, data, datalen)) != sfinfo.frames - datalen)
1535 	{	printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
1536 		exit (1) ;
1537 		} ;
1538 
1539 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
1540 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
1541 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
1542 			if (ABS (data [k]) > decay_response (k))
1543 			{	printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ;
1544 				exit (1) ;
1545 				} ;
1546 
1547 	/* Now test sf_seek function. */
1548 	if (sfinfo.seekable)
1549 	{	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
1550 		{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
1551 			exit (1) ;
1552 			} ;
1553 
1554 		for (m = 0 ; m < 3 ; m++)
1555 		{	test_readf_short_or_die (file, m, data, datalen / 7, __LINE__) ;
1556 
1557 			smoothed_diff_short (data, datalen / 7) ;
1558 			memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (short)) ;
1559 			smoothed_diff_short (smooth, datalen / 7) ;
1560 
1561 			for (k = 0 ; k < datalen / 7 ; k++)
1562 				if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
1563 				{	printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ;
1564 					for (m = 0 ; m < 10 ; m++)
1565 						printf ("%d ", data [k]) ;
1566 					printf ("\n") ;
1567 					exit (1) ;
1568 					} ;
1569 			} ; /* for (m = 0 ; m < 3 ; m++) */
1570 
1571 		seekpos = BUFFER_SIZE / 10 ;
1572 
1573 		/* Check seek from start of file. */
1574 		if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
1575 		{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
1576 			exit (1) ;
1577 			} ;
1578 		test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
1579 
1580 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
1581 		{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
1582 			exit (1) ;
1583 			} ;
1584 
1585 		if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
1586 		{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
1587 			exit (1) ;
1588 			} ;
1589 
1590 		seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
1591 		k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
1592 		test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
1593 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
1594 		{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
1595 			exit (1) ;
1596 			} ;
1597 
1598 		seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
1599 		/* Check seek backward from current position. */
1600 		k = sf_seek (file, -20, SEEK_CUR) ;
1601 		test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
1602 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
1603 		{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
1604 			exit (1) ;
1605 			} ;
1606 
1607 		/* Check that read past end of file returns number of items. */
1608 		sf_seek (file, sfinfo.frames, SEEK_SET) ;
1609 
1610 		if ((k = sf_read_short (file, data, datalen)) != 0)
1611 		{	printf ("\n\nLine %d: Return value from sf_read_short past end of file incorrect (%d).\n", __LINE__, k) ;
1612 			exit (1) ;
1613 			} ;
1614 
1615 		/* Check seek backward from end. */
1616 
1617 		if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
1618 		{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
1619 			exit (1) ;
1620 			} ;
1621 
1622 		test_read_short_or_die (file, 0, data, channels, __LINE__) ;
1623 		if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin))
1624 		{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ;
1625 			exit (1) ;
1626 			} ;
1627 		} /* if (sfinfo.seekable) */
1628 
1629 	sf_close (file) ;
1630 
1631 	unlink (filename) ;
1632 	printf ("ok\n") ;
1633 } /* sdlcomp_test_short */
1634 
1635 static	void
sdlcomp_test_int(const char * filename,int filetype,int channels,double margin)1636 sdlcomp_test_int	(const char *filename, int filetype, int channels, double margin)
1637 {	SNDFILE			*file ;
1638 	SF_INFO			sfinfo ;
1639 	int				k, m, seekpos, half_max_abs ;
1640 	sf_count_t		datalen ;
1641 	int				*orig, *data, *smooth ;
1642 	double			scale ;
1643 
1644 channels = 1 ;
1645 
1646 	print_test_name ("sdlcomp_test_int", filename) ;
1647 
1648 	datalen = BUFFER_SIZE ;
1649 	scale = 1.0 * 0x10000 ;
1650 
1651 	orig = orig_buffer.i ;
1652 	data = data_buffer.i ;
1653 	smooth = smooth_buffer.i ;
1654 
1655 	gen_signal_double (orig_buffer.d, 32000.0 * scale, channels, datalen) ;
1656 	for (k = 0 ; k < datalen ; k++)
1657 		orig [k] = lrint (orig_buffer.d [k]) ;
1658 
1659 	sfinfo.samplerate	= SAMPLE_RATE ;
1660 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
1661 	sfinfo.channels		= channels ;
1662 	sfinfo.format		= filetype ;
1663 
1664 	/*	The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
1665 	**	<= 22050. Increasing the sample rate to 32000 avoids triggering it.
1666 	**	See https://trac.xiph.org/ticket/1229
1667 	**
1668 	**	Opus only supports discrete sample rates. Choose supported 12000.
1669 	*/
1670 	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1671 	{	const char * errstr ;
1672 
1673 		errstr = sf_strerror (NULL) ;
1674 		if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL)
1675 		{	printf ("\n                                  Sample rate -> 32kHz    ") ;
1676 			sfinfo.samplerate = 32000 ;
1677 			}
1678 		else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1679 		{	printf ("\n                                  Sample rate -> 12kHz    ") ;
1680 			sfinfo.samplerate = 12000 ;
1681 			}
1682 		else
1683 		{	printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1684 			dump_log_buffer (NULL) ;
1685 			exit (1) ;
1686 			} ;
1687 
1688 		file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1689 		} ;
1690 
1691 	if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
1692 	{	sf_close (file) ;
1693 		return ;
1694 		} ;
1695 
1696 	test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ;
1697 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1698 	sf_close (file) ;
1699 
1700 	memset (data, 0, datalen * sizeof (int)) ;
1701 
1702 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1703 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
1704 
1705 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1706 
1707 	if (sfinfo.format != filetype)
1708 	{	printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
1709 		exit (1) ;
1710 		} ;
1711 
1712 	if (sfinfo.frames < datalen / channels)
1713 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1714 		exit (1) ;
1715 		} ;
1716 
1717 	if (sfinfo.frames > (datalen + 400))
1718 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
1719 		exit (1) ;
1720 		} ;
1721 
1722 	if (sfinfo.channels != channels)
1723 	{	printf ("Incorrect number of channels in file.\n") ;
1724 		exit (1) ;
1725 		} ;
1726 
1727 	check_log_buffer_or_die (file, __LINE__) ;
1728 
1729 	test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
1730 
1731 	memcpy (smooth, orig, datalen * sizeof (int)) ;
1732 	smoothed_diff_int (data, datalen) ;
1733 	smoothed_diff_int (smooth, datalen) ;
1734 
1735 	half_max_abs = abs (data [0] >> 16) ;
1736 	for (k = 1 ; k < datalen ; k++)
1737 	{	if (error_function (data [k] / scale, smooth [k] / scale, margin))
1738 		{	printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
1739 			oct_save_int (orig, smooth, datalen) ;
1740 			exit (1) ;
1741 			} ;
1742 		half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
1743 		} ;
1744 
1745 	if (half_max_abs < 1)
1746 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
1747 		exit (1) ;
1748 		} ;
1749 
1750 	if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
1751 	{	printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
1752 		exit (1) ;
1753 		} ;
1754 
1755 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_IMA_ADPCM &&
1756 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
1757 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610 &&
1758 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G721_32 &&
1759 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G723_24 &&
1760 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_16 &&
1761 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_24 &&
1762 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_32)
1763 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
1764 			if (abs (data [k]) > decay_response (k))
1765 			{	printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ;
1766 				exit (1) ;
1767 				} ;
1768 
1769 	/* Now test sf_seek function. */
1770 	if (sfinfo.seekable)
1771 	{	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
1772 		{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
1773 			exit (1) ;
1774 			} ;
1775 
1776 		for (m = 0 ; m < 3 ; m++)
1777 		{	test_readf_int_or_die (file, m, data, datalen / 7, __LINE__) ;
1778 
1779 			smoothed_diff_int (data, datalen / 7) ;
1780 			memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (int)) ;
1781 			smoothed_diff_int (smooth, datalen / 7) ;
1782 
1783 			for (k = 0 ; k < datalen / 7 ; k++)
1784 				if (error_function (data [k] / scale, smooth [k] / scale, margin))
1785 				{	printf ("\nLine %d: Incorrect sample (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ;
1786 					for (m = 0 ; m < 10 ; m++)
1787 						printf ("%d ", data [k]) ;
1788 					printf ("\n") ;
1789 					exit (1) ;
1790 					} ;
1791 			} ; /* for (m = 0 ; m < 3 ; m++) */
1792 
1793 		seekpos = BUFFER_SIZE / 10 ;
1794 
1795 		/* Check seek from start of file. */
1796 		if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
1797 		{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
1798 			exit (1) ;
1799 			} ;
1800 		test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
1801 
1802 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
1803 		{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
1804 			exit (1) ;
1805 			} ;
1806 
1807 		if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
1808 		{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
1809 			exit (1) ;
1810 			} ;
1811 
1812 		seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
1813 		k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
1814 		test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
1815 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
1816 		{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
1817 			exit (1) ;
1818 			} ;
1819 
1820 		seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
1821 		/* Check seek backward from current position. */
1822 		k = sf_seek (file, -20, SEEK_CUR) ;
1823 		test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
1824 		if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
1825 		{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
1826 			exit (1) ;
1827 			} ;
1828 
1829 		/* Check that read past end of file returns number of items. */
1830 		sf_seek (file, sfinfo.frames, SEEK_SET) ;
1831 
1832 		if ((k = sf_readf_int (file, data, datalen)) != 0)
1833 		{	printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
1834 			exit (1) ;
1835 			} ;
1836 
1837 		/* Check seek backward from end. */
1838 
1839 		if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
1840 		{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
1841 			exit (1) ;
1842 			} ;
1843 
1844 		test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
1845 		if (error_function (data [0] / scale, orig [5] / scale, margin))
1846 		{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_int failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ;
1847 			exit (1) ;
1848 			} ;
1849 		} /* if (sfinfo.seekable) */
1850 
1851 	sf_close (file) ;
1852 
1853 	unlink (filename) ;
1854 	printf ("ok\n") ;
1855 } /* sdlcomp_test_int */
1856 
1857 static void
sdlcomp_test_float(const char * filename,int filetype,int channels,double margin)1858 sdlcomp_test_float	(const char *filename, int filetype, int channels, double margin)
1859 {	SNDFILE			*file ;
1860 	SF_INFO			sfinfo ;
1861 	int				k, m, seekpos ;
1862 	sf_count_t		datalen ;
1863 	float			*orig, *data, *smooth ;
1864 	double			half_max_abs , scale ;
1865 
1866 channels = 1 ;
1867 
1868 	print_test_name ("sdlcomp_test_float", filename) ;
1869 
1870 	switch ((filetype & SF_FORMAT_SUBMASK))
1871 	{	case SF_FORMAT_VORBIS :
1872 			/*	Vorbis starts to loose fidelity with floating point values outside
1873 			**	the range of approximately [-2000.0, 2000.0] (Determined
1874 			**	experimentally, not know if it is a limitation of Vorbis or
1875 			**	libvorbis.)
1876 			*/
1877 			scale = 16.0 ; /* 32000/16 = 2000 */
1878 			break ;
1879 
1880 		case SF_FORMAT_OPUS :
1881 			/*	The Opus spec says that non-normalized floating point value
1882 			**	support (extended dynamic range in its terms) is optional and
1883 			**	cannot be relied upon.
1884 			*/
1885 			scale = 32000.0 ; /* 32000/32000 = 1 */
1886 			break ;
1887 
1888 		default :
1889 			scale = 1.0 ;
1890 			break ;
1891 		} ;
1892 
1893 	datalen = BUFFER_SIZE ;
1894 
1895 	orig = orig_buffer.f ;
1896 	data = data_buffer.f ;
1897 	smooth = smooth_buffer.f ;
1898 
1899 	gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, datalen) ;
1900 	for (k = 0 ; k < datalen ; k++)
1901 		orig [k] = orig_buffer.d [k] ;
1902 
1903 	sfinfo.samplerate	= SAMPLE_RATE ;
1904 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
1905 	sfinfo.channels		= channels ;
1906 	sfinfo.format		= filetype ;
1907 
1908 
1909 	/*	The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
1910 	**	<= 22050. Increasing the sample rate to 32000 avoids triggering it.
1911 	**	See https://trac.xiph.org/ticket/1229
1912 	**
1913 	**	Opus only supports discrete sample rates. Choose supported 12000.
1914 	*/
1915 	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1916 	{	const char * errstr ;
1917 
1918 		errstr = sf_strerror (NULL) ;
1919 		if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL)
1920 		{	printf ("\n                                  Sample rate -> 32kHz    ") ;
1921 			sfinfo.samplerate = 32000 ;
1922 			}
1923 		else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1924 		{	printf ("\n                                  Sample rate -> 12kHz    ") ;
1925 			sfinfo.samplerate = 12000 ;
1926 			}
1927 		else
1928 		{	printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1929 			dump_log_buffer (NULL) ;
1930 			exit (1) ;
1931 			} ;
1932 
1933 		file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1934 		} ;
1935 
1936 	if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
1937 	{	sf_close (file) ;
1938 		return ;
1939 		} ;
1940 
1941 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1942 	test_write_float_or_die (file, 0, orig, datalen, __LINE__) ;
1943 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1944 	sf_close (file) ;
1945 
1946 	memset (data, 0, datalen * sizeof (float)) ;
1947 
1948 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1949 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
1950 
1951 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1952 
1953 	if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1954 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
1955 		exit (1) ;
1956 		} ;
1957 
1958 	if (sfinfo.frames < datalen / channels)
1959 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
1960 		exit (1) ;
1961 		} ;
1962 
1963 	if (sfinfo.frames > (datalen + 400))
1964 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
1965 		exit (1) ;
1966 		} ;
1967 
1968 	if (sfinfo.channels != channels)
1969 	{	printf ("Incorrect number of channels in file.\n") ;
1970 		exit (1) ;
1971 		} ;
1972 
1973 	check_comment (file, filetype, __LINE__) ;
1974 
1975 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1976 
1977 	check_log_buffer_or_die (file, __LINE__) ;
1978 
1979 	test_read_float_or_die (file, 0, data, datalen, __LINE__) ;
1980 
1981 	memcpy (smooth, orig, datalen * sizeof (float)) ;
1982 	smoothed_diff_float (data, datalen) ;
1983 	smoothed_diff_float (smooth, datalen) ;
1984 
1985 	half_max_abs = fabs (data [0]) ;
1986 	for (k = 1 ; k < datalen ; k++)
1987 	{	if (error_function (data [k] * scale, smooth [k] * scale, margin))
1988 		{	printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ;
1989 			oct_save_float (orig, smooth, datalen) ;
1990 			exit (1) ;
1991 			} ;
1992 		half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k] * scale)) ;
1993 		} ;
1994 
1995 	if (half_max_abs <= 0.0)
1996 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
1997 		printf ("half_max_abs : % 10.6f\n", half_max_abs) ;
1998 		exit (1) ;
1999 		} ;
2000 
2001 	if ((k = sf_read_float (file, data, datalen)) != sfinfo.frames - datalen)
2002 	{	printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
2003 		exit (1) ;
2004 		} ;
2005 
2006 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
2007 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
2008 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
2009 			if (ABS (data [k]) > decay_response (k))
2010 			{	printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ;
2011 				exit (1) ;
2012 				} ;
2013 
2014 	/* Now test sf_seek function. */
2015 	if (sfinfo.seekable)
2016 	{	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
2017 		{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
2018 			exit (1) ;
2019 			} ;
2020 
2021 		for (m = 0 ; m < 3 ; m++)
2022 		{	test_read_float_or_die (file, 0, data, datalen / 7, __LINE__) ;
2023 
2024 			smoothed_diff_float (data, datalen / 7) ;
2025 			memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (float)) ;
2026 			smoothed_diff_float (smooth, datalen / 7) ;
2027 
2028 			for (k = 0 ; k < datalen / 7 ; k++)
2029 				if (error_function (data [k] * scale, smooth [k] * scale, margin))
2030 				{	printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) (smooth [k] * scale), (int) (data [k] * scale)) ;
2031 					for (m = 0 ; m < 10 ; m++)
2032 						printf ("%d ", (int) data [k]) ;
2033 					printf ("\n") ;
2034 					exit (1) ;
2035 					} ;
2036 			} ; /* for (m = 0 ; m < 3 ; m++) */
2037 
2038 		seekpos = BUFFER_SIZE / 10 ;
2039 
2040 		/* Check seek from start of file. */
2041 		if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
2042 		{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
2043 			exit (1) ;
2044 			} ;
2045 		test_read_float_or_die (file, 0, data, channels, __LINE__) ;
2046 
2047 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin))
2048 		{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_float failed (%d, %d).\n", __LINE__, (int) (orig [1] * scale), (int) (data [0] * scale)) ;
2049 			exit (1) ;
2050 			} ;
2051 
2052 		if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
2053 		{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
2054 			exit (1) ;
2055 			} ;
2056 
2057 		seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
2058 		k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
2059 		test_read_float_or_die (file, 0, data, channels, __LINE__) ;
2060 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
2061 		{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ;
2062 			exit (1) ;
2063 			} ;
2064 
2065 		seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
2066 		/* Check seek backward from current position. */
2067 		k = sf_seek (file, -20, SEEK_CUR) ;
2068 		test_read_float_or_die (file, 0, data, channels, __LINE__) ;
2069 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
2070 		{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ;
2071 			exit (1) ;
2072 			} ;
2073 
2074 		/* Check that read past end of file returns number of items. */
2075 		sf_seek (file, sfinfo.frames, SEEK_SET) ;
2076 
2077 		if ((k = sf_read_float (file, data, datalen)) != 0)
2078 		{	printf ("\n\nLine %d: Return value from sf_read_float past end of file incorrect (%d).\n", __LINE__, k) ;
2079 			exit (1) ;
2080 			} ;
2081 
2082 		/* Check seek backward from end. */
2083 
2084 		if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
2085 		{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
2086 			exit (1) ;
2087 			} ;
2088 
2089 		test_read_float_or_die (file, 0, data, channels, __LINE__) ;
2090 		if (error_function (data [0] * scale, orig [5 * channels] * scale, margin))
2091 		{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_float failed (%f should be %f).\n", __LINE__, data [0] * scale, orig [5 * channels] * scale) ;
2092 			exit (1) ;
2093 			} ;
2094 		} /* if (sfinfo.seekable) */
2095 
2096 	sf_close (file) ;
2097 
2098 	unlink (filename) ;
2099 	printf ("ok\n") ;
2100 } /* sdlcomp_test_float */
2101 
2102 static void
sdlcomp_test_double(const char * filename,int filetype,int channels,double margin)2103 sdlcomp_test_double	(const char *filename, int filetype, int channels, double margin)
2104 {	SNDFILE			*file ;
2105 	SF_INFO			sfinfo ;
2106 	int				k, m, seekpos ;
2107 	sf_count_t		datalen ;
2108 	double			*orig, *data, *smooth, half_max_abs, scale ;
2109 
2110 channels = 1 ;
2111 	print_test_name ("sdlcomp_test_double", filename) ;
2112 
2113 	switch ((filetype & SF_FORMAT_SUBMASK))
2114 	{	case SF_FORMAT_VORBIS :
2115 			/*	Vorbis starts to loose fidelity with floating point values outside
2116 			**	the range of approximately [-2000.0, 2000.0] (Determined
2117 			**	experimentally, not know if it is a limitation of Vorbis or
2118 			**	libvorbis.)
2119 			*/
2120 			scale = 16.0 ; /* 32000/16 = 2000 */
2121 			break ;
2122 
2123 		case SF_FORMAT_OPUS :
2124 			/*	The Opus spec says that non-normalized floating point value
2125 			**	support (extended dynamic range in its terms) is optional and
2126 			**	cannot be relied upon.
2127 			*/
2128 			scale = 32000.0 ; /* 32000/32000 = 1 */
2129 			break ;
2130 
2131 		default :
2132 			scale = 1.0 ;
2133 			break ;
2134 		} ;
2135 
2136 	datalen = BUFFER_SIZE ;
2137 
2138 	orig = orig_buffer.d ;
2139 	data = data_buffer.d ;
2140 	smooth = smooth_buffer.d ;
2141 
2142 	gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, datalen) ;
2143 
2144 	sfinfo.samplerate	= SAMPLE_RATE ;
2145 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
2146 	sfinfo.channels		= channels ;
2147 	sfinfo.format		= filetype ;
2148 
2149 	/*	The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
2150 	**	<= 22050. Increasing the sample rate to 32000 avoids triggering it.
2151 	**	See https://trac.xiph.org/ticket/1229
2152 	**
2153 	**	Opus only supports discrete sample rates. Choose supported 12000.
2154 	*/
2155 	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
2156 	{	const char * errstr ;
2157 
2158 		errstr = sf_strerror (NULL) ;
2159 		if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL)
2160 		{	printf ("\n                                  Sample rate -> 32kHz    ") ;
2161 			sfinfo.samplerate = 32000 ;
2162 			}
2163 		else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
2164 		{	printf ("\n                                  Sample rate -> 12kHz    ") ;
2165 			sfinfo.samplerate = 12000 ;
2166 			}
2167 		else
2168 		{	printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
2169 			dump_log_buffer (NULL) ;
2170 			exit (1) ;
2171 			} ;
2172 
2173 		file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
2174 		} ;
2175 
2176 	if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
2177 	{	sf_close (file) ;
2178 		return ;
2179 		} ;
2180 
2181 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
2182 	test_write_double_or_die (file, 0, orig, datalen, __LINE__) ;
2183 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
2184 	sf_close (file) ;
2185 
2186 	memset (data, 0, datalen * sizeof (double)) ;
2187 
2188 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2189 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
2190 
2191 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
2192 
2193 	if (sfinfo.format != filetype)
2194 	{	printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
2195 		exit (1) ;
2196 		} ;
2197 
2198 	if (sfinfo.frames < datalen / channels)
2199 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
2200 		exit (1) ;
2201 		} ;
2202 
2203 	if (sfinfo.frames > (datalen + 400))
2204 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
2205 		exit (1) ;
2206 		} ;
2207 
2208 	if (sfinfo.channels != channels)
2209 	{	printf ("Incorrect number of channels in file.\n") ;
2210 		exit (1) ;
2211 		} ;
2212 
2213 	check_comment (file, filetype, __LINE__) ;
2214 
2215 	check_comment (file, filetype, __LINE__) ;
2216 
2217 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
2218 
2219 	check_log_buffer_or_die (file, __LINE__) ;
2220 
2221 	test_read_double_or_die (file, 0, data, datalen, __LINE__) ;
2222 
2223 	memcpy (smooth, orig, datalen * sizeof (double)) ;
2224 	smoothed_diff_double (data, datalen) ;
2225 	smoothed_diff_double (smooth, datalen) ;
2226 
2227 	half_max_abs = 0.0 ;
2228 	for (k = 0 ; k < datalen ; k++)
2229 	{	if (error_function (data [k] * scale, smooth [k] * scale, margin))
2230 		{	printf ("\n\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ;
2231 			oct_save_double (orig, smooth, datalen) ;
2232 			exit (1) ;
2233 			} ;
2234 		half_max_abs = LCT_MAX (half_max_abs, 0.5 * fabs (data [k] * scale)) ;
2235 		} ;
2236 
2237 	if (half_max_abs < 1.0)
2238 	{	printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
2239 		exit (1) ;
2240 		} ;
2241 
2242 	if ((k = sf_read_double (file, data, datalen)) != sfinfo.frames - datalen)
2243 	{	printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
2244 		exit (1) ;
2245 		} ;
2246 
2247 	if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
2248 		(sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
2249 		for (k = 0 ; k < sfinfo.frames - datalen ; k++)
2250 			if (ABS (data [k]) > decay_response (k))
2251 			{	printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ;
2252 				exit (1) ;
2253 				} ;
2254 
2255 	/* Now test sf_seek function. */
2256 	if (sfinfo.seekable)
2257 	{	if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
2258 		{	printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
2259 			exit (1) ;
2260 			} ;
2261 
2262 		for (m = 0 ; m < 3 ; m++)
2263 		{	test_read_double_or_die (file, m, data, datalen / 7, __LINE__) ;
2264 
2265 			smoothed_diff_double (data, datalen / 7) ;
2266 			memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (double)) ;
2267 			smoothed_diff_double (smooth, datalen / 7) ;
2268 
2269 			for (k = 0 ; k < datalen / 7 ; k++)
2270 				if (error_function (data [k] * scale, smooth [k] * scale, margin))
2271 				{	printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) (smooth [k] * scale), (int) (data [k] * scale)) ;
2272 					for (m = 0 ; m < 10 ; m++)
2273 						printf ("%d ", (int) data [k]) ;
2274 					printf ("\n") ;
2275 					exit (1) ;
2276 					} ;
2277 			} ; /* for (m = 0 ; m < 3 ; m++) */
2278 
2279 		seekpos = BUFFER_SIZE / 10 ;
2280 
2281 		/* Check seek from start of file. */
2282 		if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
2283 		{	printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
2284 			exit (1) ;
2285 			} ;
2286 		test_read_double_or_die (file, 0, data, channels, __LINE__) ;
2287 
2288 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin))
2289 		{	printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).\n", __LINE__, (int) (orig [1] * scale), (int) (data [0] * scale)) ;
2290 			exit (1) ;
2291 			} ;
2292 
2293 		if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
2294 		{	printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
2295 			exit (1) ;
2296 			} ;
2297 
2298 		seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
2299 		k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
2300 		test_read_double_or_die (file, 0, data, channels, __LINE__) ;
2301 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
2302 		{	printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ;
2303 			exit (1) ;
2304 			} ;
2305 
2306 		seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
2307 		/* Check seek backward from current position. */
2308 		k = sf_seek (file, -20, SEEK_CUR) ;
2309 		test_read_double_or_die (file, 0, data, channels, __LINE__) ;
2310 		if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
2311 		{	printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ;
2312 			exit (1) ;
2313 			} ;
2314 
2315 		/* Check that read past end of file returns number of items. */
2316 		sf_seek (file, sfinfo.frames, SEEK_SET) ;
2317 
2318 		if ((k = sf_read_double (file, data, datalen)) != 0)
2319 		{	printf ("\n\nLine %d: Return value from sf_read_double past end of file incorrect (%d).\n", __LINE__, k) ;
2320 			exit (1) ;
2321 			} ;
2322 
2323 		/* Check seek backward from end. */
2324 
2325 		if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
2326 		{	printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
2327 			exit (1) ;
2328 			} ;
2329 
2330 		test_read_double_or_die (file, 0, data, channels, __LINE__) ;
2331 		if (error_function (data [0] * scale, orig [5 * channels] * scale, margin))
2332 		{	printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_double failed (%f should be %f).\n", __LINE__, data [0] * scale, orig [5 * channels] * scale) ;
2333 			exit (1) ;
2334 			} ;
2335 		} /* if (sfinfo.seekable) */
2336 
2337 	sf_close (file) ;
2338 
2339 	unlink (filename) ;
2340 	printf ("ok\n") ;
2341 } /* sdlcomp_test_double */
2342 
2343 static void
read_raw_test(const char * filename,int filetype,int channels)2344 read_raw_test (const char *filename, int filetype, int channels)
2345 {	SNDFILE			*file ;
2346 	SF_INFO			sfinfo ;
2347 	sf_count_t		count, datalen ;
2348 	short			*orig, *data ;
2349 	int				k ;
2350 
2351 	print_test_name ("read_raw_test", filename) ;
2352 
2353 	datalen = ARRAY_LEN (orig_buffer.s) / 2 ;
2354 
2355 	orig = orig_buffer.s ;
2356 	data = data_buffer.s ;
2357 
2358 	gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
2359 	for (k = 0 ; k < datalen ; k++)
2360 		orig [k] = lrint (orig_buffer.d [k]) ;
2361 
2362 	sfinfo.samplerate	= SAMPLE_RATE ;
2363 	sfinfo.frames		= 123456789 ;	/* Ridiculous value. */
2364 	sfinfo.channels		= channels ;
2365 	sfinfo.format		= filetype ;
2366 
2367 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
2368 	test_write_short_or_die (file, 0, orig, datalen, __LINE__) ;
2369 	sf_set_string (file, SF_STR_COMMENT, long_comment) ;
2370 	sf_close (file) ;
2371 
2372 	memset (data, 0, datalen * sizeof (double)) ;
2373 
2374 	if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2375 		memset (&sfinfo, 0, sizeof (sfinfo)) ;
2376 
2377 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
2378 
2379 	if (sfinfo.format != filetype)
2380 	{	printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
2381 		exit (1) ;
2382 		} ;
2383 
2384 	if (sfinfo.frames < datalen / channels)
2385 	{	printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
2386 		exit (1) ;
2387 		} ;
2388 
2389 	if (sfinfo.frames > (datalen + 400))
2390 	{	printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
2391 		exit (1) ;
2392 		} ;
2393 
2394 	if (sfinfo.channels != channels)
2395 	{	printf ("Incorrect number of channels in file.\n") ;
2396 		exit (1) ;
2397 		} ;
2398 
2399 	check_comment (file, filetype, __LINE__) ;
2400 
2401 	count = sf_read_raw (file, orig_buffer.c, datalen + 5 * channels) ;
2402 	if (count != sfinfo.channels * sfinfo.frames)
2403 	{	printf ("\nLine %d : sf_read_raw returned %" PRId64 " should be %" PRId64 "\n", __LINE__, count, sfinfo.channels * sfinfo.frames) ;
2404 		exit (1) ;
2405 		} ;
2406 
2407 	sf_close (file) ;
2408 
2409 	unlink (filename) ;
2410 	printf ("ok\n") ;
2411 } /* read_raw_test */
2412 
2413 /*========================================================================================
2414 **	Auxiliary functions
2415 */
2416 
2417 #define		SIGNAL_MAXVAL	30000.0
2418 #define		DECAY_COUNT		1000
2419 
2420 static int
decay_response(int k)2421 decay_response (int k)
2422 {	if (k < 1)
2423 		return (int) (1.2 * SIGNAL_MAXVAL) ;
2424 	if (k > DECAY_COUNT)
2425 		return 0 ;
2426 	return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ;
2427 } /* decay_response */
2428 
2429 static void
gen_signal_double(double * data,double scale,int channels,int datalen)2430 gen_signal_double (double *data, double scale, int channels, int datalen)
2431 {	int		k, ramplen ;
2432 	double	amp = 0.0 ;
2433 
2434 	ramplen = DECAY_COUNT ;
2435 
2436 	if (channels == 1)
2437 	{	for (k = 0 ; k < datalen ; k++)
2438 		{	if (k <= ramplen)
2439 				amp = scale * k / ((double) ramplen) ;
2440 			else if (k > datalen - ramplen)
2441 				amp = scale * (datalen - k) / ((double) ramplen) ;
2442 
2443 /*-printf ("%3d : %g\n", k, amp) ;-*/
2444 
2445 			data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
2446 							+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
2447 			} ;
2448 		}
2449 	else
2450 	{	for (k = 0 ; k < datalen ; k ++)
2451 		{	if (k <= ramplen)
2452 				amp = scale * k / ((double) ramplen) ;
2453 			else if (k > datalen - ramplen)
2454 				amp = scale * (datalen - k) / ((double) ramplen) ;
2455 
2456 			data [2 * k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
2457 							+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
2458 			data [2 * k + 1] = amp * (0.4 * sin (55.5 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
2459 							+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
2460 			} ;
2461 		} ;
2462 
2463 	return ;
2464 } /* gen_signal_double */
2465 
2466 static int
error_function(double data,double orig,double margin)2467 error_function (double data, double orig, double margin)
2468 {	double error ;
2469 
2470 	if (fabs (orig) <= 500.0)
2471 		error = fabs (fabs (data) - fabs (orig)) / 2000.0 ;
2472 	else if (fabs (orig) <= 1000.0)
2473 		error = fabs (data - orig) / 3000.0 ;
2474 	else
2475 		error = fabs (data - orig) / fabs (orig) ;
2476 
2477 	if (error > margin)
2478 	{	printf ("\n\nerror_function (data = %f, orig = %f, margin = %f) -> %f\n", data, orig, margin, error) ;
2479 		return 1 ;
2480 		} ;
2481 	return 0 ;
2482 } /* error_function */
2483 
2484 static void
smoothed_diff_short(short * data,unsigned int datalen)2485 smoothed_diff_short (short *data, unsigned int datalen)
2486 {	unsigned int k ;
2487 	double memory = 0.0 ;
2488 
2489 	/* Calculate the smoothed sample-to-sample difference. */
2490 	for (k = 0 ; k < datalen - 1 ; k++)
2491 	{	memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
2492 		data [k] = (short) memory ;
2493 		} ;
2494 	data [datalen-1] = data [datalen-2] ;
2495 
2496 } /* smoothed_diff_short */
2497 
2498 static void
smoothed_diff_int(int * data,unsigned int datalen)2499 smoothed_diff_int (int *data, unsigned int datalen)
2500 {	unsigned int k ;
2501 	double memory = 0.0 ;
2502 
2503 	/* Calculate the smoothed sample-to-sample difference. */
2504 	for (k = 0 ; k < datalen - 1 ; k++)
2505 	{	memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
2506 		data [k] = (int) memory ;
2507 		} ;
2508 	data [datalen-1] = data [datalen-2] ;
2509 
2510 } /* smoothed_diff_int */
2511 
2512 static	void
smoothed_diff_float(float * data,unsigned int datalen)2513 smoothed_diff_float (float *data, unsigned int datalen)
2514 {	unsigned int k ;
2515 	float memory = 0.0 ;
2516 
2517 	/* Calculate the smoothed sample-to-sample difference. */
2518 	for (k = 0 ; k < datalen - 1 ; k++)
2519 	{	memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
2520 		data [k] = memory ;
2521 		} ;
2522 	data [datalen-1] = data [datalen-2] ;
2523 
2524 } /* smoothed_diff_float */
2525 
2526 static	void
smoothed_diff_double(double * data,unsigned int datalen)2527 smoothed_diff_double (double *data, unsigned int datalen)
2528 {	unsigned int k ;
2529 	double memory = 0.0 ;
2530 
2531 	/* Calculate the smoothed sample-to-sample difference. */
2532 	for (k = 0 ; k < datalen - 1 ; k++)
2533 	{	memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
2534 		data [k] = memory ;
2535 		} ;
2536 	data [datalen-1] = data [datalen-2] ;
2537 
2538 } /* smoothed_diff_double */
2539 
2540 static void
check_comment(SNDFILE * file,int format,int lineno)2541 check_comment (SNDFILE * file, int format, int lineno)
2542 {	const char		*comment ;
2543 
2544 	switch (format & SF_FORMAT_TYPEMASK)
2545 	{	case SF_FORMAT_AIFF :
2546 		case SF_FORMAT_WAV :
2547 		case SF_FORMAT_WAVEX :
2548 			break ;
2549 		default :
2550 			return ;
2551 		} ;
2552 
2553 	comment = sf_get_string (file, SF_STR_COMMENT) ;
2554 	if (comment == NULL)
2555 	{	printf ("\n\nLine %d : File does not contain a comment string.\n\n", lineno) ;
2556 		exit (1) ;
2557 		} ;
2558 
2559 	if (strcmp (comment, long_comment) != 0)
2560 	{	printf ("\n\nLine %d : File comment does not match comment written.\n\n", lineno) ;
2561 		exit (1) ;
2562 		} ;
2563 
2564 	return ;
2565 } /* check_comment */
2566 
2567 static int
is_lossy(int filetype)2568 is_lossy (int filetype)
2569 {
2570 	switch (SF_FORMAT_SUBMASK & filetype)
2571 	{	case SF_FORMAT_PCM_U8 :
2572 		case SF_FORMAT_PCM_S8 :
2573 		case SF_FORMAT_PCM_16 :
2574 		case SF_FORMAT_PCM_24 :
2575 		case SF_FORMAT_PCM_32 :
2576 		case SF_FORMAT_FLOAT :
2577 		case SF_FORMAT_DOUBLE :
2578 			return 0 ;
2579 
2580 		default :
2581 			break ;
2582 		} ;
2583 
2584 	return 1 ;
2585 } /* is_lossy */
2586 
2587 
2588 static int
check_opus_version(SNDFILE * file)2589 check_opus_version (SNDFILE *file)
2590 {	char log_buf [256] ;
2591 	char *str, *p ;
2592 	const char *str_libopus = "Opus library version: " ;
2593 	int ver_major, ver_minor ;
2594 
2595 	sf_command (file, SFC_GET_LOG_INFO, log_buf, sizeof (log_buf)) ;
2596 	str = strstr (log_buf, str_libopus) ;
2597 	if (str)
2598 	{	str += strlen (str_libopus) ;
2599 		if ((p = strchr (str, '\n')))
2600 			*p = '\0' ;
2601 		if (sscanf (str, "libopus %d.%d", &ver_major, &ver_minor) == 2)
2602 		{	/* Reject versions prior to 1.3 */
2603 			if (ver_major > 1 || (ver_major == 1 && ver_minor >= 3))
2604 			{	/*
2605 				** Make sure that the libopus in use is not fixed-point, as it
2606 				** sacrifices accuracy. libopus API documentation explicitly
2607 				** allows checking for this suffix to determine if it is.
2608 				*/
2609 				if (!strstr (str, "-fixed"))
2610 					return 1 ;
2611 				} ;
2612 			} ;
2613 		} ;
2614 
2615 	printf ("skipping (%s)\n", str ? str : "unknown libopus version") ;
2616 	return 0 ;
2617 } /* check_opus_version */
2618