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