Chris@40
|
1 /*
|
Chris@40
|
2 ** Copyright (C) 2015 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 <math.h>
|
Chris@40
|
25 #include <inttypes.h>
|
Chris@40
|
26
|
Chris@40
|
27 #if HAVE_UNISTD_H
|
Chris@40
|
28 #include <unistd.h>
|
Chris@40
|
29 #endif
|
Chris@40
|
30
|
Chris@40
|
31 #include <sndfile.h>
|
Chris@40
|
32
|
Chris@40
|
33 #include "dft_cmp.h"
|
Chris@40
|
34 #include "utils.h"
|
Chris@40
|
35
|
Chris@40
|
36 #define BUFFER_LENGTH 10000
|
Chris@40
|
37 #define SAMPLE_RATE 44010
|
Chris@40
|
38
|
Chris@40
|
39 static void short_lrw_test (const char *filename, int filetype, const short * output, int out_len) ;
|
Chris@40
|
40 static void int_lrw_test (const char *filename, int filetype, const int * output, int out_len) ;
|
Chris@40
|
41 static void float_lrw_test (const char *filename, int filetype, const float * output, int out_len) ;
|
Chris@40
|
42 static void double_lrw_test (const char *filename, int filetype, const double * output, int out_len) ;
|
Chris@40
|
43
|
Chris@40
|
44
|
Chris@40
|
45 static short short_data [BUFFER_LENGTH] ;
|
Chris@40
|
46 static int int_data [BUFFER_LENGTH] ;
|
Chris@40
|
47 static float float_data [BUFFER_LENGTH] ;
|
Chris@40
|
48 static double double_data [BUFFER_LENGTH] ;
|
Chris@40
|
49
|
Chris@40
|
50 int
|
Chris@40
|
51 main (int argc, char *argv [])
|
Chris@40
|
52 { int do_all ;
|
Chris@40
|
53 size_t k ;
|
Chris@40
|
54
|
Chris@40
|
55 if (argc != 2)
|
Chris@40
|
56 { printf ("Usage : %s <test>\n", argv [0]) ;
|
Chris@40
|
57 printf (" Where <test> is one of the following:\n") ;
|
Chris@40
|
58 printf (" alac - test CAF/ALAC file functions\n") ;
|
Chris@40
|
59 printf (" all - perform all tests\n") ;
|
Chris@40
|
60 exit (1) ;
|
Chris@40
|
61 } ;
|
Chris@40
|
62
|
Chris@40
|
63 for (k = 0 ; k < ARRAY_LEN (short_data) ; k++)
|
Chris@40
|
64 { int value = k / 32 ;
|
Chris@40
|
65 int_data [k] = (value & 1 ? -1 : 1) * value ;
|
Chris@40
|
66 short_data [k] = int_data [k] ;
|
Chris@40
|
67 float_data [k] = int_data [k] / 32000.0 ;
|
Chris@40
|
68 double_data [k] = int_data [k] / 32000.0 ;
|
Chris@40
|
69 }
|
Chris@40
|
70
|
Chris@40
|
71 do_all = ! strcmp (argv [1], "all") ;
|
Chris@40
|
72
|
Chris@40
|
73 if (do_all || strcmp (argv [1], "alac") == 0)
|
Chris@40
|
74 { short_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_16, short_data, ARRAY_LEN (short_data)) ;
|
Chris@40
|
75 int_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, int_data, ARRAY_LEN (int_data)) ;
|
Chris@40
|
76 float_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, float_data, ARRAY_LEN (float_data)) ;
|
Chris@40
|
77 double_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, double_data, ARRAY_LEN (double_data)) ;
|
Chris@40
|
78 } ;
|
Chris@40
|
79
|
Chris@40
|
80 return 0 ;
|
Chris@40
|
81 } /* main */
|
Chris@40
|
82
|
Chris@40
|
83 /*============================================================================================
|
Chris@40
|
84 * Here are the test functions.
|
Chris@40
|
85 */
|
Chris@40
|
86
|
Chris@40
|
87 static void
|
Chris@40
|
88 short_lrw_test (const char *filename, int filetype, const short * output, int out_len)
|
Chris@40
|
89 { SNDFILE *file ;
|
Chris@40
|
90 SF_INFO sfinfo ;
|
Chris@40
|
91 int k ;
|
Chris@40
|
92 short input [out_len] ;
|
Chris@40
|
93
|
Chris@40
|
94 print_test_name ("short_lrw_test", filename) ;
|
Chris@40
|
95
|
Chris@40
|
96 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@40
|
97 sfinfo.frames = out_len ;
|
Chris@40
|
98 sfinfo.channels = 1 ;
|
Chris@40
|
99 sfinfo.format = filetype ;
|
Chris@40
|
100
|
Chris@40
|
101 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
102
|
Chris@40
|
103 test_write_short_or_die (file, 0, output, out_len, __LINE__) ;
|
Chris@40
|
104
|
Chris@40
|
105 sf_close (file) ;
|
Chris@40
|
106
|
Chris@40
|
107 memset (input, 0, sizeof (input)) ;
|
Chris@40
|
108
|
Chris@40
|
109 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
110
|
Chris@40
|
111 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
|
Chris@40
|
112 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;
|
Chris@40
|
113 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
|
Chris@40
|
114
|
Chris@40
|
115 check_log_buffer_or_die (file, __LINE__) ;
|
Chris@40
|
116
|
Chris@40
|
117 test_read_short_or_die (file, 0, input, out_len, __LINE__) ;
|
Chris@40
|
118
|
Chris@40
|
119 sf_close (file) ;
|
Chris@40
|
120
|
Chris@40
|
121 for (k = 0 ; k < out_len ; k++)
|
Chris@40
|
122 exit_if_true (input [k] != output [k],
|
Chris@40
|
123 "\n\nLine: %d: Error on input %d, expected %d, got %d\n", __LINE__, k, output [k], input [k]) ;
|
Chris@40
|
124
|
Chris@40
|
125 puts ("ok") ;
|
Chris@40
|
126 unlink (filename) ;
|
Chris@40
|
127
|
Chris@40
|
128 return ;
|
Chris@40
|
129 } /* short_lrw_test */
|
Chris@40
|
130
|
Chris@40
|
131 static void
|
Chris@40
|
132 int_lrw_test (const char *filename, int filetype, const int * output, int out_len)
|
Chris@40
|
133 { SNDFILE *file ;
|
Chris@40
|
134 SF_INFO sfinfo ;
|
Chris@40
|
135 int k ;
|
Chris@40
|
136 int input [out_len] ;
|
Chris@40
|
137
|
Chris@40
|
138 print_test_name ("int_lrw_test", filename) ;
|
Chris@40
|
139
|
Chris@40
|
140 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@40
|
141 sfinfo.frames = out_len ;
|
Chris@40
|
142 sfinfo.channels = 1 ;
|
Chris@40
|
143 sfinfo.format = filetype ;
|
Chris@40
|
144
|
Chris@40
|
145 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
146
|
Chris@40
|
147 test_write_int_or_die (file, 0, output, out_len, __LINE__) ;
|
Chris@40
|
148
|
Chris@40
|
149 sf_close (file) ;
|
Chris@40
|
150
|
Chris@40
|
151 memset (input, 0, sizeof (input)) ;
|
Chris@40
|
152
|
Chris@40
|
153 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
154
|
Chris@40
|
155 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
|
Chris@40
|
156 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too int). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;
|
Chris@40
|
157 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
|
Chris@40
|
158
|
Chris@40
|
159 check_log_buffer_or_die (file, __LINE__) ;
|
Chris@40
|
160
|
Chris@40
|
161 test_read_int_or_die (file, 0, input, out_len, __LINE__) ;
|
Chris@40
|
162
|
Chris@40
|
163 sf_close (file) ;
|
Chris@40
|
164
|
Chris@40
|
165 for (k = 0 ; k < out_len ; k++)
|
Chris@40
|
166 exit_if_true (input [k] != output [k],
|
Chris@40
|
167 "\n\nLine: %d: Error on input %d, expected %d, got %d\n", __LINE__, k, output [k], input [k]) ;
|
Chris@40
|
168
|
Chris@40
|
169 puts ("ok") ;
|
Chris@40
|
170 unlink (filename) ;
|
Chris@40
|
171
|
Chris@40
|
172 return ;
|
Chris@40
|
173 } /* int_lrw_test */
|
Chris@40
|
174
|
Chris@40
|
175 static void
|
Chris@40
|
176 float_lrw_test (const char *filename, int filetype, const float * output, int out_len)
|
Chris@40
|
177 { SNDFILE *file ;
|
Chris@40
|
178 SF_INFO sfinfo ;
|
Chris@40
|
179 int k ;
|
Chris@40
|
180 float input [out_len] ;
|
Chris@40
|
181
|
Chris@40
|
182 print_test_name ("float_lrw_test", filename) ;
|
Chris@40
|
183
|
Chris@40
|
184 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@40
|
185 sfinfo.frames = out_len ;
|
Chris@40
|
186 sfinfo.channels = 1 ;
|
Chris@40
|
187 sfinfo.format = filetype ;
|
Chris@40
|
188
|
Chris@40
|
189 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
190
|
Chris@40
|
191 test_write_float_or_die (file, 0, output, out_len, __LINE__) ;
|
Chris@40
|
192
|
Chris@40
|
193 sf_close (file) ;
|
Chris@40
|
194
|
Chris@40
|
195 memset (input, 0, sizeof (input)) ;
|
Chris@40
|
196
|
Chris@40
|
197 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
198
|
Chris@40
|
199 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
|
Chris@40
|
200 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too float). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;
|
Chris@40
|
201 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
|
Chris@40
|
202
|
Chris@40
|
203 check_log_buffer_or_die (file, __LINE__) ;
|
Chris@40
|
204
|
Chris@40
|
205 test_read_float_or_die (file, 0, input, out_len, __LINE__) ;
|
Chris@40
|
206
|
Chris@40
|
207 sf_close (file) ;
|
Chris@40
|
208
|
Chris@40
|
209 for (k = 0 ; k < out_len ; k++)
|
Chris@40
|
210 exit_if_true (fabs (input [k] - output [k]) > 0.00001,
|
Chris@40
|
211 "\n\nLine: %d: Error on input %d, expected %f, got %f\n", __LINE__, k, output [k], input [k]) ;
|
Chris@40
|
212
|
Chris@40
|
213 puts ("ok") ;
|
Chris@40
|
214 unlink (filename) ;
|
Chris@40
|
215
|
Chris@40
|
216 return ;
|
Chris@40
|
217 } /* float_lrw_test */
|
Chris@40
|
218
|
Chris@40
|
219 static void
|
Chris@40
|
220 double_lrw_test (const char *filename, int filetype, const double * output, int out_len)
|
Chris@40
|
221 { SNDFILE *file ;
|
Chris@40
|
222 SF_INFO sfinfo ;
|
Chris@40
|
223 int k ;
|
Chris@40
|
224 double input [out_len] ;
|
Chris@40
|
225
|
Chris@40
|
226 print_test_name ("double_lrw_test", filename) ;
|
Chris@40
|
227
|
Chris@40
|
228 sfinfo.samplerate = SAMPLE_RATE ;
|
Chris@40
|
229 sfinfo.frames = out_len ;
|
Chris@40
|
230 sfinfo.channels = 1 ;
|
Chris@40
|
231 sfinfo.format = filetype ;
|
Chris@40
|
232
|
Chris@40
|
233 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
234
|
Chris@40
|
235 test_write_double_or_die (file, 0, output, out_len, __LINE__) ;
|
Chris@40
|
236
|
Chris@40
|
237 sf_close (file) ;
|
Chris@40
|
238
|
Chris@40
|
239 memset (input, 0, sizeof (input)) ;
|
Chris@40
|
240
|
Chris@40
|
241 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
|
Chris@40
|
242
|
Chris@40
|
243 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
|
Chris@40
|
244 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too double). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;
|
Chris@40
|
245 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
|
Chris@40
|
246
|
Chris@40
|
247 check_log_buffer_or_die (file, __LINE__) ;
|
Chris@40
|
248
|
Chris@40
|
249 test_read_double_or_die (file, 0, input, out_len, __LINE__) ;
|
Chris@40
|
250
|
Chris@40
|
251 sf_close (file) ;
|
Chris@40
|
252
|
Chris@40
|
253 for (k = 0 ; k < out_len ; k++)
|
Chris@40
|
254 exit_if_true (fabs (input [k] - output [k]) > 0.00001,
|
Chris@40
|
255 "\n\nLine: %d: Error on input %d, expected %f, got %f\n", __LINE__, k, output [k], input [k]) ;
|
Chris@40
|
256
|
Chris@40
|
257 puts ("ok") ;
|
Chris@40
|
258 unlink (filename) ;
|
Chris@40
|
259
|
Chris@40
|
260 return ;
|
Chris@40
|
261 } /* double_lrw_test */
|
Chris@40
|
262
|