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

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

Issue 1207353002: Add new variance update option and unittests for intelligibility (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Simplified test data generation Created 5 years, 5 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
(Empty)
1 /*
2 * Copyright (c) 2015 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 //
12 // Unit tests for intelligibility utils.
13 //
14
15 #include <math.h>
16 #include <iostream>
17 #include <vector>
18
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils. h"
21
22 using std::complex;
23 using std::vector;
24
25 namespace webrtc {
26
27 namespace intelligibility {
28
29 vector<vector<complex<float>>> GenerateTestData(int freqs, int samples) {
30 vector<vector<complex<float>>> data(samples);
31 for (int i = 0; i < samples; i++) {
32 data[i].resize(freqs);
33 for (int j = 0; j < freqs; j++) {
34 data[i][j].real(0.99f / ((i + 1) * (j + 1)));
35 data[i][j].imag(0.99f / ((i + 1) * (j + 1)));
36 }
37 }
38 return data;
39 }
40
41 // Tests UpdateFactor.
42 TEST(IntelligibilityUtilsTest, TestUpdateFactor) {
43 EXPECT_EQ(0, intelligibility::UpdateFactor(0, 0, 0));
44 EXPECT_EQ(4, intelligibility::UpdateFactor(4, 2, 3));
45 EXPECT_EQ(3, intelligibility::UpdateFactor(4, 2, 1));
46 EXPECT_EQ(2, intelligibility::UpdateFactor(2, 4, 3));
47 EXPECT_EQ(3, intelligibility::UpdateFactor(2, 4, 1));
48 }
49
50 // Tests cplxfinite, cplxnormal, and zerofudge.
51 TEST(IntelligibilityUtilsTest, TestCplx) {
52 complex<float> t;
53 t.real(1.f);
54 t.imag(0.f);
55 EXPECT_TRUE(intelligibility::cplxfinite(t));
56 EXPECT_FALSE(intelligibility::cplxnormal(t));
57 t = intelligibility::zerofudge(t);
58 EXPECT_NE(t.imag(), 0.f);
59 EXPECT_NE(t.real(), 0.f);
60 t.imag(1.f / 0.f);
61 EXPECT_FALSE(intelligibility::cplxfinite(t));
62 EXPECT_FALSE(intelligibility::cplxnormal(t));
63 t.imag(sqrt(-1.f));
64 EXPECT_FALSE(intelligibility::cplxfinite(t));
65 EXPECT_FALSE(intelligibility::cplxnormal(t));
66 t.imag(1.f);
67 EXPECT_TRUE(intelligibility::cplxfinite(t));
68 EXPECT_TRUE(intelligibility::cplxnormal(t));
69 }
70
71 // Tests NewMean and AddToMean.
72 TEST(IntelligibilityUtilsTest, TestMeanUpdate) {
73 vector<complex<float>> data = {{3, 8}, {7, 6}, {2, 1}, {8, 9}, {0, 6}};
74 vector<complex<float>> means = {{3, 8}, {5, 7}, {4, 5}, {5, 6}, {4, 6}};
75 complex<float> mean(3, 8);
76 for (vector<int>::size_type i = 0; i < data.size(); i++) {
77 EXPECT_EQ(means[i], NewMean(mean, data[i], i + 1));
78 AddToMean(data[i], i + 1, &mean);
79 EXPECT_EQ(means[i], mean);
80 }
81 }
82
83 // Tests VarianceArray, for all variance step types.
84 TEST(IntelligibilityUtilsTest, TestVarianceArray) {
85 const int kFreqs = 10;
86 const int kSamples = 100;
87 const int kWindowSize = 10; // Should pass for all kWindowSize > 1.
88 const float kDecay = 0.5;
89 const vector<VarianceArray::StepType> step_types = {
90 VarianceArray::kStepInfinite,
91 VarianceArray::kStepDecaying,
92 VarianceArray::kStepWindowed,
93 VarianceArray::kStepBlocked,
94 VarianceArray::kStepBlockBasedMovingAverage};
95 const vector<vector<complex<float>>> test_data(
96 GenerateTestData(kFreqs, kSamples));
97 for (auto step_type : step_types) {
98 VarianceArray variance_array(kFreqs, step_type, kWindowSize, kDecay);
99 EXPECT_EQ(0, variance_array.variance()[0]);
100 EXPECT_EQ(0, variance_array.array_mean());
101 variance_array.ApplyScale(2.0f);
102 EXPECT_EQ(0, variance_array.variance()[0]);
103 EXPECT_EQ(0, variance_array.array_mean());
104
105 // Makes sure Step is doing something.
106 variance_array.Step(&test_data[0][0]);
107 for (int i = 1; i < kSamples; i++) {
108 variance_array.Step(&test_data[i][0]);
109 EXPECT_GE(variance_array.array_mean(), 0.0f);
110 EXPECT_LE(variance_array.array_mean(), 1.0f);
111 for (int j = 0; j < kFreqs; j++) {
112 EXPECT_GE(variance_array.variance()[j], 0.0f);
113 EXPECT_LE(variance_array.variance()[j], 1.0f);
114 }
115 }
116 variance_array.Clear();
117 EXPECT_EQ(0, variance_array.variance()[0]);
118 EXPECT_EQ(0, variance_array.array_mean());
119 }
120 }
121
122 // Tests exact computation on synthetic data.
123 TEST(IntelligibilityUtilsTest, TestMovingBlockAverage) {
124 // Exact, not unbiased estimates.
125 const float kTestVarianceBufferNotFull = 16.5f;
126 const float kTestVarianceBufferFull1 = 66.5f;
127 const float kTestVarianceBufferFull2 = 333.375f;
128 const int kFreqs = 2;
129 const int kSamples = 50;
130 const int kWindowSize = 2;
131 const float kDecay = 0.5f;
132 const float kMaxError = 0.0001f;
133
134 VarianceArray variance_array(
135 kFreqs, VarianceArray::kStepBlockBasedMovingAverage, kWindowSize, kDecay);
136
137 vector<vector<complex<float>>> test_data(kSamples);
138 for (int i = 0; i < kSamples; i++) {
139 test_data[i].resize(kFreqs);
140 for (int j = 0; j < kFreqs; j++) {
141 if (i < 30) {
142 test_data[i][j].real(static_cast<float>(kSamples - i));
143 test_data[i][j].imag(static_cast<float>(i + 1));
144 } else {
145 test_data[i][j].real(0.f);
146 test_data[i][j].imag(0.f);
147 }
148 }
149 }
150
151 for (int i = 0; i < kSamples; i++) {
152 variance_array.Step(&test_data[i][0]);
153 for (int j = 0; j < kFreqs; j++) {
154 if (i < 9) { // In utils, kWindowBlockSize = 10.
155 EXPECT_EQ(0, variance_array.variance()[j]);
156 } else if (i < 19) {
157 EXPECT_NEAR(kTestVarianceBufferNotFull, variance_array.variance()[j],
158 kMaxError);
159 } else if (i < 39) {
160 EXPECT_NEAR(kTestVarianceBufferFull1, variance_array.variance()[j],
161 kMaxError);
162 } else if (i < 49) {
163 EXPECT_NEAR(kTestVarianceBufferFull2, variance_array.variance()[j],
164 kMaxError);
165 } else {
166 EXPECT_EQ(0, variance_array.variance()[j]);
167 }
168 }
169 }
170 }
171
172 // Tests gain applier.
173 TEST(IntelligibilityUtilsTest, TestGainApplier) {
174 const int kFreqs = 10;
175 const int kSamples = 100;
176 const float kChangeLimit = 0.1f;
177 GainApplier gain_applier(kFreqs, kChangeLimit);
178 const vector<vector<complex<float>>> in_data(
179 GenerateTestData(kFreqs, kSamples));
180 vector<vector<complex<float>>> out_data(GenerateTestData(kFreqs, kSamples));
181 for (int i = 0; i < kSamples; i++) {
182 gain_applier.Apply(&in_data[i][0], &out_data[i][0]);
183 for (int j = 0; j < kFreqs; j++) {
184 EXPECT_GT(out_data[i][j].real(), 0.0f);
185 EXPECT_LT(out_data[i][j].real(), 1.0f);
186 EXPECT_GT(out_data[i][j].imag(), 0.0f);
187 EXPECT_LT(out_data[i][j].imag(), 1.0f);
188 }
189 }
190 }
191
192 } // namespace intelligibility
193
194 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698