2 ** Copyright (C) 1999-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
31 #include "sf_unistd.h"
38 #define BUFFER_SIZE (1 << 14)
39 #define SAMPLE_RATE 11025
42 #define M_PI 3.14159265358979323846264338
45 #define LCT_MAX(x, y) ((x) > (y) ? (x) : (y))
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) ;
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) ;
57 static void read_raw_test (const char *filename, int filetype, int chan) ;
59 static int error_function (double data, double orig, double margin) ;
60 static int decay_response (int k) ;
62 static void gen_signal_double (double *data, double scale, int channels, int datalen) ;
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) ;
69 static void check_comment (SNDFILE * file, int format, int lineno) ;
71 static int is_lossy (int filetype) ;
73 static int check_opus_version (SNDFILE *file) ;
76 ** Force the start of these buffers to be double aligned. Sparc-solaris will
77 ** choke if they are not.
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] ;
87 static BUFFER data_buffer ;
88 static BUFFER orig_buffer ;
89 static BUFFER smooth_buffer ;
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." ;
99 main (int argc, char *argv [])
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") ;
116 do_all = ! strcmp (argv [1], "all") ;
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 */
129 read_raw_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 2) ;
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
182 /* Lite remove end */
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) ;
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) ;
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 */
196 read_raw_test ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2) ;
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 */
208 read_raw_test ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2) ;
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) ;
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) ;
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 */
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
261 /* Lite remove end */
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 */
271 read_raw_test ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2) ;
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 */
283 read_raw_test ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2) ;
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 */
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 */
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 */
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 */
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) ;
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) ;
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) ;
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) ;
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) ;
362 /* Lite remove end */
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 */
372 read_raw_test ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2) ;
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 */
384 read_raw_test ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2) ;
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 */
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 */
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
452 /* Lite remove end */
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) ;
463 puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
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) ;
477 puts (" No Ogg/Opus tests because Ogg/Opus support was not compiled in.") ;
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) ;
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) ;
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) ;
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) ;
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) ;
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) ;
530 /* Lite remove end */
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 */
540 read_raw_test ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2) ;
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 */
552 read_raw_test ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2) ;
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) ;
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) ;
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) ;
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) ;
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 */
593 /* Lite remove end */
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 */
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) ;
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) ;
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) ;
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) ;
630 /* Lite remove end */
633 { printf ("************************************\n") ;
634 printf ("* No '%s' test defined.\n", argv [1]) ;
635 printf ("************************************\n") ;
642 /*============================================================================================
643 ** Here are the test functions.
647 lcomp_test_short (const char *filename, int filetype, int channels, double margin)
650 int k, m, seekpos, half_max_abs ;
654 print_test_name ("lcomp_test_short", filename) ;
656 datalen = BUFFER_SIZE / channels ;
658 data = data_buffer.s ;
659 orig = orig_buffer.s ;
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]) ;
665 sfinfo.samplerate = SAMPLE_RATE ;
666 sfinfo.frames = 123456789 ; /* Ridiculous value. */
667 sfinfo.channels = channels ;
668 sfinfo.format = filetype ;
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) ;
675 memset (data, 0, datalen * sizeof (short)) ;
677 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
678 memset (&sfinfo, 0, sizeof (sfinfo)) ;
680 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
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) ;
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) ;
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) ;
697 if (sfinfo.channels != channels)
698 { printf ("Incorrect number of channels in file.\n") ;
702 check_log_buffer_or_die (file, __LINE__) ;
704 check_comment (file, filetype, __LINE__) ;
706 test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
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) ;
715 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
718 if (half_max_abs < 1.0)
719 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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.
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)) ;
738 if (! sfinfo.seekable)
745 /* Now test sf_seek function. */
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) ;
752 for (m = 0 ; m < 3 ; m++)
753 { test_readf_short_or_die (file, m, data, 11, __LINE__) ;
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]) ;
765 seekpos = BUFFER_SIZE / 10 ;
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) ;
773 test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
803 /* Check that read past end of file returns number of items. */
804 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
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) ;
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]) ;
827 } /* lcomp_test_short */
829 /*--------------------------------------------------------------------------------------------
833 lcomp_test_int (const char *filename, int filetype, int channels, double margin)
836 int k, m, half_max_abs ;
837 sf_count_t datalen, seekpos ;
838 double scale, max_val ;
841 print_test_name ("lcomp_test_int", filename) ;
843 datalen = BUFFER_SIZE / channels ;
845 if (is_lossy (filetype))
846 { scale = 1.0 * 0x10000 ;
847 max_val = 32000.0 * scale ;
851 max_val = 0x7fffffff * scale ;
854 data = data_buffer.i ;
855 orig = orig_buffer.i ;
857 gen_signal_double (orig_buffer.d, max_val, channels, datalen) ;
859 for (k = 0 ; k < channels * datalen ; k++)
860 orig [k] = lrint (orig_buffer.d [k]) ;
862 sfinfo.samplerate = SAMPLE_RATE ;
863 sfinfo.frames = 123456789 ; /* Ridiculous value. */
864 sfinfo.channels = channels ;
865 sfinfo.format = filetype ;
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) ;
872 memset (data, 0, datalen * sizeof (int)) ;
874 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
875 memset (&sfinfo, 0, sizeof (sfinfo)) ;
877 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
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) ;
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) ;
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) ;
894 if (sfinfo.channels != channels)
895 { printf ("Incorrect number of channels in file.\n") ;
899 check_log_buffer_or_die (file, __LINE__) ;
901 check_comment (file, filetype, __LINE__) ;
903 test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
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) ;
912 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
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) ;
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) ;
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.
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)) ;
936 if (! sfinfo.seekable)
943 /* Now test sf_seek function. */
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) ;
950 for (m = 0 ; m < 3 ; m++)
951 { test_readf_int_or_die (file, m, data, 11, __LINE__) ;
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]) ;
963 seekpos = BUFFER_SIZE / 10 ;
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) ;
971 test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
1000 /* Check that read past end of file returns number of items. */
1001 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
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) ;
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]) ;
1024 } /* lcomp_test_int */
1026 /*--------------------------------------------------------------------------------------------
1030 lcomp_test_float (const char *filename, int filetype, int channels, double margin)
1034 sf_count_t datalen ;
1035 float *orig, *data ;
1036 double half_max_abs ;
1038 print_test_name ("lcomp_test_float", filename) ;
1040 datalen = BUFFER_SIZE / channels ;
1042 data = data_buffer.f ;
1043 orig = orig_buffer.f ;
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] ;
1049 sfinfo.samplerate = SAMPLE_RATE ;
1050 sfinfo.frames = 123456789 ; /* Ridiculous value. */
1051 sfinfo.channels = channels ;
1052 sfinfo.format = filetype ;
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) ;
1060 memset (data, 0, datalen * sizeof (float)) ;
1062 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1063 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1065 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
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) ;
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) ;
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) ;
1082 if (sfinfo.channels != channels)
1083 { printf ("Incorrect number of channels in file.\n") ;
1087 check_comment (file, filetype, __LINE__) ;
1089 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1091 check_log_buffer_or_die (file, __LINE__) ;
1093 check_comment (file, filetype, __LINE__) ;
1095 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1097 test_readf_float_or_die (file, 0, data, datalen, __LINE__) ;
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) ;
1106 half_max_abs = LCT_MAX (half_max_abs, fabs (0.5 * data [k])) ;
1109 if (half_max_abs < 1.0)
1110 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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.
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)) ;
1130 if (! sfinfo.seekable)
1137 /* Now test sf_seek function. */
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) ;
1144 for (m = 0 ; m < 3 ; m++)
1145 { test_readf_float_or_die (file, 0, data, 11, __LINE__) ;
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]) ;
1157 seekpos = BUFFER_SIZE / 10 ;
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) ;
1165 test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
1194 /* Check that read past end of file returns number of items. */
1195 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
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) ;
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]) ;
1218 } /* lcomp_test_float */
1220 /*--------------------------------------------------------------------------------------------
1224 lcomp_test_double (const char *filename, int filetype, int channels, double margin)
1228 sf_count_t datalen ;
1229 double *orig, *data ;
1230 double half_max_abs ;
1232 print_test_name ("lcomp_test_double", filename) ;
1234 datalen = BUFFER_SIZE / channels ;
1236 data = data_buffer.d ;
1237 orig = orig_buffer.d ;
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] ;
1243 sfinfo.samplerate = SAMPLE_RATE ;
1244 sfinfo.frames = 123456789 ; /* Ridiculous value. */
1245 sfinfo.channels = channels ;
1246 sfinfo.format = filetype ;
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) ;
1254 memset (data, 0, datalen * sizeof (double)) ;
1256 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1257 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1259 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
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) ;
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) ;
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) ;
1276 if (sfinfo.channels != channels)
1277 { printf ("Incorrect number of channels in file.\n") ;
1281 check_comment (file, filetype, __LINE__) ;
1283 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1285 check_log_buffer_or_die (file, __LINE__) ;
1287 check_comment (file, filetype, __LINE__) ;
1289 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
1291 test_readf_double_or_die (file, 0, data, datalen, __LINE__) ;
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) ;
1300 half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
1303 if (half_max_abs < 1.0)
1304 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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.
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)) ;
1324 if (! sfinfo.seekable)
1331 /* Now test sf_seek function. */
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) ;
1338 for (m = 0 ; m < 3 ; m++)
1339 { test_readf_double_or_die (file, m, data, 11, __LINE__) ;
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]) ;
1351 seekpos = BUFFER_SIZE / 10 ;
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) ;
1359 test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
1388 /* Check that read past end of file returns number of items. */
1389 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
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) ;
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]) ;
1412 } /* lcomp_test_double */
1414 /*========================================================================================
1415 ** Smoothed differential loss compression tests.
1419 sdlcomp_test_short (const char *filename, int filetype, int channels, double margin)
1422 int k, m, seekpos, half_max_abs ;
1423 sf_count_t datalen ;
1424 short *orig, *data, *smooth ;
1427 print_test_name ("sdlcomp_test_short", filename) ;
1429 datalen = BUFFER_SIZE ;
1431 orig = orig_buffer.s ;
1432 data = data_buffer.s ;
1433 smooth = smooth_buffer.s ;
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]) ;
1439 sfinfo.samplerate = SAMPLE_RATE ;
1440 sfinfo.frames = 123456789 ; /* Ridiculous value. */
1441 sfinfo.channels = channels ;
1442 sfinfo.format = filetype ;
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
1448 ** Opus only supports discrete sample rates. Choose supported 12000.
1450 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1451 { const char * errstr ;
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 ;
1458 else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1459 { printf ("\n Sample rate -> 12kHz ") ;
1460 sfinfo.samplerate = 12000 ;
1463 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1464 dump_log_buffer (NULL) ;
1468 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1471 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
1476 test_write_short_or_die (file, 0, orig, datalen, __LINE__) ;
1477 sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1480 memset (data, 0, datalen * sizeof (short)) ;
1482 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1483 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1485 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1487 if (sfinfo.format != filetype)
1488 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
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) ;
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) ;
1502 if (sfinfo.channels != channels)
1503 { printf ("Incorrect number of channels in file.\n") ;
1507 check_comment (file, filetype, __LINE__) ;
1509 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1511 check_log_buffer_or_die (file, __LINE__) ;
1513 test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
1515 memcpy (smooth, orig, datalen * sizeof (short)) ;
1516 smoothed_diff_short (data, datalen) ;
1517 smoothed_diff_short (smooth, datalen) ;
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) ;
1526 half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
1529 if (half_max_abs < 1)
1530 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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)) ;
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) ;
1554 for (m = 0 ; m < 3 ; m++)
1555 { test_readf_short_or_die (file, m, data, datalen / 7, __LINE__) ;
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) ;
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]) ;
1569 } ; /* for (m = 0 ; m < 3 ; m++) */
1571 seekpos = BUFFER_SIZE / 10 ;
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) ;
1578 test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
1607 /* Check that read past end of file returns number of items. */
1608 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
1615 /* Check seek backward from end. */
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) ;
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]) ;
1627 } /* if (sfinfo.seekable) */
1633 } /* sdlcomp_test_short */
1636 sdlcomp_test_int (const char *filename, int filetype, int channels, double margin)
1639 int k, m, seekpos, half_max_abs ;
1640 sf_count_t datalen ;
1641 int *orig, *data, *smooth ;
1646 print_test_name ("sdlcomp_test_int", filename) ;
1648 datalen = BUFFER_SIZE ;
1649 scale = 1.0 * 0x10000 ;
1651 orig = orig_buffer.i ;
1652 data = data_buffer.i ;
1653 smooth = smooth_buffer.i ;
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]) ;
1659 sfinfo.samplerate = SAMPLE_RATE ;
1660 sfinfo.frames = 123456789 ; /* Ridiculous value. */
1661 sfinfo.channels = channels ;
1662 sfinfo.format = filetype ;
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
1668 ** Opus only supports discrete sample rates. Choose supported 12000.
1670 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1671 { const char * errstr ;
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 ;
1678 else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1679 { printf ("\n Sample rate -> 12kHz ") ;
1680 sfinfo.samplerate = 12000 ;
1683 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1684 dump_log_buffer (NULL) ;
1688 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1691 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
1696 test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ;
1697 sf_set_string (file, SF_STR_COMMENT, long_comment) ;
1700 memset (data, 0, datalen * sizeof (int)) ;
1702 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1703 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1705 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
1707 if (sfinfo.format != filetype)
1708 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
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) ;
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) ;
1722 if (sfinfo.channels != channels)
1723 { printf ("Incorrect number of channels in file.\n") ;
1727 check_log_buffer_or_die (file, __LINE__) ;
1729 test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
1731 memcpy (smooth, orig, datalen * sizeof (int)) ;
1732 smoothed_diff_int (data, datalen) ;
1733 smoothed_diff_int (smooth, datalen) ;
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) ;
1742 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
1745 if (half_max_abs < 1)
1746 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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)) ;
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) ;
1776 for (m = 0 ; m < 3 ; m++)
1777 { test_readf_int_or_die (file, m, data, datalen / 7, __LINE__) ;
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) ;
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]) ;
1791 } ; /* for (m = 0 ; m < 3 ; m++) */
1793 seekpos = BUFFER_SIZE / 10 ;
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) ;
1800 test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
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]) ;
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) ;
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) ;
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) ;
1829 /* Check that read past end of file returns number of items. */
1830 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
1837 /* Check seek backward from end. */
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) ;
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]) ;
1849 } /* if (sfinfo.seekable) */
1855 } /* sdlcomp_test_int */
1858 sdlcomp_test_float (const char *filename, int filetype, int channels, double margin)
1862 sf_count_t datalen ;
1863 float *orig, *data, *smooth ;
1864 double half_max_abs , scale ;
1868 print_test_name ("sdlcomp_test_float", filename) ;
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
1877 scale = 16.0 ; /* 32000/16 = 2000 */
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.
1885 scale = 32000.0 ; /* 32000/32000 = 1 */
1893 datalen = BUFFER_SIZE ;
1895 orig = orig_buffer.f ;
1896 data = data_buffer.f ;
1897 smooth = smooth_buffer.f ;
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] ;
1903 sfinfo.samplerate = SAMPLE_RATE ;
1904 sfinfo.frames = 123456789 ; /* Ridiculous value. */
1905 sfinfo.channels = channels ;
1906 sfinfo.format = filetype ;
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
1913 ** Opus only supports discrete sample rates. Choose supported 12000.
1915 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
1916 { const char * errstr ;
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 ;
1923 else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
1924 { printf ("\n Sample rate -> 12kHz ") ;
1925 sfinfo.samplerate = 12000 ;
1928 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
1929 dump_log_buffer (NULL) ;
1933 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
1936 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
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) ;
1946 memset (data, 0, datalen * sizeof (float)) ;
1948 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
1949 memset (&sfinfo, 0, sizeof (sfinfo)) ;
1951 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
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) ;
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) ;
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) ;
1968 if (sfinfo.channels != channels)
1969 { printf ("Incorrect number of channels in file.\n") ;
1973 check_comment (file, filetype, __LINE__) ;
1975 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
1977 check_log_buffer_or_die (file, __LINE__) ;
1979 test_read_float_or_die (file, 0, data, datalen, __LINE__) ;
1981 memcpy (smooth, orig, datalen * sizeof (float)) ;
1982 smoothed_diff_float (data, datalen) ;
1983 smoothed_diff_float (smooth, datalen) ;
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) ;
1992 half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k] * scale)) ;
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) ;
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) ;
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)) ;
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) ;
2021 for (m = 0 ; m < 3 ; m++)
2022 { test_read_float_or_die (file, 0, data, datalen / 7, __LINE__) ;
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) ;
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]) ;
2036 } ; /* for (m = 0 ; m < 3 ; m++) */
2038 seekpos = BUFFER_SIZE / 10 ;
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) ;
2045 test_read_float_or_die (file, 0, data, channels, __LINE__) ;
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)) ;
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) ;
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) ;
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) ;
2074 /* Check that read past end of file returns number of items. */
2075 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
2082 /* Check seek backward from end. */
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) ;
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) ;
2094 } /* if (sfinfo.seekable) */
2100 } /* sdlcomp_test_float */
2103 sdlcomp_test_double (const char *filename, int filetype, int channels, double margin)
2107 sf_count_t datalen ;
2108 double *orig, *data, *smooth, half_max_abs, scale ;
2111 print_test_name ("sdlcomp_test_double", filename) ;
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
2120 scale = 16.0 ; /* 32000/16 = 2000 */
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.
2128 scale = 32000.0 ; /* 32000/32000 = 1 */
2136 datalen = BUFFER_SIZE ;
2138 orig = orig_buffer.d ;
2139 data = data_buffer.d ;
2140 smooth = smooth_buffer.d ;
2142 gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, datalen) ;
2144 sfinfo.samplerate = SAMPLE_RATE ;
2145 sfinfo.frames = 123456789 ; /* Ridiculous value. */
2146 sfinfo.channels = channels ;
2147 sfinfo.format = filetype ;
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
2153 ** Opus only supports discrete sample rates. Choose supported 12000.
2155 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
2156 { const char * errstr ;
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 ;
2163 else if (strstr (errstr, "Opus only supports sample rates of") != NULL)
2164 { printf ("\n Sample rate -> 12kHz ") ;
2165 sfinfo.samplerate = 12000 ;
2168 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
2169 dump_log_buffer (NULL) ;
2173 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
2176 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
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) ;
2186 memset (data, 0, datalen * sizeof (double)) ;
2188 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2189 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2191 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
2193 if (sfinfo.format != filetype)
2194 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
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) ;
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) ;
2208 if (sfinfo.channels != channels)
2209 { printf ("Incorrect number of channels in file.\n") ;
2213 check_comment (file, filetype, __LINE__) ;
2215 check_comment (file, filetype, __LINE__) ;
2217 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
2219 check_log_buffer_or_die (file, __LINE__) ;
2221 test_read_double_or_die (file, 0, data, datalen, __LINE__) ;
2223 memcpy (smooth, orig, datalen * sizeof (double)) ;
2224 smoothed_diff_double (data, datalen) ;
2225 smoothed_diff_double (smooth, datalen) ;
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) ;
2234 half_max_abs = LCT_MAX (half_max_abs, 0.5 * fabs (data [k] * scale)) ;
2237 if (half_max_abs < 1.0)
2238 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
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) ;
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)) ;
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) ;
2262 for (m = 0 ; m < 3 ; m++)
2263 { test_read_double_or_die (file, m, data, datalen / 7, __LINE__) ;
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) ;
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]) ;
2277 } ; /* for (m = 0 ; m < 3 ; m++) */
2279 seekpos = BUFFER_SIZE / 10 ;
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) ;
2286 test_read_double_or_die (file, 0, data, channels, __LINE__) ;
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)) ;
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) ;
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) ;
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) ;
2315 /* Check that read past end of file returns number of items. */
2316 sf_seek (file, sfinfo.frames, SEEK_SET) ;
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) ;
2323 /* Check seek backward from end. */
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) ;
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) ;
2335 } /* if (sfinfo.seekable) */
2341 } /* sdlcomp_test_double */
2344 read_raw_test (const char *filename, int filetype, int channels)
2347 sf_count_t count, datalen ;
2348 short *orig, *data ;
2351 print_test_name ("read_raw_test", filename) ;
2353 datalen = ARRAY_LEN (orig_buffer.s) / 2 ;
2355 orig = orig_buffer.s ;
2356 data = data_buffer.s ;
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]) ;
2362 sfinfo.samplerate = SAMPLE_RATE ;
2363 sfinfo.frames = 123456789 ; /* Ridiculous value. */
2364 sfinfo.channels = channels ;
2365 sfinfo.format = filetype ;
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) ;
2372 memset (data, 0, datalen * sizeof (double)) ;
2374 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
2375 memset (&sfinfo, 0, sizeof (sfinfo)) ;
2377 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
2379 if (sfinfo.format != filetype)
2380 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
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) ;
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) ;
2394 if (sfinfo.channels != channels)
2395 { printf ("Incorrect number of channels in file.\n") ;
2399 check_comment (file, filetype, __LINE__) ;
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) ;
2411 } /* read_raw_test */
2413 /*========================================================================================
2414 ** Auxiliary functions
2417 #define SIGNAL_MAXVAL 30000.0
2418 #define DECAY_COUNT 1000
2421 decay_response (int k)
2423 return (int) (1.2 * SIGNAL_MAXVAL) ;
2424 if (k > DECAY_COUNT)
2426 return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ;
2427 } /* decay_response */
2430 gen_signal_double (double *data, double scale, int channels, int datalen)
2434 ramplen = DECAY_COUNT ;
2437 { for (k = 0 ; k < datalen ; k++)
2439 amp = scale * k / ((double) ramplen) ;
2440 else if (k > datalen - ramplen)
2441 amp = scale * (datalen - k) / ((double) ramplen) ;
2443 /*-printf ("%3d : %g\n", k, amp) ;-*/
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))) ;
2450 { for (k = 0 ; k < datalen ; k ++)
2452 amp = scale * k / ((double) ramplen) ;
2453 else if (k > datalen - ramplen)
2454 amp = scale * (datalen - k) / ((double) ramplen) ;
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))) ;
2464 } /* gen_signal_double */
2467 error_function (double data, double orig, double margin)
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 ;
2475 error = fabs (data - orig) / fabs (orig) ;
2478 { printf ("\n\nerror_function (data = %f, orig = %f, margin = %f) -> %f\n", data, orig, margin, error) ;
2482 } /* error_function */
2485 smoothed_diff_short (short *data, unsigned int datalen)
2487 double memory = 0.0 ;
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 ;
2494 data [datalen-1] = data [datalen-2] ;
2496 } /* smoothed_diff_short */
2499 smoothed_diff_int (int *data, unsigned int datalen)
2501 double memory = 0.0 ;
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 ;
2508 data [datalen-1] = data [datalen-2] ;
2510 } /* smoothed_diff_int */
2513 smoothed_diff_float (float *data, unsigned int datalen)
2515 float memory = 0.0 ;
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]) ;
2522 data [datalen-1] = data [datalen-2] ;
2524 } /* smoothed_diff_float */
2527 smoothed_diff_double (double *data, unsigned int datalen)
2529 double memory = 0.0 ;
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]) ;
2536 data [datalen-1] = data [datalen-2] ;
2538 } /* smoothed_diff_double */
2541 check_comment (SNDFILE * file, int format, int lineno)
2542 { const char *comment ;
2544 switch (format & SF_FORMAT_TYPEMASK)
2545 { case SF_FORMAT_AIFF :
2546 case SF_FORMAT_WAV :
2547 case SF_FORMAT_WAVEX :
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) ;
2559 if (strcmp (comment, long_comment) != 0)
2560 { printf ("\n\nLine %d : File comment does not match comment written.\n\n", lineno) ;
2565 } /* check_comment */
2568 is_lossy (int filetype)
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 :
2589 check_opus_version (SNDFILE *file)
2590 { char log_buf [256] ;
2592 const char *str_libopus = "Opus library version: " ;
2593 int ver_major, ver_minor ;
2595 sf_command (file, SFC_GET_LOG_INFO, log_buf, sizeof (log_buf)) ;
2596 str = strstr (log_buf, str_libopus) ;
2598 { str += strlen (str_libopus) ;
2599 if ((p = strchr (str, '\n')))
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))
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.
2609 if (!strstr (str, "-fixed"))
2615 printf ("skipping (%s)\n", str ? str : "unknown libopus version") ;
2617 } /* check_opus_version */