Chris@0
|
1 /*
|
Chris@0
|
2 ** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
Chris@0
|
3 **
|
Chris@0
|
4 ** This program is free software; you can redistribute it and/or modify
|
Chris@0
|
5 ** it under the terms of the GNU General Public License as published by
|
Chris@0
|
6 ** the Free Software Foundation; either version 2 of the License, or
|
Chris@0
|
7 ** (at your option) any later version.
|
Chris@0
|
8 **
|
Chris@0
|
9 ** This program is distributed in the hope that it will be useful,
|
Chris@0
|
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@0
|
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@0
|
12 ** GNU General Public License for more details.
|
Chris@0
|
13 **
|
Chris@0
|
14 ** You should have received a copy of the GNU General Public License
|
Chris@0
|
15 ** along with this program; if not, write to the Free Software
|
Chris@0
|
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Chris@0
|
17 */
|
Chris@0
|
18
|
Chris@0
|
19 #include "sfconfig.h"
|
Chris@0
|
20
|
Chris@0
|
21 #include <stdio.h>
|
Chris@0
|
22 #include <stdlib.h>
|
Chris@0
|
23 #include <string.h>
|
Chris@0
|
24 #include <unistd.h>
|
Chris@0
|
25
|
Chris@0
|
26 #include <math.h>
|
Chris@0
|
27
|
Chris@0
|
28 #include <sndfile.h>
|
Chris@0
|
29
|
Chris@0
|
30 #include "utils.h"
|
Chris@0
|
31
|
Chris@0
|
32 #define SAMPLE_RATE 44100
|
Chris@0
|
33 #define DATA_LENGTH (SAMPLE_RATE / 8)
|
Chris@0
|
34
|
Chris@0
|
35 typedef union
|
Chris@0
|
36 { double d [DATA_LENGTH] ;
|
Chris@0
|
37 float f [DATA_LENGTH] ;
|
Chris@0
|
38 int i [DATA_LENGTH] ;
|
Chris@0
|
39 short s [DATA_LENGTH] ;
|
Chris@0
|
40 } BUFFER ;
|
Chris@0
|
41
|
Chris@0
|
42 static BUFFER data_out ;
|
Chris@0
|
43 static BUFFER data_in ;
|
Chris@0
|
44
|
Chris@0
|
45 static void
|
Chris@0
|
46 ogg_short_test (void)
|
Chris@0
|
47 { const char * filename = "vorbis_short.oga" ;
|
Chris@0
|
48
|
Chris@0
|
49 SNDFILE * file ;
|
Chris@0
|
50 SF_INFO sfinfo ;
|
Chris@0
|
51 short seek_data [10] ;
|
Chris@0
|
52 unsigned k ;
|
Chris@0
|
53
|
Chris@0
|
54 print_test_name ("ogg_short_test", filename) ;
|
Chris@0
|
55
|
Chris@0
|
56 /* Generate float data. */
|
Chris@0
|
57 gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7F00) ;
|
Chris@0
|
58
|
Chris@0
|
59 /* Convert to shorteger. */
|
Chris@0
|
60 for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
|
Chris@0
|
61 data_out.s [k] = lrintf (data_out.f [k]) ;
|
Chris@0
|
62
|
Chris@0
|
63 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
64
|
Chris@0
|
65 /* Set up output file type. */
|
Chris@0
|
66 sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
|
Chris@0
|
67 sfinfo.channels = 1 ;
|
Chris@0
|
68 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@0
|
69
|
Chris@0
|
70 /* Write the output file. */
|
Chris@0
|
71 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
72 test_write_short_or_die (file, 0, data_out.s, ARRAY_LEN (data_out.s), __LINE__) ;
|
Chris@0
|
73 sf_close (file) ;
|
Chris@0
|
74
|
Chris@0
|
75 /* Read the file in again. */
|
Chris@0
|
76 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
77
|
Chris@0
|
78 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
79 test_read_short_or_die (file, 0, data_in.s, ARRAY_LEN (data_in.s), __LINE__) ;
|
Chris@0
|
80 sf_close (file) ;
|
Chris@0
|
81
|
Chris@0
|
82 puts ("ok") ;
|
Chris@0
|
83
|
Chris@0
|
84 /* Test seeking. */
|
Chris@0
|
85 print_test_name ("ogg_seek_test", filename) ;
|
Chris@0
|
86
|
Chris@0
|
87 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
88
|
Chris@0
|
89 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
|
Chris@0
|
90 test_read_short_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
91 compare_short_or_die (seek_data, data_in.s + 10, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
92
|
Chris@0
|
93 sf_close (file) ;
|
Chris@0
|
94
|
Chris@0
|
95 puts ("ok") ;
|
Chris@0
|
96
|
Chris@0
|
97 unlink (filename) ;
|
Chris@0
|
98 } /* ogg_short_test */
|
Chris@0
|
99
|
Chris@0
|
100 static void
|
Chris@0
|
101 ogg_int_test (void)
|
Chris@0
|
102 { const char * filename = "vorbis_int.oga" ;
|
Chris@0
|
103
|
Chris@0
|
104 SNDFILE * file ;
|
Chris@0
|
105 SF_INFO sfinfo ;
|
Chris@0
|
106 int seek_data [10] ;
|
Chris@0
|
107 unsigned k ;
|
Chris@0
|
108
|
Chris@0
|
109 print_test_name ("ogg_int_test", filename) ;
|
Chris@0
|
110
|
Chris@0
|
111 /* Generate float data. */
|
Chris@0
|
112 gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7FFF0000) ;
|
Chris@0
|
113
|
Chris@0
|
114 /* Convert to integer. */
|
Chris@0
|
115 for (k = 0 ; k < ARRAY_LEN (data_out.i) ; k++)
|
Chris@0
|
116 data_out.i [k] = lrintf (data_out.f [k]) ;
|
Chris@0
|
117
|
Chris@0
|
118 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
119
|
Chris@0
|
120 /* Set up output file type. */
|
Chris@0
|
121 sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
|
Chris@0
|
122 sfinfo.channels = 1 ;
|
Chris@0
|
123 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@0
|
124
|
Chris@0
|
125 /* Write the output file. */
|
Chris@0
|
126 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
127 test_write_int_or_die (file, 0, data_out.i, ARRAY_LEN (data_out.i), __LINE__) ;
|
Chris@0
|
128 sf_close (file) ;
|
Chris@0
|
129
|
Chris@0
|
130 /* Read the file in again. */
|
Chris@0
|
131 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
132
|
Chris@0
|
133 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
134 test_read_int_or_die (file, 0, data_in.i, ARRAY_LEN (data_in.i), __LINE__) ;
|
Chris@0
|
135 sf_close (file) ;
|
Chris@0
|
136
|
Chris@0
|
137 puts ("ok") ;
|
Chris@0
|
138
|
Chris@0
|
139 /* Test seeking. */
|
Chris@0
|
140 print_test_name ("ogg_seek_test", filename) ;
|
Chris@0
|
141
|
Chris@0
|
142 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
143
|
Chris@0
|
144 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
|
Chris@0
|
145 test_read_int_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
146 compare_int_or_die (seek_data, data_in.i + 10, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
147
|
Chris@0
|
148 sf_close (file) ;
|
Chris@0
|
149
|
Chris@0
|
150 puts ("ok") ;
|
Chris@0
|
151
|
Chris@0
|
152 unlink (filename) ;
|
Chris@0
|
153 } /* ogg_int_test */
|
Chris@0
|
154
|
Chris@0
|
155 static void
|
Chris@0
|
156 ogg_float_test (void)
|
Chris@0
|
157 { const char * filename = "vorbis_float.oga" ;
|
Chris@0
|
158
|
Chris@0
|
159 SNDFILE * file ;
|
Chris@0
|
160 SF_INFO sfinfo ;
|
Chris@0
|
161 float seek_data [10] ;
|
Chris@0
|
162
|
Chris@0
|
163 print_test_name ("ogg_float_test", filename) ;
|
Chris@0
|
164
|
Chris@0
|
165 gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 0.95) ;
|
Chris@0
|
166
|
Chris@0
|
167 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
168
|
Chris@0
|
169 /* Set up output file type. */
|
Chris@0
|
170 sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
|
Chris@0
|
171 sfinfo.channels = 1 ;
|
Chris@0
|
172 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@0
|
173
|
Chris@0
|
174 /* Write the output file. */
|
Chris@0
|
175 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
176 test_write_float_or_die (file, 0, data_out.f, ARRAY_LEN (data_out.f), __LINE__) ;
|
Chris@0
|
177 sf_close (file) ;
|
Chris@0
|
178
|
Chris@0
|
179 /* Read the file in again. */
|
Chris@0
|
180 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
181
|
Chris@0
|
182 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
183 test_read_float_or_die (file, 0, data_in.f, ARRAY_LEN (data_in.f), __LINE__) ;
|
Chris@0
|
184 sf_close (file) ;
|
Chris@0
|
185
|
Chris@0
|
186 puts ("ok") ;
|
Chris@0
|
187
|
Chris@0
|
188 /* Test seeking. */
|
Chris@0
|
189 print_test_name ("ogg_seek_test", filename) ;
|
Chris@0
|
190
|
Chris@0
|
191 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
192
|
Chris@0
|
193 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
|
Chris@0
|
194 test_read_float_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
195 compare_float_or_die (seek_data, data_in.f + 10, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
196
|
Chris@0
|
197 sf_close (file) ;
|
Chris@0
|
198
|
Chris@0
|
199 puts ("ok") ;
|
Chris@0
|
200
|
Chris@0
|
201 unlink (filename) ;
|
Chris@0
|
202 } /* ogg_float_test */
|
Chris@0
|
203
|
Chris@0
|
204 static void
|
Chris@0
|
205 ogg_double_test (void)
|
Chris@0
|
206 { const char * filename = "vorbis_double.oga" ;
|
Chris@0
|
207
|
Chris@0
|
208 SNDFILE * file ;
|
Chris@0
|
209 SF_INFO sfinfo ;
|
Chris@0
|
210 double seek_data [10] ;
|
Chris@0
|
211
|
Chris@0
|
212 print_test_name ("ogg_double_test", filename) ;
|
Chris@0
|
213
|
Chris@0
|
214 gen_windowed_sine_double (data_out.d, ARRAY_LEN (data_out.d), 0.95) ;
|
Chris@0
|
215
|
Chris@0
|
216 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
217
|
Chris@0
|
218 /* Set up output file type. */
|
Chris@0
|
219 sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
|
Chris@0
|
220 sfinfo.channels = 1 ;
|
Chris@0
|
221 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@0
|
222
|
Chris@0
|
223 /* Write the output file. */
|
Chris@0
|
224 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
225 test_write_double_or_die (file, 0, data_out.d, ARRAY_LEN (data_out.d), __LINE__) ;
|
Chris@0
|
226 sf_close (file) ;
|
Chris@0
|
227
|
Chris@0
|
228 /* Read the file in again. */
|
Chris@0
|
229 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
230
|
Chris@0
|
231 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
232 test_read_double_or_die (file, 0, data_in.d, ARRAY_LEN (data_in.d), __LINE__) ;
|
Chris@0
|
233 sf_close (file) ;
|
Chris@0
|
234
|
Chris@0
|
235 puts ("ok") ;
|
Chris@0
|
236
|
Chris@0
|
237 /* Test seeking. */
|
Chris@0
|
238 print_test_name ("ogg_seek_test", filename) ;
|
Chris@0
|
239
|
Chris@0
|
240 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
241
|
Chris@0
|
242 test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
|
Chris@0
|
243 test_read_double_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
244 compare_double_or_die (seek_data, data_in.d + 10, ARRAY_LEN (seek_data), __LINE__) ;
|
Chris@0
|
245
|
Chris@0
|
246 sf_close (file) ;
|
Chris@0
|
247
|
Chris@0
|
248 puts ("ok") ;
|
Chris@0
|
249
|
Chris@0
|
250 unlink (filename) ;
|
Chris@0
|
251 } /* ogg_double_test */
|
Chris@0
|
252
|
Chris@0
|
253
|
Chris@0
|
254 static void
|
Chris@0
|
255 ogg_stereo_seek_test (const char * filename, int format)
|
Chris@0
|
256 { static float data [SAMPLE_RATE] ;
|
Chris@0
|
257 static float stereo_out [SAMPLE_RATE * 2] ;
|
Chris@0
|
258
|
Chris@0
|
259 SNDFILE * file ;
|
Chris@0
|
260 SF_INFO sfinfo ;
|
Chris@0
|
261 sf_count_t pos ;
|
Chris@0
|
262 unsigned k ;
|
Chris@0
|
263
|
Chris@0
|
264 print_test_name (__func__, filename) ;
|
Chris@0
|
265
|
Chris@0
|
266 gen_windowed_sine_float (data, ARRAY_LEN (data), 0.95) ;
|
Chris@0
|
267 for (k = 0 ; k < ARRAY_LEN (data) ; k++)
|
Chris@0
|
268 { stereo_out [2 * k] = data [k] ;
|
Chris@0
|
269 stereo_out [2 * k + 1] = data [ARRAY_LEN (data) - k - 1] ;
|
Chris@0
|
270 } ;
|
Chris@0
|
271
|
Chris@0
|
272 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
273
|
Chris@0
|
274 /* Set up output file type. */
|
Chris@0
|
275 sfinfo.format = format ;
|
Chris@0
|
276 sfinfo.channels = 2 ;
|
Chris@0
|
277 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@0
|
278
|
Chris@0
|
279 /* Write the output file. */
|
Chris@0
|
280 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
281 test_write_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
|
Chris@0
|
282 sf_close (file) ;
|
Chris@0
|
283
|
Chris@0
|
284 /* Open file in again for reading. */
|
Chris@0
|
285 memset (&sfinfo, 0, sizeof (sfinfo)) ;
|
Chris@0
|
286 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
|
Chris@0
|
287
|
Chris@0
|
288 /* Read in the whole file. */
|
Chris@0
|
289 test_read_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
|
Chris@0
|
290
|
Chris@0
|
291 /* Now hammer seeking code. */
|
Chris@0
|
292 test_seek_or_die (file, 234, SEEK_SET, 234, sfinfo.channels, __LINE__) ;
|
Chris@0
|
293 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
294 compare_float_or_die (data, stereo_out + (234 * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
295
|
Chris@0
|
296 test_seek_or_die (file, 442, SEEK_SET, 442, sfinfo.channels, __LINE__) ;
|
Chris@0
|
297 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
298 compare_float_or_die (data, stereo_out + (442 * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
299
|
Chris@0
|
300 test_seek_or_die (file, 12, SEEK_CUR, 442 + 10 + 12, sfinfo.channels, __LINE__) ;
|
Chris@0
|
301 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
302 compare_float_or_die (data, stereo_out + ((442 + 10 + 12) * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
303
|
Chris@0
|
304 test_seek_or_die (file, 12, SEEK_CUR, 442 + 20 + 24, sfinfo.channels, __LINE__) ;
|
Chris@0
|
305 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
306 compare_float_or_die (data, stereo_out + ((442 + 20 + 24) * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
307
|
Chris@0
|
308 pos = 500 - sfinfo.frames ;
|
Chris@0
|
309 test_seek_or_die (file, pos, SEEK_END, 500, sfinfo.channels, __LINE__) ;
|
Chris@0
|
310 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
311 compare_float_or_die (data, stereo_out + (500 * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
312
|
Chris@0
|
313 pos = 10 - sfinfo.frames ;
|
Chris@0
|
314 test_seek_or_die (file, pos, SEEK_END, 10, sfinfo.channels, __LINE__) ;
|
Chris@0
|
315 test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
|
Chris@0
|
316 compare_float_or_die (data, stereo_out + (10 * sfinfo.channels), 10, __LINE__) ;
|
Chris@0
|
317
|
Chris@0
|
318 sf_close (file) ;
|
Chris@0
|
319
|
Chris@0
|
320 puts ("ok") ;
|
Chris@0
|
321 unlink (filename) ;
|
Chris@0
|
322 } /* ogg_stereo_seek_test */
|
Chris@0
|
323
|
Chris@0
|
324
|
Chris@0
|
325 int
|
Chris@0
|
326 main (void)
|
Chris@0
|
327 {
|
Chris@0
|
328 if (HAVE_EXTERNAL_LIBS)
|
Chris@0
|
329 { ogg_short_test () ;
|
Chris@0
|
330 ogg_int_test () ;
|
Chris@0
|
331 ogg_float_test () ;
|
Chris@0
|
332 ogg_double_test () ;
|
Chris@0
|
333
|
Chris@0
|
334 /*-ogg_stereo_seek_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;-*/
|
Chris@0
|
335 ogg_stereo_seek_test ("vorbis_seek.ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS) ;
|
Chris@0
|
336 }
|
Chris@0
|
337 else
|
Chris@0
|
338 puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
|
Chris@0
|
339
|
Chris@0
|
340 return 0 ;
|
Chris@0
|
341 } /* main */
|