blob: e6f5ea0403423213bb9f4a8aa5cdf009329eb135 [file] [log] [blame]
peah21920892017-02-08 05:08:56 -08001/*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Per Åhgren38e2d952017-11-17 14:54:28 +010011#include "modules/audio_processing/aec3/decimator.h"
peah21920892017-02-08 05:08:56 -080012
13#include <math.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
peah21920892017-02-08 05:08:56 -080015#include <algorithm>
16#include <array>
Mirko Bonadeidbce0902019-03-15 07:39:02 +010017#include <cmath>
Gustaf Ullbergee84d392019-09-10 09:36:43 +020018#include <cstring>
peah21920892017-02-08 05:08:56 -080019#include <numeric>
peah21920892017-02-08 05:08:56 -080020#include <string>
21#include <vector>
22
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/audio_processing/aec3/aec3_common.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020024#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "test/gtest.h"
peah21920892017-02-08 05:08:56 -080026
27namespace webrtc {
28
29namespace {
30
31std::string ProduceDebugText(int sample_rate_hz) {
Jonas Olsson366a50c2018-09-06 13:41:30 +020032 rtc::StringBuilder ss;
peah21920892017-02-08 05:08:56 -080033 ss << "Sample rate: " << sample_rate_hz;
Jonas Olsson84df1c72018-09-14 16:59:32 +020034 return ss.Release();
peah21920892017-02-08 05:08:56 -080035}
36
Per Åhgren38e2d952017-11-17 14:54:28 +010037constexpr size_t kDownSamplingFactors[] = {2, 4, 8};
peah21920892017-02-08 05:08:56 -080038constexpr float kPi = 3.141592f;
39constexpr size_t kNumStartupBlocks = 50;
40constexpr size_t kNumBlocks = 1000;
41
42void ProduceDecimatedSinusoidalOutputPower(int sample_rate_hz,
Per Åhgren38e2d952017-11-17 14:54:28 +010043 size_t down_sampling_factor,
peah21920892017-02-08 05:08:56 -080044 float sinusoidal_frequency_hz,
45 float* input_power,
46 float* output_power) {
47 float input[kBlockSize * kNumBlocks];
Per Åhgren38e2d952017-11-17 14:54:28 +010048 const size_t sub_block_size = kBlockSize / down_sampling_factor;
peah21920892017-02-08 05:08:56 -080049
50 // Produce a sinusoid of the specified frequency.
51 for (size_t k = 0; k < kBlockSize * kNumBlocks; ++k) {
Mirko Bonadeidbce0902019-03-15 07:39:02 +010052 input[k] = 32767.f * std::sin(2.f * kPi * sinusoidal_frequency_hz * k /
53 sample_rate_hz);
peah21920892017-02-08 05:08:56 -080054 }
55
Per Åhgren38e2d952017-11-17 14:54:28 +010056 Decimator decimator(down_sampling_factor);
57 std::vector<float> output(sub_block_size * kNumBlocks);
peah21920892017-02-08 05:08:56 -080058
59 for (size_t k = 0; k < kNumBlocks; ++k) {
Per Åhgren38e2d952017-11-17 14:54:28 +010060 std::vector<float> sub_block(sub_block_size);
Per Åhgren6a05bb12019-12-03 11:24:59 +010061 decimator.Decimate(
62 rtc::ArrayView<const float>(&input[k * kBlockSize], kBlockSize),
63 sub_block);
peah21920892017-02-08 05:08:56 -080064
65 std::copy(sub_block.begin(), sub_block.end(),
Per Åhgren38e2d952017-11-17 14:54:28 +010066 output.begin() + k * sub_block_size);
peah21920892017-02-08 05:08:56 -080067 }
68
69 ASSERT_GT(kNumBlocks, kNumStartupBlocks);
70 rtc::ArrayView<const float> input_to_evaluate(
71 &input[kNumStartupBlocks * kBlockSize],
72 (kNumBlocks - kNumStartupBlocks) * kBlockSize);
73 rtc::ArrayView<const float> output_to_evaluate(
Per Åhgren38e2d952017-11-17 14:54:28 +010074 &output[kNumStartupBlocks * sub_block_size],
75 (kNumBlocks - kNumStartupBlocks) * sub_block_size);
peah21920892017-02-08 05:08:56 -080076 *input_power =
77 std::inner_product(input_to_evaluate.begin(), input_to_evaluate.end(),
78 input_to_evaluate.begin(), 0.f) /
79 input_to_evaluate.size();
80 *output_power =
81 std::inner_product(output_to_evaluate.begin(), output_to_evaluate.end(),
82 output_to_evaluate.begin(), 0.f) /
83 output_to_evaluate.size();
84}
85
86} // namespace
87
88// Verifies that there is little aliasing from upper frequencies in the
89// downsampling.
Per Åhgren38e2d952017-11-17 14:54:28 +010090TEST(Decimator, NoLeakageFromUpperFrequencies) {
peah21920892017-02-08 05:08:56 -080091 float input_power;
92 float output_power;
Per Åhgrence202a02019-09-02 17:01:19 +020093 for (auto rate : {16000, 32000, 48000}) {
Per Åhgren38e2d952017-11-17 14:54:28 +010094 for (auto down_sampling_factor : kDownSamplingFactors) {
95 ProduceDebugText(rate);
96 ProduceDecimatedSinusoidalOutputPower(rate, down_sampling_factor,
97 3.f / 8.f * rate, &input_power,
98 &output_power);
99 EXPECT_GT(0.0001f * input_power, output_power);
100 }
peah21920892017-02-08 05:08:56 -0800101 }
102}
103
peah21920892017-02-08 05:08:56 -0800104#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
105// Verifies the check for the input size.
Tommia5e07cc2020-05-26 21:40:37 +0200106TEST(DecimatorDeathTest, WrongInputSize) {
Per Åhgren38e2d952017-11-17 14:54:28 +0100107 Decimator decimator(4);
Per Åhgren6a05bb12019-12-03 11:24:59 +0100108 std::vector<float> x(kBlockSize - 1, 0.f);
Per Åhgren38e2d952017-11-17 14:54:28 +0100109 std::array<float, kBlockSize / 4> x_downsampled;
Per Åhgren6a05bb12019-12-03 11:24:59 +0100110 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
peah21920892017-02-08 05:08:56 -0800111}
112
113// Verifies the check for non-null output parameter.
Tommia5e07cc2020-05-26 21:40:37 +0200114TEST(DecimatorDeathTest, NullOutput) {
Per Åhgren38e2d952017-11-17 14:54:28 +0100115 Decimator decimator(4);
Per Åhgren6a05bb12019-12-03 11:24:59 +0100116 std::vector<float> x(kBlockSize, 0.f);
117 EXPECT_DEATH(decimator.Decimate(x, nullptr), "");
peah21920892017-02-08 05:08:56 -0800118}
119
Per Åhgren38e2d952017-11-17 14:54:28 +0100120// Verifies the check for the output size.
Tommia5e07cc2020-05-26 21:40:37 +0200121TEST(DecimatorDeathTest, WrongOutputSize) {
Per Åhgren38e2d952017-11-17 14:54:28 +0100122 Decimator decimator(4);
Per Åhgren6a05bb12019-12-03 11:24:59 +0100123 std::vector<float> x(kBlockSize, 0.f);
Per Åhgren38e2d952017-11-17 14:54:28 +0100124 std::array<float, kBlockSize / 4 - 1> x_downsampled;
Per Åhgren6a05bb12019-12-03 11:24:59 +0100125 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
Per Åhgren38e2d952017-11-17 14:54:28 +0100126}
127
128// Verifies the check for the correct downsampling factor.
Tommia5e07cc2020-05-26 21:40:37 +0200129TEST(DecimatorDeathTest, CorrectDownSamplingFactor) {
Per Åhgren38e2d952017-11-17 14:54:28 +0100130 EXPECT_DEATH(Decimator(3), "");
131}
132
peah21920892017-02-08 05:08:56 -0800133#endif
134
135} // namespace webrtc