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