Home | History | Annotate | Download | only in tests
      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. */
     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. */
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    410 int main(int argc, char **argv) {
    411   ::testing::InitGoogleTest(&argc, argv);
    412   return RUN_ALL_TESTS();
    413 }
    414