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

Side by Side Diff: webrtc/modules/audio_processing/test/fake_recording_device_unittest.cc

Issue 2834643002: audioproc_f with simulated mic analog gain (Closed)
Patch Set: AGC simulated gain Created 3 years, 7 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) 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 <sstream>
12 #include <string>
13 #include <vector>
14
15 #include "webrtc/base/array_view.h"
16 #include "webrtc/modules/audio_processing/test/fake_recording_device.h"
17 #include "webrtc/test/gtest.h"
18
19 namespace webrtc {
20
21 namespace {
22
23 using MappingKind = FakeRecordingDevice::LevelToScalingMappingKind;
24
25 const std::vector<MappingKind> kMappingKindsToTest =
aleloi 2017/05/04 12:47:14 I suggest adding TODO(...): add new mapping kinds
AleBzk 2017/05/05 12:20:18 Done.
26 {MappingKind::kIdentity, MappingKind::kLinear};
27
28 const std::vector<std::vector<float>> kTestMultiChannelSamples{
29 std::vector<float>{-10.0, -1.0, -0.1, 0.0, 0.1, 1.0, 10.0}};
30
31 // Creates a vector of ArrayView instances pointing to distinct array of floats.
aleloi 2017/05/04 12:47:14 Comment is wrong. Should be 'vector of *vectors*'.
AleBzk 2017/05/05 12:20:18 Done.
32 std::vector<std::vector<float>> CreateOutputMultiChannelBuffer(
33 const size_t num_channels, const size_t num_samples) {
34 return std::vector<std::vector<float>>(
35 num_channels, std::vector<float>(num_samples, 0.0f));
36 }
aleloi 2017/05/04 12:47:14 I think we improve readability by removing this fu
AleBzk 2017/05/05 12:20:18 Thanks for this comment. There's no need anymore
37
38 // Returns a vector of ArrayView items of const floats.
39 std::vector<rtc::ArrayView<const float>> VecVecToVecArrayViewOfConst(
40 const std::vector<std::vector<float>>& vectorOfVectors) {
41 std::vector<rtc::ArrayView<const float>> vectorOfArrayViews;
42 for (const auto& v : vectorOfVectors) {
43 vectorOfArrayViews.emplace_back(rtc::MakeArrayView(v.data(), v.size()));
aleloi 2017/05/04 12:47:14 Does .emplace_back(v) work? I think ArrayView has
AleBzk 2017/05/05 12:20:18 Done.
44 }
45 return vectorOfArrayViews;
46 }
47
48 // Returns a vector of ArrayView items of non-const floats.
49 std::vector<rtc::ArrayView<float>> VecVecToVecArrayView(
50 std::vector<std::vector<float>>* vectorOfVectors) {
51 std::vector<rtc::ArrayView<float>> vectorOfArrayViews;
52 for (auto& v : *vectorOfVectors) {
53 vectorOfArrayViews.emplace_back(rtc::MakeArrayView(v.data(), v.size()));
aleloi 2017/05/04 12:47:14 Change to emplace_back(v) if it works.
AleBzk 2017/05/05 12:20:18 Done.
54 }
55 return vectorOfArrayViews;
56 }
57
58 // Checks that the samples modified using monotonic level values are also
59 // monotonic.
60 void CheckIfMonotoneSamplesModules(
61 const std::vector<rtc::ArrayView<float>>& prev,
62 const std::vector<rtc::ArrayView<float>>& curr) {
63 bool valid = true;
64 for (size_t i = 0; i < prev.size(); ++i) {
65 for (size_t j = 0; j < prev[i].size(); ++j) {
66 valid = std::fabs(prev[i][j]) <= std::fabs(curr[i][j]);
67 if (!valid) { break; }
68 }
69 if (!valid) { break; }
70 }
71 EXPECT_TRUE(valid);
72 }
73
74 // Checks that the samples in each pair have the same sign unless the sample in
75 // |dst| is zero (because of zero gain).
76 void CheckSameSign(
77 const std::vector<rtc::ArrayView<const float>>& src,
78 const std::vector<rtc::ArrayView<float>>& dst) {
79 auto fsgn = [](float x) { return static_cast<int>
aleloi 2017/05/04 12:47:14 const auto
AleBzk 2017/05/05 12:20:18 Done.
80 ((x < 0) ? -1 : ((x > 0) ? 1 : 0)); };
aleloi 2017/05/04 12:47:14 I prefer if / else if / else to two nested ternary
AleBzk 2017/05/05 12:20:18 I thought that static_cast <int> was safer since t
81 bool valid = true;
82 for (size_t i = 0; i < src.size(); ++i) {
83 for (size_t j = 0; j < src[i].size(); ++j) {
84 valid = dst[i][j] == 0.0f || fsgn(src[i][j]) == fsgn(dst[i][j]);
85 if (!valid) { break; }
86 }
87 if (!valid) { break; }
88 }
89 EXPECT_TRUE(valid);
90 }
91
92 std::string MappingKindToString(MappingKind kind) {
93 std::ostringstream ss;
94 ss << "simulated microphone kind code: " << static_cast<size_t>(kind);
95 return ss.str();
96 }
97
98 std::string AnalogLevelToString(int level) {
99 std::ostringstream ss;
100 ss << "analog level: " << level;
101 return ss.str();
102 }
103
104 } // namespace
105
106 TEST(AnalogVolumeMapper, CheckAnalogLevelSetGet) {
107 webrtc::FakeRecordingDevice level_mapper(MappingKind::kIdentity);
108 level_mapper.set_analog_level(0);
109 EXPECT_EQ(0, level_mapper.analog_level());
110 level_mapper.set_analog_level(255);
111 EXPECT_EQ(255, level_mapper.analog_level());
112 }
113
114 TEST(AnalogVolumeMapper, CheckHelperFunctions) {
115 // Check read.
116 auto src_multichannel_samples_view = VecVecToVecArrayViewOfConst(
aleloi 2017/05/04 12:47:14 Should be 'const auto' because we don't write to i
AleBzk 2017/05/05 12:20:18 Done.
117 kTestMultiChannelSamples);
118 EXPECT_EQ(kTestMultiChannelSamples[0][0],
119 src_multichannel_samples_view[0][0]);
120
121 // Check sizes.
122 auto dst_multichannel_samples = CreateOutputMultiChannelBuffer(
123 src_multichannel_samples_view.size(),
124 src_multichannel_samples_view[0].size());
125 auto dst_multichannel_samples_view = VecVecToVecArrayView(
126 &dst_multichannel_samples);
127 EXPECT_EQ(kTestMultiChannelSamples.size(), // Same number of channels.
128 dst_multichannel_samples_view.size());
129 EXPECT_EQ(kTestMultiChannelSamples[0].size(), // Same number of samples.
130 dst_multichannel_samples_view[0].size());
131
132 // Check write.
133 dst_multichannel_samples[0][1] = -5.0f;
134 EXPECT_EQ(dst_multichannel_samples[0][0],
135 dst_multichannel_samples_view[0][0]);
136 }
137
138 TEST(AnalogVolumeMapper, GainCurveShouldBeMonotone) {
139 // Create test samples.
140 auto src_multichannel_samples_view = VecVecToVecArrayViewOfConst(
141 kTestMultiChannelSamples);
142
143 // Create output buffers.
144 auto dst_multichannel_samples_prev = CreateOutputMultiChannelBuffer(
aleloi 2017/05/04 12:47:14 Suggest instead copy 'dst = kTestMultiChannelSampl
AleBzk 2017/05/05 12:20:18 Great point! Much simpler now and no need for Crea
145 src_multichannel_samples_view.size(),
146 src_multichannel_samples_view[0].size());
147 auto dst_multichannel_samples_prev_view = VecVecToVecArrayView(
148 &dst_multichannel_samples_prev);
149 auto dst_multichannel_samples = CreateOutputMultiChannelBuffer(
aleloi 2017/05/04 12:47:14 And also copy here.
AleBzk 2017/05/05 12:20:18 Done.
150 src_multichannel_samples_view.size(),
151 src_multichannel_samples_view[0].size());
152 auto dst_multichannel_samples_view = VecVecToVecArrayView(
153 &dst_multichannel_samples);
154
155 // Test different mappings.
156 for (auto kind : kMappingKindsToTest) {
aleloi 2017/05/04 12:47:14 Nit: prefer 'const auto &' to plain 'auto' if poss
AleBzk 2017/05/05 12:20:18 Done.
157 SCOPED_TRACE(MappingKindToString(kind));
158 webrtc::FakeRecordingDevice level_mapper(kind);
159
160 // Apply lowest analog level.
161 level_mapper.set_analog_level(0);
162 level_mapper.ProcessStream(
163 src_multichannel_samples_view, dst_multichannel_samples_prev_view);
164
165 // Increment analog level to check monotonicity.
166 for (int i = 1; i <= 255; ++i) {
167 SCOPED_TRACE(AnalogLevelToString(i));
168 level_mapper.set_analog_level(i);
169 level_mapper.ProcessStream(
170 src_multichannel_samples_view, dst_multichannel_samples_view);
171 // TODO(alessiob): The test below is designed for state-less recording
172 // devices. If, for instance, soft-clipping is used, the test might need
173 // to be redesigned.
174 CheckIfMonotoneSamplesModules(
175 dst_multichannel_samples_prev_view, dst_multichannel_samples_view);
176 dst_multichannel_samples_prev_view.swap(dst_multichannel_samples_view);
aleloi 2017/05/04 12:47:14 I think the naming doesn't represent how the vecto
AleBzk 2017/05/05 12:20:18 Done.
177 }
178 }
179 }
180
181 TEST(AnalogVolumeMapper, GainCurveShouldNotChangeSign) {
182 // Create test samples.
183 auto src_multichannel_samples_view = VecVecToVecArrayViewOfConst(
aleloi 2017/05/04 12:47:14 const auto
AleBzk 2017/05/05 12:20:18 Done.
184 kTestMultiChannelSamples);
185
186 // Create output buffer.
187 auto dst_multichannel_samples = CreateOutputMultiChannelBuffer(
188 src_multichannel_samples_view.size(),
189 src_multichannel_samples_view[0].size());
190 auto dst_multichannel_samples_view = VecVecToVecArrayView(
191 &dst_multichannel_samples);
192
193 // Test different mappings.
194 for (auto kind : kMappingKindsToTest) {
195 SCOPED_TRACE(MappingKindToString(kind));
196 webrtc::FakeRecordingDevice level_mapper(kind);
197
198 for (int i = 0; i <= 255; ++i) {
199 SCOPED_TRACE(AnalogLevelToString(i));
200 level_mapper.set_analog_level(i);
201 level_mapper.ProcessStream(
202 src_multichannel_samples_view, dst_multichannel_samples_view);
203 // TODO(alessiob): The test below is designed for state-less recording
204 // devices. If, for instance, soft-clipping is used, the test might need
205 // to be redesigned.
206 CheckSameSign(
207 src_multichannel_samples_view, dst_multichannel_samples_view);
208 }
209 }
210 }
211
212 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698