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