• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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