OLD | NEW |
(Empty) | |
| 1 /* |
| 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 |
| 11 #include "webrtc/modules/audio_processing/aec3/suppression_gain.h" |
| 12 |
| 13 #include "webrtc/typedefs.h" |
| 14 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
| 15 #include "webrtc/test/gtest.h" |
| 16 |
| 17 namespace webrtc { |
| 18 namespace aec3 { |
| 19 |
| 20 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| 21 |
| 22 // Verifies that the check for non-null output gains works. |
| 23 TEST(SuppressionGain, NullOutputGains) { |
| 24 std::array<float, kFftLengthBy2Plus1> E2; |
| 25 std::array<float, kFftLengthBy2Plus1> R2; |
| 26 std::array<float, kFftLengthBy2Plus1> N2; |
| 27 EXPECT_DEATH( |
| 28 SuppressionGain(DetectOptimization()).GetGain(E2, R2, N2, 0.1f, nullptr), |
| 29 ""); |
| 30 } |
| 31 |
| 32 #endif |
| 33 |
| 34 #if defined(WEBRTC_ARCH_X86_FAMILY) |
| 35 // Verifies that the optimized methods are bitexact to their reference |
| 36 // counterparts. |
| 37 TEST(SuppressionGain, TestOptimizations) { |
| 38 if (WebRtc_GetCPUInfo(kSSE2) != 0) { |
| 39 std::array<float, kFftLengthBy2 - 1> G2_old; |
| 40 std::array<float, kFftLengthBy2 - 1> M2_old; |
| 41 std::array<float, kFftLengthBy2 - 1> G2_old_SSE2; |
| 42 std::array<float, kFftLengthBy2 - 1> M2_old_SSE2; |
| 43 std::array<float, kFftLengthBy2Plus1> E2; |
| 44 std::array<float, kFftLengthBy2Plus1> R2; |
| 45 std::array<float, kFftLengthBy2Plus1> N2; |
| 46 std::array<float, kFftLengthBy2Plus1> g; |
| 47 std::array<float, kFftLengthBy2Plus1> g_SSE2; |
| 48 |
| 49 G2_old.fill(1.f); |
| 50 M2_old.fill(.23f); |
| 51 G2_old_SSE2.fill(1.f); |
| 52 M2_old_SSE2.fill(.23f); |
| 53 |
| 54 E2.fill(10.f); |
| 55 R2.fill(0.1f); |
| 56 N2.fill(100.f); |
| 57 for (int k = 0; k < 10; ++k) { |
| 58 ComputeGains(E2, R2, N2, 0.1f, &G2_old, &M2_old, &g); |
| 59 ComputeGains_SSE2(E2, R2, N2, 0.1f, &G2_old_SSE2, &M2_old_SSE2, &g_SSE2); |
| 60 for (size_t j = 0; j < G2_old.size(); ++j) { |
| 61 EXPECT_NEAR(G2_old[j], G2_old_SSE2[j], 0.0000001f); |
| 62 } |
| 63 for (size_t j = 0; j < M2_old.size(); ++j) { |
| 64 EXPECT_NEAR(M2_old[j], M2_old_SSE2[j], 0.0000001f); |
| 65 } |
| 66 for (size_t j = 0; j < g.size(); ++j) { |
| 67 EXPECT_NEAR(g[j], g_SSE2[j], 0.0000001f); |
| 68 } |
| 69 } |
| 70 |
| 71 E2.fill(100.f); |
| 72 R2.fill(0.1f); |
| 73 N2.fill(0.f); |
| 74 for (int k = 0; k < 10; ++k) { |
| 75 ComputeGains(E2, R2, N2, 0.1f, &G2_old, &M2_old, &g); |
| 76 ComputeGains_SSE2(E2, R2, N2, 0.1f, &G2_old_SSE2, &M2_old_SSE2, &g_SSE2); |
| 77 for (size_t j = 0; j < G2_old.size(); ++j) { |
| 78 EXPECT_NEAR(G2_old[j], G2_old_SSE2[j], 0.0000001f); |
| 79 } |
| 80 for (size_t j = 0; j < M2_old.size(); ++j) { |
| 81 EXPECT_NEAR(M2_old[j], M2_old_SSE2[j], 0.0000001f); |
| 82 } |
| 83 for (size_t j = 0; j < g.size(); ++j) { |
| 84 EXPECT_NEAR(g[j], g_SSE2[j], 0.0000001f); |
| 85 } |
| 86 } |
| 87 |
| 88 E2.fill(0.1f); |
| 89 R2.fill(100.f); |
| 90 N2.fill(0.f); |
| 91 for (int k = 0; k < 10; ++k) { |
| 92 ComputeGains(E2, R2, N2, 0.1f, &G2_old, &M2_old, &g); |
| 93 ComputeGains_SSE2(E2, R2, N2, 0.1f, &G2_old_SSE2, &M2_old_SSE2, &g_SSE2); |
| 94 for (size_t j = 0; j < G2_old.size(); ++j) { |
| 95 EXPECT_NEAR(G2_old[j], G2_old_SSE2[j], 0.0000001f); |
| 96 } |
| 97 for (size_t j = 0; j < M2_old.size(); ++j) { |
| 98 EXPECT_NEAR(M2_old[j], M2_old_SSE2[j], 0.0000001f); |
| 99 } |
| 100 for (size_t j = 0; j < g.size(); ++j) { |
| 101 EXPECT_NEAR(g[j], g_SSE2[j], 0.0000001f); |
| 102 } |
| 103 } |
| 104 } |
| 105 } |
| 106 #endif |
| 107 |
| 108 // Does a sanity check that the gains are correctly computed. |
| 109 TEST(SuppressionGain, BasicGainComputation) { |
| 110 SuppressionGain suppression_gain(DetectOptimization()); |
| 111 std::array<float, kFftLengthBy2Plus1> E2; |
| 112 std::array<float, kFftLengthBy2Plus1> R2; |
| 113 std::array<float, kFftLengthBy2Plus1> N2; |
| 114 std::array<float, kFftLengthBy2Plus1> g; |
| 115 |
| 116 // Ensure that a strong noise is detected to mask any echoes. |
| 117 E2.fill(10.f); |
| 118 R2.fill(0.1f); |
| 119 N2.fill(100.f); |
| 120 for (int k = 0; k < 10; ++k) { |
| 121 suppression_gain.GetGain(E2, R2, N2, 0.1f, &g); |
| 122 } |
| 123 std::for_each(g.begin(), g.end(), |
| 124 [](float a) { EXPECT_NEAR(1.f, a, 0.001); }); |
| 125 |
| 126 // Ensure that a strong nearend is detected to mask any echoes. |
| 127 E2.fill(100.f); |
| 128 R2.fill(0.1f); |
| 129 N2.fill(0.f); |
| 130 for (int k = 0; k < 10; ++k) { |
| 131 suppression_gain.GetGain(E2, R2, N2, 0.1f, &g); |
| 132 } |
| 133 std::for_each(g.begin(), g.end(), |
| 134 [](float a) { EXPECT_NEAR(1.f, a, 0.001); }); |
| 135 |
| 136 // Ensure that a strong echo is suppressed. |
| 137 E2.fill(0.1f); |
| 138 R2.fill(100.f); |
| 139 N2.fill(0.f); |
| 140 for (int k = 0; k < 10; ++k) { |
| 141 suppression_gain.GetGain(E2, R2, N2, 0.1f, &g); |
| 142 } |
| 143 std::for_each(g.begin(), g.end(), |
| 144 [](float a) { EXPECT_NEAR(0.f, a, 0.001); }); |
| 145 } |
| 146 |
| 147 } // namespace aec3 |
| 148 } // namespace webrtc |
OLD | NEW |