Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.25/tests/peak_chunk_test.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2001-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_LEN (1<<15) | |
35 #define LOG_BUFFER_SIZE 1024 | |
36 | |
37 | |
38 static void test_float_peak (const char *filename, int filetype) ; | |
39 static void read_write_peak_test (const char *filename, int filetype) ; | |
40 | |
41 static void check_logged_peaks (char *buffer) ; | |
42 | |
43 /* Force the start of this buffer to be double aligned. Sparc-solaris will | |
44 ** choke if its not. | |
45 */ | |
46 static double data [BUFFER_LEN] ; | |
47 static char log_buffer [LOG_BUFFER_SIZE] ; | |
48 | |
49 int | |
50 main (int argc, char *argv []) | |
51 { int do_all = 0 ; | |
52 int test_count = 0 ; | |
53 | |
54 if (argc != 2) | |
55 { printf ("Usage : %s <test>\n", argv [0]) ; | |
56 printf (" Where <test> is one of the following:\n") ; | |
57 printf (" aiff - test AIFF file PEAK chunk\n") ; | |
58 printf (" caf - test CAF file PEAK chunk\n") ; | |
59 printf (" wav - test WAV file peak chunk\n") ; | |
60 printf (" all - perform all tests\n") ; | |
61 exit (1) ; | |
62 } ; | |
63 | |
64 do_all = ! strcmp (argv [1], "all") ; | |
65 | |
66 if (do_all || ! strcmp (argv [1], "wav")) | |
67 { test_float_peak ("peak_float.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT) ; | |
68 test_float_peak ("peak_float.wavex", SF_FORMAT_WAVEX | SF_FORMAT_FLOAT) ; | |
69 test_float_peak ("peak_float.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_FLOAT) ; | |
70 | |
71 read_write_peak_test ("rw_peak.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT) ; | |
72 read_write_peak_test ("rw_peak.wavex", SF_FORMAT_WAVEX | SF_FORMAT_FLOAT) ; | |
73 test_count++ ; | |
74 } ; | |
75 | |
76 if (do_all || ! strcmp (argv [1], "aiff")) | |
77 { test_float_peak ("peak_float.aiff", SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ; | |
78 | |
79 read_write_peak_test ("rw_peak.aiff", SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ; | |
80 test_count++ ; | |
81 } ; | |
82 | |
83 if (do_all || ! strcmp (argv [1], "caf")) | |
84 { test_float_peak ("peak_float.caf", SF_FORMAT_CAF | SF_FORMAT_FLOAT) ; | |
85 | |
86 read_write_peak_test ("rw_peak.caf", SF_FORMAT_CAF | SF_FORMAT_FLOAT) ; | |
87 test_count++ ; | |
88 } ; | |
89 | |
90 if (test_count == 0) | |
91 { printf ("Mono : ************************************\n") ; | |
92 printf ("Mono : * No '%s' test defined.\n", argv [1]) ; | |
93 printf ("Mono : ************************************\n") ; | |
94 return 1 ; | |
95 } ; | |
96 | |
97 return 0 ; | |
98 } /* main */ | |
99 | |
100 /*============================================================================================ | |
101 ** Here are the test functions. | |
102 */ | |
103 | |
104 static void | |
105 test_float_peak (const char *filename, int filetype) | |
106 { SNDFILE *file ; | |
107 SF_INFO sfinfo ; | |
108 int k, frames, count ; | |
109 | |
110 print_test_name ("test_float_peak", filename) ; | |
111 | |
112 memset (&sfinfo, 0, sizeof (sfinfo)) ; | |
113 sfinfo.samplerate = 44100 ; | |
114 sfinfo.format = filetype ; | |
115 sfinfo.channels = 4 ; | |
116 sfinfo.frames = 0 ; | |
117 | |
118 frames = BUFFER_LEN / sfinfo.channels ; | |
119 | |
120 /* Create some random data with a peak value of 0.66. */ | |
121 for (k = 0 ; k < BUFFER_LEN ; k++) | |
122 data [k] = (rand () % 2000) / 3000.0 ; | |
123 | |
124 /* Insert some larger peaks a know locations. */ | |
125 data [4 * (frames / 8) + 0] = (frames / 8) * 0.01 ; /* First channel */ | |
126 data [4 * (frames / 6) + 1] = (frames / 6) * 0.01 ; /* Second channel */ | |
127 data [4 * (frames / 4) + 2] = (frames / 4) * 0.01 ; /* Third channel */ | |
128 data [4 * (frames / 2) + 3] = (frames / 2) * 0.01 ; /* Fourth channel */ | |
129 | |
130 /* Write a file with PEAK chunks. */ | |
131 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, 0, __LINE__) ; | |
132 | |
133 /* Try to confuse the header writer by adding a removing the PEAK chunk. */ | |
134 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_TRUE) ; | |
135 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
136 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_TRUE) ; | |
137 | |
138 /* Write the data in four passed. The data is designed so that peaks will | |
139 ** be written in the different calls to sf_write_double (). | |
140 */ | |
141 for (count = 0 ; count < 4 ; count ++) | |
142 test_write_double_or_die (file, 0, data + count * BUFFER_LEN / 4, BUFFER_LEN / 4, BUFFER_LEN / 4) ; | |
143 | |
144 sf_close (file) ; | |
145 | |
146 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, 0, __LINE__) ; | |
147 | |
148 if (sfinfo.format != filetype) | |
149 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; | |
150 exit (1) ; | |
151 } ; | |
152 | |
153 if (sfinfo.frames != frames) | |
154 { printf ("\n\nLine %d: Incorrect number of frames in file. (%d => %ld)\n", __LINE__, frames, (long) sfinfo.frames) ; | |
155 exit (1) ; | |
156 } ; | |
157 | |
158 if (sfinfo.channels != 4) | |
159 { printf ("\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; | |
160 exit (1) ; | |
161 } ; | |
162 | |
163 /* Check these two commands. */ | |
164 if (sf_command (file, SFC_GET_SIGNAL_MAX, data, sizeof (double)) == SF_FALSE) | |
165 { printf ("\n\nLine %d: Command should have returned SF_TRUE.\n", __LINE__) ; | |
166 exit (1) ; | |
167 } ; | |
168 | |
169 if (fabs (data [0] - (frames / 2) * 0.01) > 0.01) | |
170 { printf ("\n\nLine %d: Bad peak value (%f should be %f) for command SFC_GET_SIGNAL_MAX.\n", __LINE__, data [0], (frames / 2) * 0.01) ; | |
171 exit (1) ; | |
172 } ; | |
173 | |
174 if (sf_command (file, SFC_GET_MAX_ALL_CHANNELS, data, sizeof (double) * sfinfo.channels) == SF_FALSE) | |
175 { printf ("\n\nLine %d: Command should have returned SF_TRUE.\n", __LINE__) ; | |
176 exit (1) ; | |
177 } ; | |
178 | |
179 if (fabs (data [3] - (frames / 2) * 0.01) > 0.01) | |
180 { printf ("\n\nLine %d: Bad peak value (%f should be %f) for command SFC_GET_MAX_ALL_CHANNELS.\n", __LINE__, data [0], (frames / 2) * 0.01) ; | |
181 exit (1) ; | |
182 } ; | |
183 | |
184 /* Get the log buffer data. */ | |
185 log_buffer [0] = 0 ; | |
186 sf_command (file, SFC_GET_LOG_INFO, log_buffer, LOG_BUFFER_SIZE) ; | |
187 | |
188 if (strlen (log_buffer) == 0) | |
189 { printf ("\n\nLine %d: Empty log buffer,\n", __LINE__) ; | |
190 exit (1) ; | |
191 } ; | |
192 | |
193 check_logged_peaks (log_buffer) ; | |
194 | |
195 sf_close (file) ; | |
196 | |
197 /* Write a file ***without*** PEAK chunks. */ | |
198 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, 0, __LINE__) ; | |
199 | |
200 /* Try to confuse the header writer by adding a removing the PEAK chunk. */ | |
201 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
202 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_TRUE) ; | |
203 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ; | |
204 | |
205 /* Write the data in four passed. The data is designed so that peaks will | |
206 ** be written in the different calls to sf_write_double (). | |
207 */ | |
208 for (count = 0 ; count < 4 ; count ++) | |
209 test_write_double_or_die (file, 0, data + count * BUFFER_LEN / 4, BUFFER_LEN / 4, BUFFER_LEN / 4) ; | |
210 | |
211 sf_close (file) ; | |
212 | |
213 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, 0, __LINE__) ; | |
214 | |
215 /* Check these two commands. */ | |
216 if (sf_command (file, SFC_GET_SIGNAL_MAX, data, sizeof (double))) | |
217 { printf ("\n\nLine %d: Command should have returned SF_FALSE.\n", __LINE__) ; | |
218 exit (1) ; | |
219 } ; | |
220 | |
221 if (sf_command (file, SFC_GET_MAX_ALL_CHANNELS, data, sizeof (double) * sfinfo.channels)) | |
222 { printf ("\n\nLine %d: Command should have returned SF_FALSE.\n", __LINE__) ; | |
223 exit (1) ; | |
224 } ; | |
225 | |
226 /* Get the log buffer data. */ | |
227 log_buffer [0] = 0 ; | |
228 sf_command (file, SFC_GET_LOG_INFO, log_buffer, LOG_BUFFER_SIZE) ; | |
229 | |
230 if (strlen (log_buffer) == 0) | |
231 { printf ("\n\nLine %d: Empty log buffer,\n", __LINE__) ; | |
232 exit (1) ; | |
233 } ; | |
234 | |
235 if (strstr (log_buffer, "PEAK :") != NULL) | |
236 { printf ("\n\nLine %d: Should not have a PEAK chunk in this file.\n\n", __LINE__) ; | |
237 puts (log_buffer) ; | |
238 exit (1) ; | |
239 } ; | |
240 | |
241 sf_close (file) ; | |
242 | |
243 unlink (filename) ; | |
244 printf ("ok\n") ; | |
245 } /* test_float_peak */ | |
246 | |
247 static void | |
248 check_logged_peaks (char *buffer) | |
249 { char *cptr ; | |
250 int k, chan, channel_count, position ; | |
251 float value ; | |
252 | |
253 if (strstr (buffer, "should") || strstr (buffer, "*")) | |
254 { printf ("\n\nLine %d: Something wrong in buffer. Dumping.\n", __LINE__) ; | |
255 puts (buffer) ; | |
256 exit (1) ; | |
257 } ; | |
258 | |
259 channel_count = 0 ; | |
260 cptr = strstr (buffer, "Channels") ; | |
261 if (cptr && sscanf (cptr, "Channels : %d", &k) == 1) | |
262 channel_count = k ; | |
263 else if (cptr && sscanf (cptr, "Channels / frame : %d", &k) == 1) | |
264 channel_count = k ; | |
265 else | |
266 { printf ("\n\nLine %d: Couldn't find channel count.\n", __LINE__) ; | |
267 exit (1) ; | |
268 } ; | |
269 | |
270 if (channel_count != 4) | |
271 { printf ("\n\nLine %d: Wrong channel count (4 ->%d).\n", __LINE__, channel_count) ; | |
272 exit (1) ; | |
273 } ; | |
274 | |
275 if (! (cptr = strstr (buffer, "Ch Position Value"))) | |
276 { printf ("\n\nLine %d: Can't find PEAK data.\n", __LINE__) ; | |
277 exit (1) ; | |
278 } ; | |
279 | |
280 for (k = 0 ; k < channel_count ; k++) | |
281 { if (! (cptr = strchr (cptr, '\n'))) | |
282 { printf ("\n\nLine %d: Got lost.\n", __LINE__) ; | |
283 exit (1) ; | |
284 } ; | |
285 if (sscanf (cptr, "%d %d %f", &chan, &position, &value) != 3) | |
286 { printf ("\n\nLine %d: sscanf failed.\n", __LINE__) ; | |
287 exit (1) ; | |
288 } ; | |
289 if (position == 0) | |
290 { printf ("\n\nLine %d: peak position for channel %d should not be at offset 0.\n", __LINE__, chan) ; | |
291 printf ("%s", buffer) ; | |
292 exit (1) ; | |
293 } ; | |
294 if (chan != k || fabs ((position) * 0.01 - value) > 1e-6) | |
295 { printf ("\n\nLine %d: Error : peak value incorrect!\n", __LINE__) ; | |
296 printf ("%s", buffer) ; | |
297 printf ("\n\nLine %d: %d %f %f\n", __LINE__, chan, position * 0.01, value) ; | |
298 exit (1) ; | |
299 } ; | |
300 cptr ++ ; /* Move past current newline. */ | |
301 } ; | |
302 | |
303 } /* check_logged_peaks */ | |
304 | |
305 static void | |
306 read_write_peak_test (const char *filename, int filetype) | |
307 { SNDFILE *file ; | |
308 SF_INFO sfinfo ; | |
309 | |
310 double small_data [10] ; | |
311 double max_peak = 0.0 ; | |
312 unsigned k ; | |
313 | |
314 print_test_name (__func__, filename) ; | |
315 | |
316 for (k = 0 ; k < ARRAY_LEN (small_data) ; k ++) | |
317 small_data [k] = 0.1 ; | |
318 | |
319 sfinfo.samplerate = 44100 ; | |
320 sfinfo.channels = 2 ; | |
321 sfinfo.format = filetype ; | |
322 sfinfo.frames = 0 ; | |
323 | |
324 /* Open the file, add peak chunk and write samples with value 0.1. */ | |
325 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; | |
326 | |
327 sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_TRUE) ; | |
328 | |
329 test_write_double_or_die (file, 0, small_data, ARRAY_LEN (small_data), __LINE__) ; | |
330 | |
331 sf_close (file) ; | |
332 | |
333 /* Open the fiel RDWR, write sample valied 1.25. */ | |
334 file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; | |
335 | |
336 for (k = 0 ; k < ARRAY_LEN (small_data) ; k ++) | |
337 small_data [k] = 1.0 ; | |
338 | |
339 test_write_double_or_die (file, 0, small_data, ARRAY_LEN (small_data), __LINE__) ; | |
340 | |
341 sf_command (file, SFC_GET_SIGNAL_MAX, &max_peak, sizeof (max_peak)) ; | |
342 | |
343 sf_close (file) ; | |
344 | |
345 exit_if_true (max_peak < 0.1, "\n\nLine %d : max peak (%5.3f) should not be 0.1.\n\n", __LINE__, max_peak) ; | |
346 | |
347 /* Open the file and test the values written to the PEAK chunk. */ | |
348 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; | |
349 | |
350 exit_if_true (sfinfo.channels * sfinfo.frames != 2 * ARRAY_LEN (small_data), | |
351 "Line %d : frame count is %ld, should be %d\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * ARRAY_LEN (small_data)) ; | |
352 | |
353 sf_command (file, SFC_GET_SIGNAL_MAX, &max_peak, sizeof (double)) ; | |
354 | |
355 sf_close (file) ; | |
356 | |
357 exit_if_true (max_peak < 1.0, "\n\nLine %d : max peak (%5.3f) should be 1.0.\n\n", __LINE__, max_peak) ; | |
358 | |
359 unlink (filename) ; | |
360 puts ("ok") ; | |
361 } /* read_write_peak_test */ | |
362 |