blob: 79e74403b172223d9ab27d53a7b554eb9b45f55e [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>
14#include <algorithm>
15#include <array>
Mirko Bonadeidbce0902019-03-15 07:39:02 +010016#include <cmath>
peah21920892017-02-08 05:08:56 -080017#include <numeric>
peah21920892017-02-08 05:08:56 -080018#include <string>
19#include <vector>
20
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/audio_processing/aec3/aec3_common.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020022#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "test/gtest.h"
peah21920892017-02-08 05:08:56 -080024
25namespace webrtc {
26
27namespace {
28
29std::string ProduceDebugText(int sample_rate_hz) {
Jonas Olsson366a50c2018-09-06 13:41:30 +020030 rtc::StringBuilder ss;
peah21920892017-02-08 05:08:56 -080031 ss << "Sample rate: " << sample_rate_hz;
Jonas Olsson84df1c72018-09-14 16:59:32 +020032 return ss.Release();
peah21920892017-02-08 05:08:56 -080033}
34
Per Åhgren38e2d952017-11-17 14:54:28 +010035constexpr size_t kDownSamplingFactors[] = {2, 4, 8};
peah21920892017-02-08 05:08:56 -080036constexpr float kPi = 3.141592f;
37constexpr size_t kNumStartupBlocks = 50;
38constexpr size_t kNumBlocks = 1000;
39
40void ProduceDecimatedSinusoidalOutputPower(int sample_rate_hz,
Per Åhgren38e2d952017-11-17 14:54:28 +010041 size_t down_sampling_factor,
peah21920892017-02-08 05:08:56 -080042 float sinusoidal_frequency_hz,
43 float* input_power,
44 float* output_power) {
45 float input[kBlockSize * kNumBlocks];
Per Åhgren38e2d952017-11-17 14:54:28 +010046 const size_t sub_block_size = kBlockSize / down_sampling_factor;
peah21920892017-02-08 05:08:56 -080047
48 // Produce a sinusoid of the specified frequency.
49 for (size_t k = 0; k < kBlockSize * kNumBlocks; ++k) {
Mirko Bonadeidbce0902019-03-15 07:39:02 +010050 input[k] = 32767.f * std::sin(2.f * kPi * sinusoidal_frequency_hz * k /
51 sample_rate_hz);
peah21920892017-02-08 05:08:56 -080052 }
53
Per Åhgren38e2d952017-11-17 14:54:28 +010054 Decimator decimator(down_sampling_factor);
55 std::vector<float> output(sub_block_size * kNumBlocks);
peah21920892017-02-08 05:08:56 -080056
57 for (size_t k = 0; k < kNumBlocks; ++k) {
Per Åhgren38e2d952017-11-17 14:54:28 +010058 std::vector<float> sub_block(sub_block_size);
peah21920892017-02-08 05:08:56 -080059
60 decimator.Decimate(
61 rtc::ArrayView<const float>(&input[k * kBlockSize], kBlockSize),
peahcf02cf12017-04-05 14:18:07 -070062 sub_block);
peah21920892017-02-08 05:08:56 -080063
64 std::copy(sub_block.begin(), sub_block.end(),
Per Åhgren38e2d952017-11-17 14:54:28 +010065 output.begin() + k * sub_block_size);
peah21920892017-02-08 05:08:56 -080066 }
67
68 ASSERT_GT(kNumBlocks, kNumStartupBlocks);
69 rtc::ArrayView<const float> input_to_evaluate(
70 &input[kNumStartupBlocks * kBlockSize],
71 (kNumBlocks - kNumStartupBlocks) * kBlockSize);
72 rtc::ArrayView<const float> output_to_evaluate(
Per Åhgren38e2d952017-11-17 14:54:28 +010073 &output[kNumStartupBlocks * sub_block_size],
74 (kNumBlocks - kNumStartupBlocks) * sub_block_size);
peah21920892017-02-08 05:08:56 -080075 *input_power =
76 std::inner_product(input_to_evaluate.begin(), input_to_evaluate.end(),
77 input_to_evaluate.begin(), 0.f) /
78 input_to_evaluate.size();
79 *output_power =
80 std::inner_product(output_to_evaluate.begin(), output_to_evaluate.end(),
81 output_to_evaluate.begin(), 0.f) /
82 output_to_evaluate.size();
83}
84
85} // namespace
86
87// Verifies that there is little aliasing from upper frequencies in the
88// downsampling.
Per Åhgren38e2d952017-11-17 14:54:28 +010089TEST(Decimator, NoLeakageFromUpperFrequencies) {
peah21920892017-02-08 05:08:56 -080090 float input_power;
91 float output_power;
92 for (auto rate : {8000, 16000, 32000, 48000}) {
Per Åhgren38e2d952017-11-17 14:54:28 +010093 for (auto down_sampling_factor : kDownSamplingFactors) {
94 ProduceDebugText(rate);
95 ProduceDecimatedSinusoidalOutputPower(rate, down_sampling_factor,
96 3.f / 8.f * rate, &input_power,
97 &output_power);
98 EXPECT_GT(0.0001f * input_power, output_power);
99 }
peah21920892017-02-08 05:08:56 -0800100 }
101}
102
peah21920892017-02-08 05:08:56 -0800103#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
104// Verifies the check for the input size.
Per Åhgren38e2d952017-11-17 14:54:28 +0100105TEST(Decimator, WrongInputSize) {
106 Decimator decimator(4);
peah21920892017-02-08 05:08:56 -0800107 std::vector<float> x(std::vector<float>(kBlockSize - 1, 0.f));
Per Åhgren38e2d952017-11-17 14:54:28 +0100108 std::array<float, kBlockSize / 4> x_downsampled;
peahcf02cf12017-04-05 14:18:07 -0700109 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
peah21920892017-02-08 05:08:56 -0800110}
111
112// Verifies the check for non-null output parameter.
Per Åhgren38e2d952017-11-17 14:54:28 +0100113TEST(Decimator, NullOutput) {
114 Decimator decimator(4);
peah21920892017-02-08 05:08:56 -0800115 std::vector<float> x(std::vector<float>(kBlockSize, 0.f));
116 EXPECT_DEATH(decimator.Decimate(x, nullptr), "");
117}
118
Per Åhgren38e2d952017-11-17 14:54:28 +0100119// Verifies the check for the output size.
120TEST(Decimator, WrongOutputSize) {
121 Decimator decimator(4);
122 std::vector<float> x(std::vector<float>(kBlockSize, 0.f));
123 std::array<float, kBlockSize / 4 - 1> x_downsampled;
124 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
125}
126
127// Verifies the check for the correct downsampling factor.
128TEST(Decimator, CorrectDownSamplingFactor) {
129 EXPECT_DEATH(Decimator(3), "");
130}
131
peah21920892017-02-08 05:08:56 -0800132#endif
133
134} // namespace webrtc