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