1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <gtest/gtest.h>
6 #include <math.h>
7
8 #include "crossover.h"
9 #include "crossover2.h"
10 #include "drc.h"
11 #include "dsp_util.h"
12 #include "eq.h"
13 #include "eq2.h"
14
15 namespace {
16
17 /* Adds amplitude * sin(pi*freq*i + offset) to the data array. */
add_sine(float * data,size_t len,float freq,float offset,float amplitude)18 static void add_sine(float* data,
19 size_t len,
20 float freq,
21 float offset,
22 float amplitude) {
23 for (size_t i = 0; i < len; i++)
24 data[i] += amplitude * sinf((float)M_PI * freq * i + offset);
25 }
26
27 /* Calculates the magnitude at normalized frequency f. The output is
28 * the result of DFT, multiplied by 2/len. */
magnitude_at(float * data,size_t len,float f)29 static float magnitude_at(float* data, size_t len, float f) {
30 double re = 0, im = 0;
31 f *= (float)M_PI;
32 for (size_t i = 0; i < len; i++) {
33 re += data[i] * cos(i * f);
34 im += data[i] * sin(i * f);
35 }
36 return sqrt(re * re + im * im) * (2.0 / len);
37 }
38
TEST(InterleaveTest,All)39 TEST(InterleaveTest, All) {
40 const int FRAMES = 12;
41 const int SAMPLES = FRAMES * 2;
42
43 /* Repeat the same data twice, so it will exercise neon/sse
44 * optimized functions. */
45 int16_t input[SAMPLES] = {
46 -32768, -32767, -32766, -2, -1, 0, 1, 2, 3, 32765, 32766, 32767,
47 -32768, -32767, -32766, -2, -1, 0, 1, 2, 3, 32765, 32766, 32767};
48
49 float answer[SAMPLES] = {-1,
50 -32766 / 32768.0f,
51 -1 / 32768.0f,
52 1 / 32768.0f,
53 3 / 32768.0f,
54 32766 / 32768.0f,
55 -1,
56 -32766 / 32768.0f,
57 -1 / 32768.0f,
58 1 / 32768.0f,
59 3 / 32768.0f,
60 32766 / 32768.0f,
61 -32767 / 32768.0f,
62 -2 / 32768.0f,
63 0,
64 2 / 32768.0f,
65 32765 / 32768.0f,
66 32767 / 32768.0f,
67 -32767 / 32768.0f,
68 -2 / 32768.0f,
69 0,
70 2 / 32768.0f,
71 32765 / 32768.0f,
72 32767 / 32768.0f};
73
74 float output[SAMPLES];
75 float* out_ptr[] = {output, output + FRAMES};
76
77 dsp_util_deinterleave((uint8_t*)input, out_ptr, 2, SND_PCM_FORMAT_S16_LE,
78 FRAMES);
79
80 for (int i = 0; i < SAMPLES; i++) {
81 EXPECT_EQ(answer[i], output[i]);
82 }
83
84 /* dsp_util_interleave() should round to nearest number. */
85 for (int i = 0; i < SAMPLES; i += 2) {
86 output[i] += 0.499 / 32768.0f;
87 output[i + 1] -= 0.499 / 32768.0f;
88 }
89
90 int16_t output2[SAMPLES];
91 dsp_util_interleave(out_ptr, (uint8_t*)output2, 2, SND_PCM_FORMAT_S16_LE,
92 FRAMES);
93 for (int i = 0; i < SAMPLES; i++) {
94 EXPECT_EQ(input[i], output2[i]);
95 }
96 }
97
TEST(EqTest,All)98 TEST(EqTest, All) {
99 struct eq* eq;
100 size_t len = 44100;
101 float NQ = len / 2;
102 float f_low = 10 / NQ;
103 float f_mid = 100 / NQ;
104 float f_high = 1000 / NQ;
105 float* data = (float*)malloc(sizeof(float) * len);
106
107 dsp_enable_flush_denormal_to_zero();
108 /* low pass */
109 memset(data, 0, sizeof(float) * len);
110 add_sine(data, len, f_low, 0, 1); // 10Hz sine, magnitude = 1
111 EXPECT_FLOAT_EQ(1, magnitude_at(data, len, f_low));
112 add_sine(data, len, f_high, 0, 1); // 1000Hz sine, magnitude = 1
113 EXPECT_FLOAT_EQ(1, magnitude_at(data, len, f_low));
114 EXPECT_FLOAT_EQ(1, magnitude_at(data, len, f_high));
115
116 eq = eq_new();
117 EXPECT_EQ(0, eq_append_biquad(eq, BQ_LOWPASS, f_mid, 0, 0));
118 eq_process(eq, data, len);
119 EXPECT_NEAR(1, magnitude_at(data, len, f_low), 0.01);
120 EXPECT_NEAR(0, magnitude_at(data, len, f_high), 0.01);
121
122 /* Test for empty input */
123 eq_process(eq, NULL, 0);
124
125 eq_free(eq);
126
127 /* high pass */
128 memset(data, 0, sizeof(float) * len);
129 add_sine(data, len, f_low, 0, 1);
130 add_sine(data, len, f_high, 0, 1);
131
132 eq = eq_new();
133 EXPECT_EQ(0, eq_append_biquad(eq, BQ_HIGHPASS, f_mid, 0, 0));
134 eq_process(eq, data, len);
135 EXPECT_NEAR(0, magnitude_at(data, len, f_low), 0.01);
136 EXPECT_NEAR(1, magnitude_at(data, len, f_high), 0.01);
137 eq_free(eq);
138
139 /* peaking */
140 memset(data, 0, sizeof(float) * len);
141 add_sine(data, len, f_low, 0, 1);
142 add_sine(data, len, f_high, 0, 1);
143
144 eq = eq_new();
145 EXPECT_EQ(0,
146 eq_append_biquad(eq, BQ_PEAKING, f_high, 5, 6)); // Q=5, 6dB gain
147 eq_process(eq, data, len);
148 EXPECT_NEAR(1, magnitude_at(data, len, f_low), 0.01);
149 EXPECT_NEAR(2, magnitude_at(data, len, f_high), 0.01);
150 eq_free(eq);
151
152 free(data);
153
154 /* Too many biquads */
155 eq = eq_new();
156 for (int i = 0; i < MAX_BIQUADS_PER_EQ; i++) {
157 EXPECT_EQ(0, eq_append_biquad(eq, BQ_PEAKING, f_high, 5, 6));
158 }
159 EXPECT_EQ(-1, eq_append_biquad(eq, BQ_PEAKING, f_high, 5, 6));
160 eq_free(eq);
161 }
162
TEST(Eq2Test,All)163 TEST(Eq2Test, All) {
164 struct eq2* eq2;
165 size_t len = 44100;
166 float NQ = len / 2;
167 float f_low = 10 / NQ;
168 float f_mid = 100 / NQ;
169 float f_high = 1000 / NQ;
170 float* data0 = (float*)malloc(sizeof(float) * len);
171 float* data1 = (float*)malloc(sizeof(float) * len);
172
173 dsp_enable_flush_denormal_to_zero();
174
175 /* a mixture of 10Hz an 1000Hz sine */
176 memset(data0, 0, sizeof(float) * len);
177 memset(data1, 0, sizeof(float) * len);
178 add_sine(data0, len, f_low, 0, 1); // 10Hz sine, magnitude = 1
179 add_sine(data0, len, f_high, 0, 1); // 1000Hz sine, magnitude = 1
180 add_sine(data1, len, f_low, 0, 1); // 10Hz sine, magnitude = 1
181 add_sine(data1, len, f_high, 0, 1); // 1000Hz sine, magnitude = 1
182
183 /* low pass at left and high pass at right */
184 eq2 = eq2_new();
185 EXPECT_EQ(0, eq2_append_biquad(eq2, 0, BQ_LOWPASS, f_mid, 0, 0));
186 EXPECT_EQ(0, eq2_append_biquad(eq2, 1, BQ_HIGHPASS, f_mid, 0, 0));
187 eq2_process(eq2, data0, data1, len);
188 EXPECT_NEAR(1, magnitude_at(data0, len, f_low), 0.01);
189 EXPECT_NEAR(0, magnitude_at(data0, len, f_high), 0.01);
190 EXPECT_NEAR(0, magnitude_at(data1, len, f_low), 0.01);
191 EXPECT_NEAR(1, magnitude_at(data1, len, f_high), 0.01);
192
193 /* Test for empty input */
194 eq2_process(eq2, NULL, NULL, 0);
195 eq2_free(eq2);
196
197 /* a mixture of 10Hz and 1000Hz sine */
198 memset(data0, 0, sizeof(float) * len);
199 memset(data1, 0, sizeof(float) * len);
200 add_sine(data0, len, f_low, 0, 1);
201 add_sine(data0, len, f_high, 0, 1);
202 add_sine(data1, len, f_low, 0, 1);
203 add_sine(data1, len, f_high, 0, 1);
204
205 /* one high-shelving biquad at left and two low-shelving biquads at right */
206 eq2 = eq2_new();
207 EXPECT_EQ(0, eq2_append_biquad(eq2, 0, BQ_HIGHSHELF, f_mid, 5, 6));
208 EXPECT_EQ(0, eq2_append_biquad(eq2, 1, BQ_LOWSHELF, f_mid, 0, -6));
209 EXPECT_EQ(0, eq2_append_biquad(eq2, 1, BQ_LOWSHELF, f_mid, 0, -6));
210
211 eq2_process(eq2, data0, data1, len);
212 EXPECT_NEAR(1, magnitude_at(data0, len, f_low), 0.01);
213 EXPECT_NEAR(2, magnitude_at(data0, len, f_high), 0.01);
214 EXPECT_NEAR(0.25, magnitude_at(data1, len, f_low), 0.01);
215 EXPECT_NEAR(1, magnitude_at(data1, len, f_high), 0.01);
216 eq2_free(eq2);
217
218 free(data0);
219 free(data1);
220
221 /* Too many biquads */
222 eq2 = eq2_new();
223 for (int i = 0; i < MAX_BIQUADS_PER_EQ2; i++) {
224 EXPECT_EQ(0, eq2_append_biquad(eq2, 0, BQ_PEAKING, f_high, 5, 6));
225 EXPECT_EQ(0, eq2_append_biquad(eq2, 1, BQ_PEAKING, f_high, 5, 6));
226 }
227 EXPECT_EQ(-1, eq2_append_biquad(eq2, 0, BQ_PEAKING, f_high, 5, 6));
228 EXPECT_EQ(-1, eq2_append_biquad(eq2, 1, BQ_PEAKING, f_high, 5, 6));
229 eq2_free(eq2);
230 }
231
TEST(CrossoverTest,All)232 TEST(CrossoverTest, All) {
233 struct crossover xo;
234 size_t len = 44100;
235 float NQ = len / 2;
236 float f0 = 62.5 / NQ;
237 float f1 = 250 / NQ;
238 float f2 = 1000 / NQ;
239 float f3 = 4000 / NQ;
240 float f4 = 16000 / NQ;
241 float* data = (float*)malloc(sizeof(float) * len);
242 float* data1 = (float*)malloc(sizeof(float) * len);
243 float* data2 = (float*)malloc(sizeof(float) * len);
244
245 dsp_enable_flush_denormal_to_zero();
246 crossover_init(&xo, f1, f3);
247 memset(data, 0, sizeof(float) * len);
248 add_sine(data, len, f0, 0, 1);
249 add_sine(data, len, f2, 0, 1);
250 add_sine(data, len, f4, 0, 1);
251
252 crossover_process(&xo, len, data, data1, data2);
253
254 // low band
255 EXPECT_NEAR(1, magnitude_at(data, len, f0), 0.01);
256 EXPECT_NEAR(0, magnitude_at(data, len, f2), 0.01);
257 EXPECT_NEAR(0, magnitude_at(data, len, f4), 0.01);
258
259 // mid band
260 EXPECT_NEAR(0, magnitude_at(data1, len, f0), 0.01);
261 EXPECT_NEAR(1, magnitude_at(data1, len, f2), 0.01);
262 EXPECT_NEAR(0, magnitude_at(data1, len, f4), 0.01);
263
264 // high band
265 EXPECT_NEAR(0, magnitude_at(data2, len, f0), 0.01);
266 EXPECT_NEAR(0, magnitude_at(data2, len, f2), 0.01);
267 EXPECT_NEAR(1, magnitude_at(data2, len, f4), 0.01);
268
269 /* Test for empty input */
270 crossover_process(&xo, 0, NULL, NULL, NULL);
271
272 free(data);
273 free(data1);
274 free(data2);
275 }
276
TEST(Crossover2Test,All)277 TEST(Crossover2Test, All) {
278 struct crossover2 xo2;
279 size_t len = 44100;
280 float NQ = len / 2;
281 float f0 = 62.5 / NQ;
282 float f1 = 250 / NQ;
283 float f2 = 1000 / NQ;
284 float f3 = 4000 / NQ;
285 float f4 = 16000 / NQ;
286 float* data0L = (float*)malloc(sizeof(float) * len);
287 float* data1L = (float*)malloc(sizeof(float) * len);
288 float* data2L = (float*)malloc(sizeof(float) * len);
289 float* data0R = (float*)malloc(sizeof(float) * len);
290 float* data1R = (float*)malloc(sizeof(float) * len);
291 float* data2R = (float*)malloc(sizeof(float) * len);
292
293 dsp_enable_flush_denormal_to_zero();
294 crossover2_init(&xo2, f1, f3);
295 memset(data0L, 0, sizeof(float) * len);
296 memset(data0R, 0, sizeof(float) * len);
297
298 add_sine(data0L, len, f0, 0, 1);
299 add_sine(data0L, len, f2, 0, 1);
300 add_sine(data0L, len, f4, 0, 1);
301
302 add_sine(data0R, len, f0, 0, 0.5);
303 add_sine(data0R, len, f2, 0, 0.5);
304 add_sine(data0R, len, f4, 0, 0.5);
305
306 crossover2_process(&xo2, len, data0L, data0R, data1L, data1R, data2L, data2R);
307
308 // left low band
309 EXPECT_NEAR(1, magnitude_at(data0L, len, f0), 0.01);
310 EXPECT_NEAR(0, magnitude_at(data0L, len, f2), 0.01);
311 EXPECT_NEAR(0, magnitude_at(data0L, len, f4), 0.01);
312
313 // left mid band
314 EXPECT_NEAR(0, magnitude_at(data1L, len, f0), 0.01);
315 EXPECT_NEAR(1, magnitude_at(data1L, len, f2), 0.01);
316 EXPECT_NEAR(0, magnitude_at(data1L, len, f4), 0.01);
317
318 // left high band
319 EXPECT_NEAR(0, magnitude_at(data2L, len, f0), 0.01);
320 EXPECT_NEAR(0, magnitude_at(data2L, len, f2), 0.01);
321 EXPECT_NEAR(1, magnitude_at(data2L, len, f4), 0.01);
322
323 // right low band
324 EXPECT_NEAR(0.5, magnitude_at(data0R, len, f0), 0.005);
325 EXPECT_NEAR(0, magnitude_at(data0R, len, f2), 0.005);
326 EXPECT_NEAR(0, magnitude_at(data0R, len, f4), 0.005);
327
328 // right mid band
329 EXPECT_NEAR(0, magnitude_at(data1R, len, f0), 0.005);
330 EXPECT_NEAR(0.5, magnitude_at(data1R, len, f2), 0.005);
331 EXPECT_NEAR(0, magnitude_at(data1R, len, f4), 0.005);
332
333 // right high band
334 EXPECT_NEAR(0, magnitude_at(data2R, len, f0), 0.005);
335 EXPECT_NEAR(0, magnitude_at(data2R, len, f2), 0.005);
336 EXPECT_NEAR(0.5, magnitude_at(data2R, len, f4), 0.005);
337
338 /* Test for empty input */
339 crossover2_process(&xo2, 0, NULL, NULL, NULL, NULL, NULL, NULL);
340
341 free(data0L);
342 free(data1L);
343 free(data2L);
344 free(data0R);
345 free(data1R);
346 free(data2R);
347 }
348
TEST(DrcTest,All)349 TEST(DrcTest, All) {
350 size_t len = 44100;
351 float NQ = len / 2;
352 float f0 = 62.5 / NQ;
353 float f1 = 250 / NQ;
354 float f2 = 1000 / NQ;
355 float f3 = 4000 / NQ;
356 float f4 = 16000 / NQ;
357 float* data_left = (float*)malloc(sizeof(float) * len);
358 float* data_right = (float*)malloc(sizeof(float) * len);
359 float* data[] = {data_left, data_right};
360 float* data_empty[] = {NULL, NULL};
361 struct drc* drc;
362
363 dsp_enable_flush_denormal_to_zero();
364 drc = drc_new(44100);
365
366 drc_set_param(drc, 0, PARAM_CROSSOVER_LOWER_FREQ, 0);
367 drc_set_param(drc, 0, PARAM_ENABLED, 1);
368 drc_set_param(drc, 0, PARAM_THRESHOLD, -30);
369 drc_set_param(drc, 0, PARAM_KNEE, 0);
370 drc_set_param(drc, 0, PARAM_RATIO, 3);
371 drc_set_param(drc, 0, PARAM_ATTACK, 0.02);
372 drc_set_param(drc, 0, PARAM_RELEASE, 0.2);
373 drc_set_param(drc, 0, PARAM_POST_GAIN, 0);
374
375 drc_set_param(drc, 1, PARAM_CROSSOVER_LOWER_FREQ, f1);
376 drc_set_param(drc, 1, PARAM_ENABLED, 0);
377 drc_set_param(drc, 1, PARAM_THRESHOLD, -30);
378 drc_set_param(drc, 1, PARAM_KNEE, 0);
379 drc_set_param(drc, 1, PARAM_RATIO, 3);
380 drc_set_param(drc, 1, PARAM_ATTACK, 0.02);
381 drc_set_param(drc, 1, PARAM_RELEASE, 0.2);
382 drc_set_param(drc, 1, PARAM_POST_GAIN, 0);
383
384 drc_set_param(drc, 2, PARAM_CROSSOVER_LOWER_FREQ, f3);
385 drc_set_param(drc, 2, PARAM_ENABLED, 1);
386 drc_set_param(drc, 2, PARAM_THRESHOLD, -30);
387 drc_set_param(drc, 2, PARAM_KNEE, 0);
388 drc_set_param(drc, 2, PARAM_RATIO, 1);
389 drc_set_param(drc, 2, PARAM_ATTACK, 0.02);
390 drc_set_param(drc, 2, PARAM_RELEASE, 0.2);
391 drc_set_param(drc, 2, PARAM_POST_GAIN, 20);
392
393 drc_init(drc);
394
395 memset(data_left, 0, sizeof(float) * len);
396 memset(data_right, 0, sizeof(float) * len);
397 add_sine(data_left, len, f0, 0, 1);
398 add_sine(data_left, len, f2, 0, 1);
399 add_sine(data_left, len, f4, 0, 1);
400 add_sine(data_right, len, f0, 0, 1);
401 add_sine(data_right, len, f2, 0, 1);
402 add_sine(data_right, len, f4, 0, 1);
403
404 for (size_t start = 0; start < len; start += DRC_PROCESS_MAX_FRAMES) {
405 int chunk = std::min(len - start, (size_t)DRC_PROCESS_MAX_FRAMES);
406 drc_process(drc, data, chunk);
407 data[0] += chunk;
408 data[1] += chunk;
409 }
410
411 /* This is -8dB because there is a 12dB makeup (20dB^0.6) inside the DRC */
412 EXPECT_NEAR(0.4, magnitude_at(data_right, len, f0), 0.1);
413
414 /* This is 0dB because the DRC is disabled */
415 EXPECT_NEAR(1, magnitude_at(data_right, len, f2), 0.1);
416
417 /* This is 20dB because of the post gain */
418 EXPECT_NEAR(10, magnitude_at(data_right, len, f4), 1);
419
420 /* Test for empty input */
421 drc_process(drc, data_empty, 0);
422
423 drc_free(drc);
424 free(data_left);
425 free(data_right);
426 }
427
428 } // namespace
429
main(int argc,char ** argv)430 int main(int argc, char** argv) {
431 ::testing::InitGoogleTest(&argc, argv);
432 return RUN_ALL_TESTS();
433 }
434