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