1 /*
2 * Copyright (c) 2016 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
11 #include "modules/audio_processing/ns/noise_suppressor.h"
12
13 #include <deque>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18
19 #include "rtc_base/strings/string_builder.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22
23 namespace webrtc {
24 namespace {
25
ProduceDebugText(int sample_rate_hz,size_t num_channels,NsConfig::SuppressionLevel level)26 std::string ProduceDebugText(int sample_rate_hz,
27 size_t num_channels,
28 NsConfig::SuppressionLevel level) {
29 rtc::StringBuilder ss;
30 ss << "Sample rate: " << sample_rate_hz << ", num_channels: " << num_channels
31 << ", level: " << static_cast<int>(level);
32 return ss.Release();
33 }
34
PopulateInputFrameWithIdenticalChannels(size_t num_channels,size_t num_bands,size_t frame_index,AudioBuffer * audio)35 void PopulateInputFrameWithIdenticalChannels(size_t num_channels,
36 size_t num_bands,
37 size_t frame_index,
38 AudioBuffer* audio) {
39 for (size_t ch = 0; ch < num_channels; ++ch) {
40 for (size_t b = 0; b < num_bands; ++b) {
41 for (size_t i = 0; i < 160; ++i) {
42 float value = static_cast<int>(frame_index * 160 + i);
43 audio->split_bands(ch)[b][i] = (value > 0 ? 5000 * b + value : 0);
44 }
45 }
46 }
47 }
48
VerifyIdenticalChannels(size_t num_channels,size_t num_bands,size_t frame_index,const AudioBuffer & audio)49 void VerifyIdenticalChannels(size_t num_channels,
50 size_t num_bands,
51 size_t frame_index,
52 const AudioBuffer& audio) {
53 EXPECT_GT(num_channels, 1u);
54 for (size_t ch = 1; ch < num_channels; ++ch) {
55 for (size_t b = 0; b < num_bands; ++b) {
56 for (size_t i = 0; i < 160; ++i) {
57 EXPECT_EQ(audio.split_bands_const(ch)[b][i],
58 audio.split_bands_const(0)[b][i]);
59 }
60 }
61 }
62 }
63
64 } // namespace
65
66 // Verifies that the same noise reduction effect is applied to all channels.
TEST(NoiseSuppressor,IdenticalChannelEffects)67 TEST(NoiseSuppressor, IdenticalChannelEffects) {
68 for (auto rate : {16000, 32000, 48000}) {
69 for (auto num_channels : {1, 4, 8}) {
70 for (auto level :
71 {NsConfig::SuppressionLevel::k6dB, NsConfig::SuppressionLevel::k12dB,
72 NsConfig::SuppressionLevel::k18dB,
73 NsConfig::SuppressionLevel::k21dB}) {
74 SCOPED_TRACE(ProduceDebugText(rate, num_channels, level));
75
76 const size_t num_bands = rate / 16000;
77 // const int frame_length = rtc::CheckedDivExact(rate, 100);
78 AudioBuffer audio(rate, num_channels, rate, num_channels, rate,
79 num_channels);
80 NsConfig cfg;
81 NoiseSuppressor ns(cfg, rate, num_channels);
82 for (size_t frame_index = 0; frame_index < 1000; ++frame_index) {
83 if (rate > 16000) {
84 audio.SplitIntoFrequencyBands();
85 }
86
87 PopulateInputFrameWithIdenticalChannels(num_channels, num_bands,
88 frame_index, &audio);
89
90 ns.Analyze(audio);
91 ns.Process(&audio);
92 if (num_channels > 1) {
93 VerifyIdenticalChannels(num_channels, num_bands, frame_index,
94 audio);
95 }
96 }
97 }
98 }
99 }
100 }
101
102 } // namespace webrtc
103