blob: cf8de84a2bdc45bf0d745f34c16d1f939439b055 [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>
peah21920892017-02-08 05:08:56 -080018#include <numeric>
peah21920892017-02-08 05:08:56 -080019#include <string>
20#include <vector>
21
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/audio_processing/aec3/aec3_common.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020023#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "test/gtest.h"
peah21920892017-02-08 05:08:56 -080025
26namespace webrtc {
27
28namespace {
29
30std::string ProduceDebugText(int sample_rate_hz) {
Jonas Olsson366a50c2018-09-06 13:41:30 +020031 rtc::StringBuilder ss;
peah21920892017-02-08 05:08:56 -080032 ss << "Sample rate: " << sample_rate_hz;
Jonas Olsson84df1c72018-09-14 16:59:32 +020033 return ss.Release();
peah21920892017-02-08 05:08:56 -080034}
35
Per Åhgren38e2d952017-11-17 14:54:28 +010036constexpr size_t kDownSamplingFactors[] = {2, 4, 8};
peah21920892017-02-08 05:08:56 -080037constexpr float kPi = 3.141592f;
38constexpr size_t kNumStartupBlocks = 50;
39constexpr size_t kNumBlocks = 1000;
40
41void ProduceDecimatedSinusoidalOutputPower(int sample_rate_hz,
Per Åhgren38e2d952017-11-17 14:54:28 +010042 size_t down_sampling_factor,
peah21920892017-02-08 05:08:56 -080043 float sinusoidal_frequency_hz,
44 float* input_power,
45 float* output_power) {
46 float input[kBlockSize * kNumBlocks];
Per Åhgren38e2d952017-11-17 14:54:28 +010047 const size_t sub_block_size = kBlockSize / down_sampling_factor;
peah21920892017-02-08 05:08:56 -080048
49 // Produce a sinusoid of the specified frequency.
50 for (size_t k = 0; k < kBlockSize * kNumBlocks; ++k) {
Mirko Bonadeidbce0902019-03-15 07:39:02 +010051 input[k] = 32767.f * std::sin(2.f * kPi * sinusoidal_frequency_hz * k /
52 sample_rate_hz);
peah21920892017-02-08 05:08:56 -080053 }
54
Per Åhgren38e2d952017-11-17 14:54:28 +010055 Decimator decimator(down_sampling_factor);
56 std::vector<float> output(sub_block_size * kNumBlocks);
peah21920892017-02-08 05:08:56 -080057
58 for (size_t k = 0; k < kNumBlocks; ++k) {
Per Åhgren38e2d952017-11-17 14:54:28 +010059 std::vector<float> sub_block(sub_block_size);
peah21920892017-02-08 05:08:56 -080060
61 decimator.Decimate(
62 rtc::ArrayView<const float>(&input[k * kBlockSize], kBlockSize),
peahcf02cf12017-04-05 14:18:07 -070063 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;
93 for (auto rate : {8000, 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.
Per Åhgren38e2d952017-11-17 14:54:28 +0100106TEST(Decimator, WrongInputSize) {
107 Decimator decimator(4);
peah21920892017-02-08 05:08:56 -0800108 std::vector<float> x(std::vector<float>(kBlockSize - 1, 0.f));
Per Åhgren38e2d952017-11-17 14:54:28 +0100109 std::array<float, kBlockSize / 4> x_downsampled;
peahcf02cf12017-04-05 14:18:07 -0700110 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
peah21920892017-02-08 05:08:56 -0800111}
112
113// Verifies the check for non-null output parameter.
Per Åhgren38e2d952017-11-17 14:54:28 +0100114TEST(Decimator, NullOutput) {
115 Decimator decimator(4);
peah21920892017-02-08 05:08:56 -0800116 std::vector<float> x(std::vector<float>(kBlockSize, 0.f));
117 EXPECT_DEATH(decimator.Decimate(x, nullptr), "");
118}
119
Per Åhgren38e2d952017-11-17 14:54:28 +0100120// Verifies the check for the output size.
121TEST(Decimator, WrongOutputSize) {
122 Decimator decimator(4);
123 std::vector<float> x(std::vector<float>(kBlockSize, 0.f));
124 std::array<float, kBlockSize / 4 - 1> x_downsampled;
125 EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
126}
127
128// Verifies the check for the correct downsampling factor.
129TEST(Decimator, CorrectDownSamplingFactor) {
130 EXPECT_DEATH(Decimator(3), "");
131}
132
peah21920892017-02-08 05:08:56 -0800133#endif
134
135} // namespace webrtc