Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: webrtc/modules/audio_processing/intelligibility/intelligibility_utils_unittest.cc

Issue 1693823004: Use VAD to get a better speech power estimation in the IntelligibilityEnhancer (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@pow
Patch Set: Make gain change limit relative Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 // 11 #include <cmath>
12 // Unit tests for intelligibility utils.
13 //
14
15 #include <math.h>
16 #include <complex> 12 #include <complex>
17 #include <iostream>
18 #include <vector> 13 #include <vector>
19 14
20 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
21 #include "webrtc/base/arraysize.h" 16 #include "webrtc/base/arraysize.h"
22 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils. h" 17 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils. h"
23 18
24 using std::complex;
25 using std::vector;
26
27 namespace webrtc { 19 namespace webrtc {
28 20
29 namespace intelligibility { 21 namespace intelligibility {
30 22
31 vector<vector<complex<float>>> GenerateTestData(int freqs, int samples) { 23 std::vector<std::vector<std::complex<float>>> GenerateTestData(size_t freqs,
32 vector<vector<complex<float>>> data(samples); 24 size_t samples) {
33 for (int i = 0; i < samples; i++) { 25 std::vector<std::vector<std::complex<float>>> data(samples);
34 for (int j = 0; j < freqs; j++) { 26 for (size_t i = 0; i < samples; ++i) {
27 for (size_t j = 0; j < freqs; ++j) {
35 const float val = 0.99f / ((i + 1) * (j + 1)); 28 const float val = 0.99f / ((i + 1) * (j + 1));
36 data[i].push_back(complex<float>(val, val)); 29 data[i].push_back(std::complex<float>(val, val));
37 } 30 }
38 } 31 }
39 return data; 32 return data;
40 } 33 }
41 34
42 // Tests UpdateFactor. 35 // Tests PowerEstimator, for all power step types.
43 TEST(IntelligibilityUtilsTest, TestUpdateFactor) { 36 TEST(IntelligibilityUtilsTest, TestPowerEstimator) {
44 EXPECT_EQ(0, intelligibility::UpdateFactor(0, 0, 0)); 37 const size_t kFreqs = 10;
45 EXPECT_EQ(4, intelligibility::UpdateFactor(4, 2, 3)); 38 const size_t kSamples = 100;
46 EXPECT_EQ(3, intelligibility::UpdateFactor(4, 2, 1)); 39 const float kDecay = 0.5f;
47 EXPECT_EQ(2, intelligibility::UpdateFactor(2, 4, 3)); 40 const std::vector<std::vector<std::complex<float>>> test_data(
48 EXPECT_EQ(3, intelligibility::UpdateFactor(2, 4, 1)); 41 GenerateTestData(kFreqs, kSamples));
49 } 42 PowerEstimator power_estimator(kFreqs, kDecay);
43 EXPECT_EQ(0, power_estimator.power()[0]);
50 44
51 // Tests zerofudge. 45 // Makes sure Step is doing something.
52 TEST(IntelligibilityUtilsTest, TestCplx) { 46 power_estimator.Step(&test_data[0][0]);
53 complex<float> t0(1.f, 0.f); 47 for (size_t i = 1; i < kSamples; ++i) {
54 t0 = intelligibility::zerofudge(t0); 48 power_estimator.Step(&test_data[i][0]);
55 EXPECT_NE(t0.imag(), 0.f); 49 for (size_t j = 0; j < kFreqs; ++j) {
56 EXPECT_NE(t0.real(), 0.f); 50 EXPECT_GE(power_estimator.power()[j], 0.f);
57 } 51 EXPECT_LE(power_estimator.power()[j], 1.f);
58
59 // Tests NewMean and AddToMean.
60 TEST(IntelligibilityUtilsTest, TestMeanUpdate) {
61 const complex<float> data[] = {{3, 8}, {7, 6}, {2, 1}, {8, 9}, {0, 6}};
62 const complex<float> means[] = {{3, 8}, {5, 7}, {4, 5}, {5, 6}, {4, 6}};
63 complex<float> mean(3, 8);
64 for (size_t i = 0; i < arraysize(data); i++) {
65 EXPECT_EQ(means[i], NewMean(mean, data[i], i + 1));
66 AddToMean(data[i], i + 1, &mean);
67 EXPECT_EQ(means[i], mean);
68 }
69 }
70
71 // Tests VarianceArray, for all variance step types.
72 TEST(IntelligibilityUtilsTest, TestVarianceArray) {
73 const int kFreqs = 10;
74 const int kSamples = 100;
75 const int kWindowSize = 10; // Should pass for all kWindowSize > 1.
76 const float kDecay = 0.5f;
77 vector<VarianceArray::StepType> step_types;
78 step_types.push_back(VarianceArray::kStepInfinite);
79 step_types.push_back(VarianceArray::kStepDecaying);
80 step_types.push_back(VarianceArray::kStepWindowed);
81 step_types.push_back(VarianceArray::kStepBlocked);
82 step_types.push_back(VarianceArray::kStepBlockBasedMovingAverage);
83 const vector<vector<complex<float>>> test_data(
84 GenerateTestData(kFreqs, kSamples));
85 for (auto step_type : step_types) {
86 VarianceArray variance_array(kFreqs, step_type, kWindowSize, kDecay);
87 EXPECT_EQ(0, variance_array.variance()[0]);
88 EXPECT_EQ(0, variance_array.array_mean());
89 variance_array.ApplyScale(2.0f);
90 EXPECT_EQ(0, variance_array.variance()[0]);
91 EXPECT_EQ(0, variance_array.array_mean());
92
93 // Makes sure Step is doing something.
94 variance_array.Step(&test_data[0][0]);
95 for (int i = 1; i < kSamples; i++) {
96 variance_array.Step(&test_data[i][0]);
97 EXPECT_GE(variance_array.array_mean(), 0.0f);
98 EXPECT_LE(variance_array.array_mean(), 1.0f);
99 for (int j = 0; j < kFreqs; j++) {
100 EXPECT_GE(variance_array.variance()[j], 0.0f);
101 EXPECT_LE(variance_array.variance()[j], 1.0f);
102 }
103 }
104 variance_array.Clear();
105 EXPECT_EQ(0, variance_array.variance()[0]);
106 EXPECT_EQ(0, variance_array.array_mean());
107 }
108 }
109
110 // Tests exact computation on synthetic data.
111 TEST(IntelligibilityUtilsTest, TestMovingBlockAverage) {
112 // Exact, not unbiased estimates.
113 const float kTestVarianceBufferNotFull = 16.5f;
114 const float kTestVarianceBufferFull1 = 66.5f;
115 const float kTestVarianceBufferFull2 = 333.375f;
116 const int kFreqs = 2;
117 const int kSamples = 50;
118 const int kWindowSize = 2;
119 const float kDecay = 0.5f;
120 const float kMaxError = 0.0001f;
121
122 VarianceArray variance_array(
123 kFreqs, VarianceArray::kStepBlockBasedMovingAverage, kWindowSize, kDecay);
124
125 vector<vector<complex<float>>> test_data(kSamples);
126 for (int i = 0; i < kSamples; i++) {
127 for (int j = 0; j < kFreqs; j++) {
128 if (i < 30) {
129 test_data[i].push_back(complex<float>(static_cast<float>(kSamples - i),
130 static_cast<float>(i + 1)));
131 } else {
132 test_data[i].push_back(complex<float>(0.f, 0.f));
133 }
134 }
135 }
136
137 for (int i = 0; i < kSamples; i++) {
138 variance_array.Step(&test_data[i][0]);
139 for (int j = 0; j < kFreqs; j++) {
140 if (i < 9) { // In utils, kWindowBlockSize = 10.
141 EXPECT_EQ(0, variance_array.variance()[j]);
142 } else if (i < 19) {
143 EXPECT_NEAR(kTestVarianceBufferNotFull, variance_array.variance()[j],
144 kMaxError);
145 } else if (i < 39) {
146 EXPECT_NEAR(kTestVarianceBufferFull1, variance_array.variance()[j],
147 kMaxError);
148 } else if (i < 49) {
149 EXPECT_NEAR(kTestVarianceBufferFull2, variance_array.variance()[j],
150 kMaxError);
151 } else {
152 EXPECT_EQ(0, variance_array.variance()[j]);
153 }
154 } 52 }
155 } 53 }
156 } 54 }
157 55
158 // Tests gain applier. 56 // Tests gain applier.
159 TEST(IntelligibilityUtilsTest, TestGainApplier) { 57 TEST(IntelligibilityUtilsTest, TestGainApplier) {
160 const int kFreqs = 10; 58 const size_t kFreqs = 10;
161 const int kSamples = 100; 59 const size_t kSamples = 100;
162 const float kChangeLimit = 0.1f; 60 const float kChangeLimit = 0.1f;
163 GainApplier gain_applier(kFreqs, kChangeLimit); 61 GainApplier gain_applier(kFreqs, kChangeLimit);
164 const vector<vector<complex<float>>> in_data( 62 const std::vector<std::vector<std::complex<float>>> in_data(
165 GenerateTestData(kFreqs, kSamples)); 63 GenerateTestData(kFreqs, kSamples));
166 vector<vector<complex<float>>> out_data(GenerateTestData(kFreqs, kSamples)); 64 std::vector<std::vector<std::complex<float>>> out_data(
167 for (int i = 0; i < kSamples; i++) { 65 GenerateTestData(kFreqs, kSamples));
66 for (size_t i = 0; i < kSamples; ++i) {
168 gain_applier.Apply(&in_data[i][0], &out_data[i][0]); 67 gain_applier.Apply(&in_data[i][0], &out_data[i][0]);
169 for (int j = 0; j < kFreqs; j++) { 68 for (size_t j = 0; j < kFreqs; ++j) {
170 EXPECT_GT(out_data[i][j].real(), 0.0f); 69 EXPECT_GT(out_data[i][j].real(), 0.f);
171 EXPECT_LT(out_data[i][j].real(), 1.0f); 70 EXPECT_LT(out_data[i][j].real(), 1.f);
172 EXPECT_GT(out_data[i][j].imag(), 0.0f); 71 EXPECT_GT(out_data[i][j].imag(), 0.f);
173 EXPECT_LT(out_data[i][j].imag(), 1.0f); 72 EXPECT_LT(out_data[i][j].imag(), 1.f);
174 } 73 }
175 } 74 }
176 } 75 }
177 76
178 } // namespace intelligibility 77 } // namespace intelligibility
179 78
180 } // namespace webrtc 79 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698