1 /*
2 ** Copyright (C) 1999-2012 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 #if HAVE_UNISTD_H
28 #include <unistd.h>
29 #else
30 #include "sf_unistd.h"
31 #endif
32 
33 #include <sndfile.h>
34 
35 #include "utils.h"
36 
37 #ifndef		M_PI
38 #define		M_PI	3.14159265358979323846264338
39 #endif
40 
41 #define	HALF_BUFFER_SIZE	(1 << 12)
42 #define	BUFFER_SIZE			(2 * HALF_BUFFER_SIZE)
43 
44 #define	SINE_AMP		1.1
45 #define	MAX_ERROR		0.0202
46 
47 
48 static void	flt_scale_clip_test_16 (const char *filename, int filetype, float maxval) ;
49 static void	flt_scale_clip_test_24 (const char *filename, int filetype, float maxval) ;
50 static void	flt_scale_clip_test_32 (const char *filename, int filetype, float maxval) ;
51 static void	flt_scale_clip_test_08 (const char *filename, int filetype, float maxval) ;
52 
53 static void	dbl_scale_clip_test_16 (const char *filename, int filetype, float maxval) ;
54 static void	dbl_scale_clip_test_24 (const char *filename, int filetype, float maxval) ;
55 static void	dbl_scale_clip_test_32 (const char *filename, int filetype, float maxval) ;
56 static void	dbl_scale_clip_test_08 (const char *filename, int filetype, float maxval) ;
57 
58 
59 
60 static void flt_short_clip_read_test (const char *filename, int filetype) ;
61 static void flt_int_clip_read_test (const char *filename, int filetype) ;
62 
63 static void dbl_short_clip_read_test (const char *filename, int filetype) ;
64 static void dbl_int_clip_read_test (const char *filename, int filetype) ;
65 
66 
67 
68 static void short_flt_scale_write_test (const char *filename, int filetype) ;
69 static void short_dbl_scale_write_test (const char *filename, int filetype) ;
70 
71 static void int_flt_scale_write_test (const char *filename, int filetype) ;
72 static void int_dbl_scale_write_test (const char *filename, int filetype) ;
73 
74 
75 typedef union
76 {	double	dbl [BUFFER_SIZE] ;
77 	float	flt [BUFFER_SIZE] ;
78 	int		i [BUFFER_SIZE] ;
79 	short	s [BUFFER_SIZE] ;
80 } BUFFER ;
81 
82 /* Data buffer. */
83 static	BUFFER	buffer_out ;
84 static	BUFFER	buffer_in ;
85 
86 int
main(void)87 main (void)
88 {
89 	flt_scale_clip_test_08 ("scale_clip_s8.au", SF_FORMAT_AU | SF_FORMAT_PCM_S8, 1.0 * 0x80) ;
90 	flt_scale_clip_test_08 ("scale_clip_u8.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 1.0 * 0x80) ;
91 
92 	dbl_scale_clip_test_08 ("scale_clip_s8.au", SF_FORMAT_AU | SF_FORMAT_PCM_S8, 1.0 * 0x80) ;
93 	dbl_scale_clip_test_08 ("scale_clip_u8.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 1.0 * 0x80) ;
94 
95 	/*
96 	**	Now use SF_FORMAT_AU where possible because it allows both
97 	**	big and little endian files.
98 	*/
99 
100 	flt_scale_clip_test_16 ("scale_clip_be16.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ;
101 	flt_scale_clip_test_16 ("scale_clip_le16.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ;
102 	flt_scale_clip_test_24 ("scale_clip_be24.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ;
103 	flt_scale_clip_test_24 ("scale_clip_le24.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ;
104 	flt_scale_clip_test_32 ("scale_clip_be32.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ;
105 	flt_scale_clip_test_32 ("scale_clip_le32.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ;
106 
107 	dbl_scale_clip_test_16 ("scale_clip_be16.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ;
108 	dbl_scale_clip_test_16 ("scale_clip_le16.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ;
109 	dbl_scale_clip_test_24 ("scale_clip_be24.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ;
110 	dbl_scale_clip_test_24 ("scale_clip_le24.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ;
111 	dbl_scale_clip_test_32 ("scale_clip_be32.au", SF_ENDIAN_BIG	| SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ;
112 	dbl_scale_clip_test_32 ("scale_clip_le32.au", SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ;
113 
114 	flt_short_clip_read_test	("flt_short.au"	, SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
115 	flt_int_clip_read_test		("flt_int.au"	, SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
116 	dbl_short_clip_read_test	("dbl_short.au"	, SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_DOUBLE) ;
117 	dbl_int_clip_read_test		("dbl_int.au"	, SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_DOUBLE) ;
118 
119 	short_flt_scale_write_test	("short_flt.au"	, SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
120 	int_flt_scale_write_test	("int_flt.au"	, SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
121 	short_dbl_scale_write_test	("short_dbl.au"	, SF_ENDIAN_BIG		| SF_FORMAT_AU | SF_FORMAT_DOUBLE) ;
122 	int_dbl_scale_write_test	("int_dbl.au"	, SF_ENDIAN_LITTLE	| SF_FORMAT_AU | SF_FORMAT_DOUBLE) ;
123 
124 	return 0 ;
125 } /* main */
126 
127 /*============================================================================================
128 **	Here are the test functions.
129 */
130 
131 
132 static void
flt_scale_clip_test_16(const char * filename,int filetype,float maxval)133 flt_scale_clip_test_16 (const char *filename, int filetype, float maxval)
134 {	SNDFILE		*file ;
135 	SF_INFO		sfinfo ;
136 	int			k ;
137 	float		*data_out, *data_in ;
138 	double		diff, clip_max_diff ;
139 
140 	print_test_name ("flt_scale_clip_test_16", filename) ;
141 
142 	data_out = buffer_out.flt ;
143 	data_in = buffer_in.flt ;
144 
145 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
146 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
147 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
148 		} ;
149 
150 	sfinfo.samplerate	= 44100 ;
151 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
152 	sfinfo.channels		= 1 ;
153 	sfinfo.format		= filetype ;
154 
155 	/*
156 	**	Write two versions of the data:
157 	**		normalized and clipped
158 	**		un-normalized and clipped.
159 	*/
160 
161 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
162 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
163 	test_write_float_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
164 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
165 	test_write_float_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
166 	sf_close (file) ;
167 
168 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
169 
170 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
171 
172 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
173 
174 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
175 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
176 		exit (1) ;
177 		} ;
178 
179 	if (sfinfo.frames != BUFFER_SIZE)
180 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
181 		exit (1) ;
182 		} ;
183 
184 	if (sfinfo.channels != 1)
185 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
186 		exit (1) ;
187 		} ;
188 
189 	check_log_buffer_or_die (file, __LINE__) ;
190 
191 	test_read_float_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
192 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
193 	test_read_float_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
194 	sf_close (file) ;
195 
196 	/* Check normalized version. */
197 	clip_max_diff = 0.0 ;
198 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
199 	{	if (fabs (data_in [k]) > 1.0)
200 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
201 			exit (1) ;
202 			} ;
203 
204 		if (data_out [k] * data_in [k] < 0.0)
205 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
206 			exit (1) ;
207 			} ;
208 
209 		if (fabs (data_out [k]) > 1.0)
210 			continue ;
211 
212 		diff = fabs (data_out [k] - data_in [k]) ;
213 		if (diff > clip_max_diff)
214 			clip_max_diff = diff ;
215 		} ;
216 
217 	if (clip_max_diff < 1e-20)
218 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
219 		exit (1) ;
220 		} ;
221 
222 	if (clip_max_diff > 1.0 / 0x8000)
223 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
224 		exit (1) ;
225 		} ;
226 
227 	/* Check the un-normalized data. */
228 	clip_max_diff = 0.0 ;
229 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
230 	{	if (fabs (data_in [k]) > maxval)
231 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
232 			exit (1) ;
233 			} ;
234 
235 		if (data_out [k] * data_in [k] < 0.0)
236 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
237 			exit (1) ;
238 			} ;
239 
240 		if (fabs (data_out [k]) > maxval)
241 			continue ;
242 
243 		diff = fabs (data_out [k] - data_in [k]) ;
244 		if (diff > clip_max_diff)
245 			clip_max_diff = diff ;
246 		} ;
247 
248 	if (clip_max_diff < 1e-20)
249 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
250 		exit (1) ;
251 		} ;
252 
253 	if (clip_max_diff > 1.0)
254 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
255 		exit (1) ;
256 		} ;
257 
258 	printf ("ok\n") ;
259 	unlink (filename) ;
260 } /* flt_scale_clip_test_16 */
261 
262 static void
flt_scale_clip_test_24(const char * filename,int filetype,float maxval)263 flt_scale_clip_test_24 (const char *filename, int filetype, float maxval)
264 {	SNDFILE		*file ;
265 	SF_INFO		sfinfo ;
266 	int			k ;
267 	float		*data_out, *data_in ;
268 	double		diff, clip_max_diff ;
269 
270 	print_test_name ("flt_scale_clip_test_24", filename) ;
271 
272 	data_out = buffer_out.flt ;
273 	data_in = buffer_in.flt ;
274 
275 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
276 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
277 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
278 		} ;
279 
280 	sfinfo.samplerate	= 44100 ;
281 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
282 	sfinfo.channels		= 1 ;
283 	sfinfo.format		= filetype ;
284 
285 	/*
286 	**	Write two versions of the data:
287 	**		normalized and clipped
288 	**		un-normalized and clipped.
289 	*/
290 
291 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
292 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
293 	test_write_float_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
294 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
295 	test_write_float_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
296 	sf_close (file) ;
297 
298 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
299 
300 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
301 
302 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
303 
304 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
305 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
306 		exit (1) ;
307 		} ;
308 
309 	if (sfinfo.frames != BUFFER_SIZE)
310 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
311 		exit (1) ;
312 		} ;
313 
314 	if (sfinfo.channels != 1)
315 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
316 		exit (1) ;
317 		} ;
318 
319 	check_log_buffer_or_die (file, __LINE__) ;
320 
321 	test_read_float_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
322 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
323 	test_read_float_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
324 	sf_close (file) ;
325 
326 	/* Check normalized version. */
327 	clip_max_diff = 0.0 ;
328 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
329 	{	if (fabs (data_in [k]) > 1.0)
330 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
331 			exit (1) ;
332 			} ;
333 
334 		if (data_out [k] * data_in [k] < 0.0)
335 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
336 			exit (1) ;
337 			} ;
338 
339 		if (fabs (data_out [k]) > 1.0)
340 			continue ;
341 
342 		diff = fabs (data_out [k] - data_in [k]) ;
343 		if (diff > clip_max_diff)
344 			clip_max_diff = diff ;
345 		} ;
346 
347 	if (clip_max_diff < 1e-20)
348 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
349 		exit (1) ;
350 		} ;
351 
352 	if (clip_max_diff > 1.0 / 0x800000)
353 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
354 		exit (1) ;
355 		} ;
356 
357 	/* Check the un-normalized data. */
358 	clip_max_diff = 0.0 ;
359 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
360 	{	if (fabs (data_in [k]) > maxval)
361 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
362 			exit (1) ;
363 			} ;
364 
365 		if (data_out [k] * data_in [k] < 0.0)
366 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
367 			exit (1) ;
368 			} ;
369 
370 		if (fabs (data_out [k]) > maxval)
371 			continue ;
372 
373 		diff = fabs (data_out [k] - data_in [k]) ;
374 		if (diff > clip_max_diff)
375 			clip_max_diff = diff ;
376 		} ;
377 
378 	if (clip_max_diff < 1e-20)
379 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
380 		exit (1) ;
381 		} ;
382 
383 	if (clip_max_diff > 1.0)
384 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
385 		exit (1) ;
386 		} ;
387 
388 	printf ("ok\n") ;
389 	unlink (filename) ;
390 } /* flt_scale_clip_test_24 */
391 
392 static void
flt_scale_clip_test_32(const char * filename,int filetype,float maxval)393 flt_scale_clip_test_32 (const char *filename, int filetype, float maxval)
394 {	SNDFILE		*file ;
395 	SF_INFO		sfinfo ;
396 	int			k ;
397 	float		*data_out, *data_in ;
398 	double		diff, clip_max_diff ;
399 
400 	print_test_name ("flt_scale_clip_test_32", filename) ;
401 
402 	data_out = buffer_out.flt ;
403 	data_in = buffer_in.flt ;
404 
405 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
406 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
407 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
408 		} ;
409 
410 	sfinfo.samplerate	= 44100 ;
411 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
412 	sfinfo.channels		= 1 ;
413 	sfinfo.format		= filetype ;
414 
415 	/*
416 	**	Write two versions of the data:
417 	**		normalized and clipped
418 	**		un-normalized and clipped.
419 	*/
420 
421 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
422 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
423 	test_write_float_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
424 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
425 	test_write_float_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
426 	sf_close (file) ;
427 
428 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
429 
430 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
431 
432 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
433 
434 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
435 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
436 		exit (1) ;
437 		} ;
438 
439 	if (sfinfo.frames != BUFFER_SIZE)
440 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
441 		exit (1) ;
442 		} ;
443 
444 	if (sfinfo.channels != 1)
445 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
446 		exit (1) ;
447 		} ;
448 
449 	check_log_buffer_or_die (file, __LINE__) ;
450 
451 	test_read_float_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
452 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
453 	test_read_float_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
454 	sf_close (file) ;
455 
456 	/* Check normalized version. */
457 	clip_max_diff = 0.0 ;
458 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
459 	{	if (fabs (data_in [k]) > 1.0)
460 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
461 			exit (1) ;
462 			} ;
463 
464 		if (data_out [k] * data_in [k] < 0.0)
465 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
466 			exit (1) ;
467 			} ;
468 
469 		if (fabs (data_out [k]) > 1.0)
470 			continue ;
471 
472 		diff = fabs (data_out [k] - data_in [k]) ;
473 		if (diff > clip_max_diff)
474 			clip_max_diff = diff ;
475 		} ;
476 
477 	if (clip_max_diff < 1e-20)
478 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
479 		exit (1) ;
480 		} ;
481 
482 	if (clip_max_diff > 1.0 / 0x80000000)
483 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
484 		exit (1) ;
485 		} ;
486 
487 	/* Check the un-normalized data. */
488 	clip_max_diff = 0.0 ;
489 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
490 	{	if (fabs (data_in [k]) > maxval)
491 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
492 			exit (1) ;
493 			} ;
494 
495 		if (data_out [k] * data_in [k] < 0.0)
496 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
497 			exit (1) ;
498 			} ;
499 
500 		if (fabs (data_out [k]) > maxval)
501 			continue ;
502 
503 		diff = fabs (data_out [k] - data_in [k]) ;
504 		if (diff > clip_max_diff)
505 			clip_max_diff = diff ;
506 		} ;
507 
508 	if (clip_max_diff < 1e-20)
509 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
510 		exit (1) ;
511 		} ;
512 
513 	if (clip_max_diff > 1.0)
514 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
515 		exit (1) ;
516 		} ;
517 
518 	printf ("ok\n") ;
519 	unlink (filename) ;
520 } /* flt_scale_clip_test_32 */
521 
522 static void
flt_scale_clip_test_08(const char * filename,int filetype,float maxval)523 flt_scale_clip_test_08 (const char *filename, int filetype, float maxval)
524 {	SNDFILE		*file ;
525 	SF_INFO		sfinfo ;
526 	int			k ;
527 	float		*data_out, *data_in ;
528 	double		diff, clip_max_diff ;
529 
530 	print_test_name ("flt_scale_clip_test_08", filename) ;
531 
532 	data_out = buffer_out.flt ;
533 	data_in = buffer_in.flt ;
534 
535 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
536 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
537 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
538 		} ;
539 
540 	sfinfo.samplerate	= 44100 ;
541 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
542 	sfinfo.channels		= 1 ;
543 	sfinfo.format		= filetype ;
544 
545 	/*
546 	**	Write two versions of the data:
547 	**		normalized and clipped
548 	**		un-normalized and clipped.
549 	*/
550 
551 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
552 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
553 	test_write_float_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
554 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
555 	test_write_float_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
556 	sf_close (file) ;
557 
558 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
559 
560 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
561 
562 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
563 
564 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
565 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
566 		exit (1) ;
567 		} ;
568 
569 	if (sfinfo.frames != BUFFER_SIZE)
570 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
571 		exit (1) ;
572 		} ;
573 
574 	if (sfinfo.channels != 1)
575 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
576 		exit (1) ;
577 		} ;
578 
579 	check_log_buffer_or_die (file, __LINE__) ;
580 
581 	test_read_float_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
582 	sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
583 	test_read_float_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
584 	sf_close (file) ;
585 
586 	/* Check normalized version. */
587 	clip_max_diff = 0.0 ;
588 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
589 	{	if (fabs (data_in [k]) > 1.0)
590 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
591 			exit (1) ;
592 			} ;
593 
594 		if (data_out [k] * data_in [k] < 0.0)
595 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
596 			exit (1) ;
597 			} ;
598 
599 		if (fabs (data_out [k]) > 1.0)
600 			continue ;
601 
602 		diff = fabs (data_out [k] - data_in [k]) ;
603 		if (diff > clip_max_diff)
604 			clip_max_diff = diff ;
605 		} ;
606 
607 	if (clip_max_diff < 1e-20)
608 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
609 		exit (1) ;
610 		} ;
611 
612 	if (clip_max_diff > 1.0 / 0x80)
613 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
614 		exit (1) ;
615 		} ;
616 
617 	/* Check the un-normalized data. */
618 	clip_max_diff = 0.0 ;
619 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
620 	{	if (fabs (data_in [k]) > maxval)
621 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
622 			exit (1) ;
623 			} ;
624 
625 		if (data_out [k] * data_in [k] < 0.0)
626 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
627 			exit (1) ;
628 			} ;
629 
630 		if (fabs (data_out [k]) > maxval)
631 			continue ;
632 
633 		diff = fabs (data_out [k] - data_in [k]) ;
634 		if (diff > clip_max_diff)
635 			clip_max_diff = diff ;
636 		} ;
637 
638 	if (clip_max_diff < 1e-20)
639 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
640 		exit (1) ;
641 		} ;
642 
643 	if (clip_max_diff > 1.0)
644 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
645 		exit (1) ;
646 		} ;
647 
648 	printf ("ok\n") ;
649 	unlink (filename) ;
650 } /* flt_scale_clip_test_08 */
651 
652 
653 
654 static void
dbl_scale_clip_test_16(const char * filename,int filetype,float maxval)655 dbl_scale_clip_test_16 (const char *filename, int filetype, float maxval)
656 {	SNDFILE		*file ;
657 	SF_INFO		sfinfo ;
658 	int			k ;
659 	double		*data_out, *data_in ;
660 	double		diff, clip_max_diff ;
661 
662 	print_test_name ("dbl_scale_clip_test_16", filename) ;
663 
664 	data_out = buffer_out.dbl ;
665 	data_in = buffer_in.dbl ;
666 
667 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
668 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
669 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
670 		} ;
671 
672 	sfinfo.samplerate	= 44100 ;
673 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
674 	sfinfo.channels		= 1 ;
675 	sfinfo.format		= filetype ;
676 
677 	/*
678 	**	Write two versions of the data:
679 	**		normalized and clipped
680 	**		un-normalized and clipped.
681 	*/
682 
683 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
684 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
685 	test_write_double_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
686 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
687 	test_write_double_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
688 	sf_close (file) ;
689 
690 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
691 
692 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
693 
694 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
695 
696 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
697 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
698 		exit (1) ;
699 		} ;
700 
701 	if (sfinfo.frames != BUFFER_SIZE)
702 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
703 		exit (1) ;
704 		} ;
705 
706 	if (sfinfo.channels != 1)
707 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
708 		exit (1) ;
709 		} ;
710 
711 	check_log_buffer_or_die (file, __LINE__) ;
712 
713 	test_read_double_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
714 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
715 	test_read_double_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
716 	sf_close (file) ;
717 
718 	/* Check normalized version. */
719 	clip_max_diff = 0.0 ;
720 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
721 	{	if (fabs (data_in [k]) > 1.0)
722 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
723 			exit (1) ;
724 			} ;
725 
726 		if (data_out [k] * data_in [k] < 0.0)
727 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
728 			exit (1) ;
729 			} ;
730 
731 		if (fabs (data_out [k]) > 1.0)
732 			continue ;
733 
734 		diff = fabs (data_out [k] - data_in [k]) ;
735 		if (diff > clip_max_diff)
736 			clip_max_diff = diff ;
737 		} ;
738 
739 	if (clip_max_diff < 1e-20)
740 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
741 		exit (1) ;
742 		} ;
743 
744 	if (clip_max_diff > 1.0 / 0x8000)
745 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
746 		exit (1) ;
747 		} ;
748 
749 	/* Check the un-normalized data. */
750 	clip_max_diff = 0.0 ;
751 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
752 	{	if (fabs (data_in [k]) > maxval)
753 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
754 			exit (1) ;
755 			} ;
756 
757 		if (data_out [k] * data_in [k] < 0.0)
758 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
759 			exit (1) ;
760 			} ;
761 
762 		if (fabs (data_out [k]) > maxval)
763 			continue ;
764 
765 		diff = fabs (data_out [k] - data_in [k]) ;
766 		if (diff > clip_max_diff)
767 			clip_max_diff = diff ;
768 		} ;
769 
770 	if (clip_max_diff < 1e-20)
771 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
772 		exit (1) ;
773 		} ;
774 
775 	if (clip_max_diff > 1.0)
776 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
777 		exit (1) ;
778 		} ;
779 
780 	printf ("ok\n") ;
781 	unlink (filename) ;
782 } /* dbl_scale_clip_test_16 */
783 
784 static void
dbl_scale_clip_test_24(const char * filename,int filetype,float maxval)785 dbl_scale_clip_test_24 (const char *filename, int filetype, float maxval)
786 {	SNDFILE		*file ;
787 	SF_INFO		sfinfo ;
788 	int			k ;
789 	double		*data_out, *data_in ;
790 	double		diff, clip_max_diff ;
791 
792 	print_test_name ("dbl_scale_clip_test_24", filename) ;
793 
794 	data_out = buffer_out.dbl ;
795 	data_in = buffer_in.dbl ;
796 
797 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
798 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
799 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
800 		} ;
801 
802 	sfinfo.samplerate	= 44100 ;
803 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
804 	sfinfo.channels		= 1 ;
805 	sfinfo.format		= filetype ;
806 
807 	/*
808 	**	Write two versions of the data:
809 	**		normalized and clipped
810 	**		un-normalized and clipped.
811 	*/
812 
813 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
814 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
815 	test_write_double_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
816 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
817 	test_write_double_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
818 	sf_close (file) ;
819 
820 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
821 
822 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
823 
824 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
825 
826 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
827 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
828 		exit (1) ;
829 		} ;
830 
831 	if (sfinfo.frames != BUFFER_SIZE)
832 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
833 		exit (1) ;
834 		} ;
835 
836 	if (sfinfo.channels != 1)
837 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
838 		exit (1) ;
839 		} ;
840 
841 	check_log_buffer_or_die (file, __LINE__) ;
842 
843 	test_read_double_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
844 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
845 	test_read_double_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
846 	sf_close (file) ;
847 
848 	/* Check normalized version. */
849 	clip_max_diff = 0.0 ;
850 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
851 	{	if (fabs (data_in [k]) > 1.0)
852 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
853 			exit (1) ;
854 			} ;
855 
856 		if (data_out [k] * data_in [k] < 0.0)
857 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
858 			exit (1) ;
859 			} ;
860 
861 		if (fabs (data_out [k]) > 1.0)
862 			continue ;
863 
864 		diff = fabs (data_out [k] - data_in [k]) ;
865 		if (diff > clip_max_diff)
866 			clip_max_diff = diff ;
867 		} ;
868 
869 	if (clip_max_diff < 1e-20)
870 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
871 		exit (1) ;
872 		} ;
873 
874 	if (clip_max_diff > 1.0 / 0x800000)
875 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
876 		exit (1) ;
877 		} ;
878 
879 	/* Check the un-normalized data. */
880 	clip_max_diff = 0.0 ;
881 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
882 	{	if (fabs (data_in [k]) > maxval)
883 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
884 			exit (1) ;
885 			} ;
886 
887 		if (data_out [k] * data_in [k] < 0.0)
888 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
889 			exit (1) ;
890 			} ;
891 
892 		if (fabs (data_out [k]) > maxval)
893 			continue ;
894 
895 		diff = fabs (data_out [k] - data_in [k]) ;
896 		if (diff > clip_max_diff)
897 			clip_max_diff = diff ;
898 		} ;
899 
900 	if (clip_max_diff < 1e-20)
901 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
902 		exit (1) ;
903 		} ;
904 
905 	if (clip_max_diff > 1.0)
906 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
907 		exit (1) ;
908 		} ;
909 
910 	printf ("ok\n") ;
911 	unlink (filename) ;
912 } /* dbl_scale_clip_test_24 */
913 
914 static void
dbl_scale_clip_test_32(const char * filename,int filetype,float maxval)915 dbl_scale_clip_test_32 (const char *filename, int filetype, float maxval)
916 {	SNDFILE		*file ;
917 	SF_INFO		sfinfo ;
918 	int			k ;
919 	double		*data_out, *data_in ;
920 	double		diff, clip_max_diff ;
921 
922 	print_test_name ("dbl_scale_clip_test_32", filename) ;
923 
924 	data_out = buffer_out.dbl ;
925 	data_in = buffer_in.dbl ;
926 
927 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
928 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
929 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
930 		} ;
931 
932 	sfinfo.samplerate	= 44100 ;
933 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
934 	sfinfo.channels		= 1 ;
935 	sfinfo.format		= filetype ;
936 
937 	/*
938 	**	Write two versions of the data:
939 	**		normalized and clipped
940 	**		un-normalized and clipped.
941 	*/
942 
943 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
944 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
945 	test_write_double_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
946 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
947 	test_write_double_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
948 	sf_close (file) ;
949 
950 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
951 
952 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
953 
954 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
955 
956 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
957 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
958 		exit (1) ;
959 		} ;
960 
961 	if (sfinfo.frames != BUFFER_SIZE)
962 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
963 		exit (1) ;
964 		} ;
965 
966 	if (sfinfo.channels != 1)
967 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
968 		exit (1) ;
969 		} ;
970 
971 	check_log_buffer_or_die (file, __LINE__) ;
972 
973 	test_read_double_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
974 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
975 	test_read_double_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
976 	sf_close (file) ;
977 
978 	/* Check normalized version. */
979 	clip_max_diff = 0.0 ;
980 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
981 	{	if (fabs (data_in [k]) > 1.0)
982 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
983 			exit (1) ;
984 			} ;
985 
986 		if (data_out [k] * data_in [k] < 0.0)
987 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
988 			exit (1) ;
989 			} ;
990 
991 		if (fabs (data_out [k]) > 1.0)
992 			continue ;
993 
994 		diff = fabs (data_out [k] - data_in [k]) ;
995 		if (diff > clip_max_diff)
996 			clip_max_diff = diff ;
997 		} ;
998 
999 	if (clip_max_diff < 1e-20)
1000 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
1001 		exit (1) ;
1002 		} ;
1003 
1004 	if (clip_max_diff > 1.0 / 0x80000000)
1005 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
1006 		exit (1) ;
1007 		} ;
1008 
1009 	/* Check the un-normalized data. */
1010 	clip_max_diff = 0.0 ;
1011 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
1012 	{	if (fabs (data_in [k]) > maxval)
1013 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
1014 			exit (1) ;
1015 			} ;
1016 
1017 		if (data_out [k] * data_in [k] < 0.0)
1018 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
1019 			exit (1) ;
1020 			} ;
1021 
1022 		if (fabs (data_out [k]) > maxval)
1023 			continue ;
1024 
1025 		diff = fabs (data_out [k] - data_in [k]) ;
1026 		if (diff > clip_max_diff)
1027 			clip_max_diff = diff ;
1028 		} ;
1029 
1030 	if (clip_max_diff < 1e-20)
1031 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
1032 		exit (1) ;
1033 		} ;
1034 
1035 	if (clip_max_diff > 1.0)
1036 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
1037 		exit (1) ;
1038 		} ;
1039 
1040 	printf ("ok\n") ;
1041 	unlink (filename) ;
1042 } /* dbl_scale_clip_test_32 */
1043 
1044 static void
dbl_scale_clip_test_08(const char * filename,int filetype,float maxval)1045 dbl_scale_clip_test_08 (const char *filename, int filetype, float maxval)
1046 {	SNDFILE		*file ;
1047 	SF_INFO		sfinfo ;
1048 	int			k ;
1049 	double		*data_out, *data_in ;
1050 	double		diff, clip_max_diff ;
1051 
1052 	print_test_name ("dbl_scale_clip_test_08", filename) ;
1053 
1054 	data_out = buffer_out.dbl ;
1055 	data_in = buffer_in.dbl ;
1056 
1057 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
1058 	{	data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ;
1059 		data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ;
1060 		} ;
1061 
1062 	sfinfo.samplerate	= 44100 ;
1063 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1064 	sfinfo.channels		= 1 ;
1065 	sfinfo.format		= filetype ;
1066 
1067 	/*
1068 	**	Write two versions of the data:
1069 	**		normalized and clipped
1070 	**		un-normalized and clipped.
1071 	*/
1072 
1073 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1074 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
1075 	test_write_double_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ;
1076 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1077 	test_write_double_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
1078 	sf_close (file) ;
1079 
1080 	memset (&buffer_in, 0, sizeof (buffer_in)) ;
1081 
1082 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1083 
1084 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1085 
1086 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1087 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1088 		exit (1) ;
1089 		} ;
1090 
1091 	if (sfinfo.frames != BUFFER_SIZE)
1092 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
1093 		exit (1) ;
1094 		} ;
1095 
1096 	if (sfinfo.channels != 1)
1097 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1098 		exit (1) ;
1099 		} ;
1100 
1101 	check_log_buffer_or_die (file, __LINE__) ;
1102 
1103 	test_read_double_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ;
1104 	sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1105 	test_read_double_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ;
1106 	sf_close (file) ;
1107 
1108 	/* Check normalized version. */
1109 	clip_max_diff = 0.0 ;
1110 	for (k = 0 ; k < HALF_BUFFER_SIZE ; k++)
1111 	{	if (fabs (data_in [k]) > 1.0)
1112 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
1113 			exit (1) ;
1114 			} ;
1115 
1116 		if (data_out [k] * data_in [k] < 0.0)
1117 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
1118 			exit (1) ;
1119 			} ;
1120 
1121 		if (fabs (data_out [k]) > 1.0)
1122 			continue ;
1123 
1124 		diff = fabs (data_out [k] - data_in [k]) ;
1125 		if (diff > clip_max_diff)
1126 			clip_max_diff = diff ;
1127 		} ;
1128 
1129 	if (clip_max_diff < 1e-20)
1130 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ;
1131 		exit (1) ;
1132 		} ;
1133 
1134 	if (clip_max_diff > 1.0 / 0x80)
1135 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ;
1136 		exit (1) ;
1137 		} ;
1138 
1139 	/* Check the un-normalized data. */
1140 	clip_max_diff = 0.0 ;
1141 	for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++)
1142 	{	if (fabs (data_in [k]) > maxval)
1143 		{	printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ;
1144 			exit (1) ;
1145 			} ;
1146 
1147 		if (data_out [k] * data_in [k] < 0.0)
1148 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ;
1149 			exit (1) ;
1150 			} ;
1151 
1152 		if (fabs (data_out [k]) > maxval)
1153 			continue ;
1154 
1155 		diff = fabs (data_out [k] - data_in [k]) ;
1156 		if (diff > clip_max_diff)
1157 			clip_max_diff = diff ;
1158 		} ;
1159 
1160 	if (clip_max_diff < 1e-20)
1161 	{	printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ;
1162 		exit (1) ;
1163 		} ;
1164 
1165 	if (clip_max_diff > 1.0)
1166 	{	printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ;
1167 		exit (1) ;
1168 		} ;
1169 
1170 	printf ("ok\n") ;
1171 	unlink (filename) ;
1172 } /* dbl_scale_clip_test_08 */
1173 
1174 
1175 
1176 
1177 /*==============================================================================
1178 */
1179 
1180 
flt_short_clip_read_test(const char * filename,int filetype)1181 static void flt_short_clip_read_test (const char *filename, int filetype)
1182 {	SNDFILE		*file ;
1183 	SF_INFO		sfinfo ;
1184 	float		*data_out ;
1185 	short			*data_in, max_value ;
1186 	int			k ;
1187 
1188 	print_test_name ("flt_short_clip_read_test", filename) ;
1189 
1190 	data_out = buffer_out.flt ;
1191 	data_in = buffer_in.s ;
1192 
1193 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1194 		data_out [k] = 0.995 * sin (4 * M_PI * k / BUFFER_SIZE) ;
1195 	data_out [BUFFER_SIZE / 8] = 1.0 ;
1196 	data_out [3 * BUFFER_SIZE / 8] = -1.000000001 ;
1197 	data_out [5 * BUFFER_SIZE / 8] = 1.0 ;
1198 	data_out [7 * BUFFER_SIZE / 8] = -1.000000001 ;
1199 
1200 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1201 	sfinfo.samplerate	= 44100 ;
1202 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1203 	sfinfo.channels		= 1 ;
1204 	sfinfo.format		= filetype ;
1205 
1206 	/* Save unclipped data to the file. */
1207 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1208 	test_write_float_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1209 	sf_close (file) ;
1210 
1211 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1212 
1213 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1214 	sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ;
1215 
1216 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1217 
1218 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1219 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1220 		exit (1) ;
1221 		} ;
1222 
1223 	if (sfinfo.frames != BUFFER_SIZE)
1224 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
1225 		exit (1) ;
1226 		} ;
1227 
1228 	if (sfinfo.channels != 1)
1229 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1230 		exit (1) ;
1231 		} ;
1232 
1233 	check_log_buffer_or_die (file, __LINE__) ;
1234 
1235 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
1236 	test_read_short_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1237 	/*-sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;-*/
1238 	sf_close (file) ;
1239 
1240 	/* Check the first half. */
1241 	max_value = 0 ;
1242 	for (k = 0 ; k < sfinfo.frames ; k++)
1243 	{	/* Check if data_out has different sign from data_in. */
1244 		if ((data_out [k] < 0.0 && data_in [k] > 0) || (data_out [k] > 0.0 && data_in [k] < 0))
1245 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d  (%f -> %d).\n\n", __LINE__, k, BUFFER_SIZE, data_out [k], data_in [k]) ;
1246 			exit (1) ;
1247 			} ;
1248 		max_value = (max_value > abs (data_in [k])) ? max_value : abs (data_in [k]) ;
1249 		} ;
1250 
1251 	unlink (filename) ;
1252 	puts ("ok") ;
1253 } /* flt_short_clip_read_test */
flt_int_clip_read_test(const char * filename,int filetype)1254 static void flt_int_clip_read_test (const char *filename, int filetype)
1255 {	SNDFILE		*file ;
1256 	SF_INFO		sfinfo ;
1257 	float		*data_out ;
1258 	int			*data_in, max_value ;
1259 	int			k ;
1260 
1261 	print_test_name ("flt_int_clip_read_test", filename) ;
1262 
1263 	data_out = buffer_out.flt ;
1264 	data_in = buffer_in.i ;
1265 
1266 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1267 		data_out [k] = 0.995 * sin (4 * M_PI * k / BUFFER_SIZE) ;
1268 	data_out [BUFFER_SIZE / 8] = 1.0 ;
1269 	data_out [3 * BUFFER_SIZE / 8] = -1.000000001 ;
1270 	data_out [5 * BUFFER_SIZE / 8] = 1.0 ;
1271 	data_out [7 * BUFFER_SIZE / 8] = -1.000000001 ;
1272 
1273 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1274 	sfinfo.samplerate	= 44100 ;
1275 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1276 	sfinfo.channels		= 1 ;
1277 	sfinfo.format		= filetype ;
1278 
1279 	/* Save unclipped data to the file. */
1280 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1281 	test_write_float_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1282 	sf_close (file) ;
1283 
1284 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1285 
1286 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1287 	sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ;
1288 
1289 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1290 
1291 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1292 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1293 		exit (1) ;
1294 		} ;
1295 
1296 	if (sfinfo.frames != BUFFER_SIZE)
1297 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
1298 		exit (1) ;
1299 		} ;
1300 
1301 	if (sfinfo.channels != 1)
1302 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1303 		exit (1) ;
1304 		} ;
1305 
1306 	check_log_buffer_or_die (file, __LINE__) ;
1307 
1308 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
1309 	test_read_int_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1310 	/*-sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;-*/
1311 	sf_close (file) ;
1312 
1313 	/* Check the first half. */
1314 	max_value = 0 ;
1315 	for (k = 0 ; k < sfinfo.frames ; k++)
1316 	{	/* Check if data_out has different sign from data_in. */
1317 		if ((data_out [k] < 0.0 && data_in [k] > 0) || (data_out [k] > 0.0 && data_in [k] < 0))
1318 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d  (%f -> %d).\n\n", __LINE__, k, BUFFER_SIZE, data_out [k], data_in [k]) ;
1319 			exit (1) ;
1320 			} ;
1321 		max_value = (max_value > abs (data_in [k])) ? max_value : abs (data_in [k]) ;
1322 		} ;
1323 
1324 	unlink (filename) ;
1325 	puts ("ok") ;
1326 } /* flt_int_clip_read_test */
1327 
dbl_short_clip_read_test(const char * filename,int filetype)1328 static void dbl_short_clip_read_test (const char *filename, int filetype)
1329 {	SNDFILE		*file ;
1330 	SF_INFO		sfinfo ;
1331 	double		*data_out ;
1332 	short			*data_in, max_value ;
1333 	int			k ;
1334 
1335 	print_test_name ("dbl_short_clip_read_test", filename) ;
1336 
1337 	data_out = buffer_out.dbl ;
1338 	data_in = buffer_in.s ;
1339 
1340 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1341 		data_out [k] = 0.995 * sin (4 * M_PI * k / BUFFER_SIZE) ;
1342 	data_out [BUFFER_SIZE / 8] = 1.0 ;
1343 	data_out [3 * BUFFER_SIZE / 8] = -1.000000001 ;
1344 	data_out [5 * BUFFER_SIZE / 8] = 1.0 ;
1345 	data_out [7 * BUFFER_SIZE / 8] = -1.000000001 ;
1346 
1347 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1348 	sfinfo.samplerate	= 44100 ;
1349 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1350 	sfinfo.channels		= 1 ;
1351 	sfinfo.format		= filetype ;
1352 
1353 	/* Save unclipped data to the file. */
1354 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1355 	test_write_double_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1356 	sf_close (file) ;
1357 
1358 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1359 
1360 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1361 	sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ;
1362 
1363 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1364 
1365 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1366 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1367 		exit (1) ;
1368 		} ;
1369 
1370 	if (sfinfo.frames != BUFFER_SIZE)
1371 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
1372 		exit (1) ;
1373 		} ;
1374 
1375 	if (sfinfo.channels != 1)
1376 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1377 		exit (1) ;
1378 		} ;
1379 
1380 	check_log_buffer_or_die (file, __LINE__) ;
1381 
1382 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
1383 	test_read_short_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1384 	/*-sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;-*/
1385 	sf_close (file) ;
1386 
1387 	/* Check the first half. */
1388 	max_value = 0 ;
1389 	for (k = 0 ; k < sfinfo.frames ; k++)
1390 	{	/* Check if data_out has different sign from data_in. */
1391 		if ((data_out [k] < 0.0 && data_in [k] > 0) || (data_out [k] > 0.0 && data_in [k] < 0))
1392 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d  (%f -> %d).\n\n", __LINE__, k, BUFFER_SIZE, data_out [k], data_in [k]) ;
1393 			exit (1) ;
1394 			} ;
1395 		max_value = (max_value > abs (data_in [k])) ? max_value : abs (data_in [k]) ;
1396 		} ;
1397 
1398 	unlink (filename) ;
1399 	puts ("ok") ;
1400 } /* dbl_short_clip_read_test */
dbl_int_clip_read_test(const char * filename,int filetype)1401 static void dbl_int_clip_read_test (const char *filename, int filetype)
1402 {	SNDFILE		*file ;
1403 	SF_INFO		sfinfo ;
1404 	double		*data_out ;
1405 	int			*data_in, max_value ;
1406 	int			k ;
1407 
1408 	print_test_name ("dbl_int_clip_read_test", filename) ;
1409 
1410 	data_out = buffer_out.dbl ;
1411 	data_in = buffer_in.i ;
1412 
1413 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1414 		data_out [k] = 0.995 * sin (4 * M_PI * k / BUFFER_SIZE) ;
1415 	data_out [BUFFER_SIZE / 8] = 1.0 ;
1416 	data_out [3 * BUFFER_SIZE / 8] = -1.000000001 ;
1417 	data_out [5 * BUFFER_SIZE / 8] = 1.0 ;
1418 	data_out [7 * BUFFER_SIZE / 8] = -1.000000001 ;
1419 
1420 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1421 	sfinfo.samplerate	= 44100 ;
1422 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1423 	sfinfo.channels		= 1 ;
1424 	sfinfo.format		= filetype ;
1425 
1426 	/* Save unclipped data to the file. */
1427 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1428 	test_write_double_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1429 	sf_close (file) ;
1430 
1431 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1432 
1433 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1434 	sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ;
1435 
1436 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1437 
1438 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1439 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1440 		exit (1) ;
1441 		} ;
1442 
1443 	if (sfinfo.frames != BUFFER_SIZE)
1444 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ;
1445 		exit (1) ;
1446 		} ;
1447 
1448 	if (sfinfo.channels != 1)
1449 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1450 		exit (1) ;
1451 		} ;
1452 
1453 	check_log_buffer_or_die (file, __LINE__) ;
1454 
1455 	sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
1456 	test_read_int_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1457 	/*-sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;-*/
1458 	sf_close (file) ;
1459 
1460 	/* Check the first half. */
1461 	max_value = 0 ;
1462 	for (k = 0 ; k < sfinfo.frames ; k++)
1463 	{	/* Check if data_out has different sign from data_in. */
1464 		if ((data_out [k] < 0.0 && data_in [k] > 0) || (data_out [k] > 0.0 && data_in [k] < 0))
1465 		{	printf ("\n\nLine %d: Data wrap around at index %d/%d  (%f -> %d).\n\n", __LINE__, k, BUFFER_SIZE, data_out [k], data_in [k]) ;
1466 			exit (1) ;
1467 			} ;
1468 		max_value = (max_value > abs (data_in [k])) ? max_value : abs (data_in [k]) ;
1469 		} ;
1470 
1471 	unlink (filename) ;
1472 	puts ("ok") ;
1473 } /* dbl_int_clip_read_test */
1474 
1475 
1476 /*==============================================================================
1477 */
1478 
1479 
short_flt_scale_write_test(const char * filename,int filetype)1480 static void short_flt_scale_write_test (const char *filename, int filetype)
1481 {	SNDFILE		*file ;
1482 	SF_INFO		sfinfo ;
1483 	short		*data_out ;
1484 	float	*data_in, max_value ;
1485 	int			k ;
1486 
1487 	print_test_name ("short_flt_clip_write_test", filename) ;
1488 
1489 	data_out = buffer_out.s ;
1490 	data_in = buffer_in.flt ;
1491 
1492 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1493 		data_out [k] = lrintf (0x7FFFF * 0.995 * sin (4 * M_PI * k / BUFFER_SIZE)) ;
1494 
1495 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1496 	sfinfo.samplerate	= 44100 ;
1497 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1498 	sfinfo.channels		= 1 ;
1499 	sfinfo.format		= filetype ;
1500 
1501 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1502 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1503 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE) ;
1504 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1505 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_FALSE) ;
1506 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1507 	sf_close (file) ;
1508 
1509 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1510 
1511 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1512 
1513 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1514 
1515 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1516 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1517 		exit (1) ;
1518 		} ;
1519 
1520 	if (sfinfo.frames != 3 * BUFFER_SIZE)
1521 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, 3 * BUFFER_SIZE, sfinfo.frames) ;
1522 		exit (1) ;
1523 		} ;
1524 
1525 	if (sfinfo.channels != 1)
1526 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1527 		exit (1) ;
1528 		} ;
1529 
1530 	check_log_buffer_or_die (file, __LINE__) ;
1531 
1532 	/* Check the first section. */
1533 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1534 
1535 	max_value = 0.0 ;
1536 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1537 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1538 
1539 	if (max_value < 1000.0)
1540 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1541 		exit (1) ;
1542 		} ;
1543 
1544 	/* Check the second section. */
1545 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1546 
1547 	max_value = 0.0 ;
1548 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1549 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1550 
1551 	if (max_value > 1.0)
1552 	{	printf ("\n\nLine %d: Max value (%f) > 1.0.\n\n", __LINE__, max_value) ;
1553 		exit (1) ;
1554 		} ;
1555 
1556 	/* Check the third section. */
1557 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1558 
1559 	max_value = 0.0 ;
1560 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1561 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1562 
1563 	if (max_value < 1000.0)
1564 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1565 		exit (1) ;
1566 		} ;
1567 
1568 	sf_close (file) ;
1569 
1570 	unlink (filename) ;
1571 	puts ("ok") ;
1572 } /* short_flt_scale_write_test */
short_dbl_scale_write_test(const char * filename,int filetype)1573 static void short_dbl_scale_write_test (const char *filename, int filetype)
1574 {	SNDFILE		*file ;
1575 	SF_INFO		sfinfo ;
1576 	short		*data_out ;
1577 	double	*data_in, max_value ;
1578 	int			k ;
1579 
1580 	print_test_name ("short_dbl_clip_write_test", filename) ;
1581 
1582 	data_out = buffer_out.s ;
1583 	data_in = buffer_in.dbl ;
1584 
1585 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1586 		data_out [k] = lrint (0x7FFFF * 0.995 * sin (4 * M_PI * k / BUFFER_SIZE)) ;
1587 
1588 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1589 	sfinfo.samplerate	= 44100 ;
1590 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1591 	sfinfo.channels		= 1 ;
1592 	sfinfo.format		= filetype ;
1593 
1594 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1595 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1596 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE) ;
1597 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1598 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_FALSE) ;
1599 	test_write_short_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1600 	sf_close (file) ;
1601 
1602 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1603 
1604 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1605 
1606 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1607 
1608 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1609 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1610 		exit (1) ;
1611 		} ;
1612 
1613 	if (sfinfo.frames != 3 * BUFFER_SIZE)
1614 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, 3 * BUFFER_SIZE, sfinfo.frames) ;
1615 		exit (1) ;
1616 		} ;
1617 
1618 	if (sfinfo.channels != 1)
1619 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1620 		exit (1) ;
1621 		} ;
1622 
1623 	check_log_buffer_or_die (file, __LINE__) ;
1624 
1625 	/* Check the first section. */
1626 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1627 
1628 	max_value = 0.0 ;
1629 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1630 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1631 
1632 	if (max_value < 1000.0)
1633 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1634 		exit (1) ;
1635 		} ;
1636 
1637 	/* Check the second section. */
1638 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1639 
1640 	max_value = 0.0 ;
1641 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1642 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1643 
1644 	if (max_value > 1.0)
1645 	{	printf ("\n\nLine %d: Max value (%f) > 1.0.\n\n", __LINE__, max_value) ;
1646 		exit (1) ;
1647 		} ;
1648 
1649 	/* Check the third section. */
1650 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1651 
1652 	max_value = 0.0 ;
1653 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1654 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1655 
1656 	if (max_value < 1000.0)
1657 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1658 		exit (1) ;
1659 		} ;
1660 
1661 	sf_close (file) ;
1662 
1663 	unlink (filename) ;
1664 	puts ("ok") ;
1665 } /* short_dbl_scale_write_test */
1666 
int_flt_scale_write_test(const char * filename,int filetype)1667 static void int_flt_scale_write_test (const char *filename, int filetype)
1668 {	SNDFILE		*file ;
1669 	SF_INFO		sfinfo ;
1670 	int		*data_out ;
1671 	float	*data_in, max_value ;
1672 	int			k ;
1673 
1674 	print_test_name ("int_flt_clip_write_test", filename) ;
1675 
1676 	data_out = buffer_out.i ;
1677 	data_in = buffer_in.flt ;
1678 
1679 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1680 		data_out [k] = lrintf (0x7FFFFFFF * 0.995 * sin (4 * M_PI * k / BUFFER_SIZE)) ;
1681 
1682 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1683 	sfinfo.samplerate	= 44100 ;
1684 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1685 	sfinfo.channels		= 1 ;
1686 	sfinfo.format		= filetype ;
1687 
1688 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1689 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1690 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE) ;
1691 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1692 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_FALSE) ;
1693 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1694 	sf_close (file) ;
1695 
1696 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1697 
1698 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1699 
1700 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1701 
1702 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1703 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1704 		exit (1) ;
1705 		} ;
1706 
1707 	if (sfinfo.frames != 3 * BUFFER_SIZE)
1708 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, 3 * BUFFER_SIZE, sfinfo.frames) ;
1709 		exit (1) ;
1710 		} ;
1711 
1712 	if (sfinfo.channels != 1)
1713 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1714 		exit (1) ;
1715 		} ;
1716 
1717 	check_log_buffer_or_die (file, __LINE__) ;
1718 
1719 	/* Check the first section. */
1720 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1721 
1722 	max_value = 0.0 ;
1723 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1724 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1725 
1726 	if (max_value < 1000.0)
1727 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1728 		exit (1) ;
1729 		} ;
1730 
1731 	/* Check the second section. */
1732 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1733 
1734 	max_value = 0.0 ;
1735 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1736 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1737 
1738 	if (max_value > 1.0)
1739 	{	printf ("\n\nLine %d: Max value (%f) > 1.0.\n\n", __LINE__, max_value) ;
1740 		exit (1) ;
1741 		} ;
1742 
1743 	/* Check the third section. */
1744 	test_read_float_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1745 
1746 	max_value = 0.0 ;
1747 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1748 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1749 
1750 	if (max_value < 1000.0)
1751 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1752 		exit (1) ;
1753 		} ;
1754 
1755 	sf_close (file) ;
1756 
1757 	unlink (filename) ;
1758 	puts ("ok") ;
1759 } /* int_flt_scale_write_test */
int_dbl_scale_write_test(const char * filename,int filetype)1760 static void int_dbl_scale_write_test (const char *filename, int filetype)
1761 {	SNDFILE		*file ;
1762 	SF_INFO		sfinfo ;
1763 	int		*data_out ;
1764 	double	*data_in, max_value ;
1765 	int			k ;
1766 
1767 	print_test_name ("int_dbl_clip_write_test", filename) ;
1768 
1769 	data_out = buffer_out.i ;
1770 	data_in = buffer_in.dbl ;
1771 
1772 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1773 		data_out [k] = lrint (0x7FFFFFFF * 0.995 * sin (4 * M_PI * k / BUFFER_SIZE)) ;
1774 
1775 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1776 	sfinfo.samplerate	= 44100 ;
1777 	sfinfo.frames		= 123456789 ; /* Wrong length. Library should correct this on sf_close. */
1778 	sfinfo.channels		= 1 ;
1779 	sfinfo.format		= filetype ;
1780 
1781 	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1782 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1783 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE) ;
1784 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1785 	sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_FALSE) ;
1786 	test_write_int_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ;
1787 	sf_close (file) ;
1788 
1789 	memset (&sfinfo, 0, sizeof (sfinfo)) ;
1790 
1791 	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
1792 
1793 	sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ;
1794 
1795 	if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
1796 	{	printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ;
1797 		exit (1) ;
1798 		} ;
1799 
1800 	if (sfinfo.frames != 3 * BUFFER_SIZE)
1801 	{	printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, 3 * BUFFER_SIZE, sfinfo.frames) ;
1802 		exit (1) ;
1803 		} ;
1804 
1805 	if (sfinfo.channels != 1)
1806 	{	printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ;
1807 		exit (1) ;
1808 		} ;
1809 
1810 	check_log_buffer_or_die (file, __LINE__) ;
1811 
1812 	/* Check the first section. */
1813 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1814 
1815 	max_value = 0.0 ;
1816 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1817 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1818 
1819 	if (max_value < 1000.0)
1820 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1821 		exit (1) ;
1822 		} ;
1823 
1824 	/* Check the second section. */
1825 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1826 
1827 	max_value = 0.0 ;
1828 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1829 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1830 
1831 	if (max_value > 1.0)
1832 	{	printf ("\n\nLine %d: Max value (%f) > 1.0.\n\n", __LINE__, max_value) ;
1833 		exit (1) ;
1834 		} ;
1835 
1836 	/* Check the third section. */
1837 	test_read_double_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ;
1838 
1839 	max_value = 0.0 ;
1840 	for (k = 0 ; k < BUFFER_SIZE ; k++)
1841 		max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ;
1842 
1843 	if (max_value < 1000.0)
1844 	{	printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ;
1845 		exit (1) ;
1846 		} ;
1847 
1848 	sf_close (file) ;
1849 
1850 	unlink (filename) ;
1851 	puts ("ok") ;
1852 } /* int_dbl_scale_write_test */
1853 
1854 
1855 
1856