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