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