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

Side by Side Diff: webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc

Issue 2458703002: Changed mixing to be done at the minimal possible frequency. (Closed)
Patch Set: Changed name NeededFrequncy -> PreferredSampleRate to match upstream change Created 4 years, 1 month 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) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 } // namespace 50 } // namespace
51 51
52 class MockMixerAudioSource : public AudioMixer::Source { 52 class MockMixerAudioSource : public AudioMixer::Source {
53 public: 53 public:
54 MockMixerAudioSource() 54 MockMixerAudioSource()
55 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) { 55 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) {
56 ON_CALL(*this, GetAudioFrameWithInfo(_, _)) 56 ON_CALL(*this, GetAudioFrameWithInfo(_, _))
57 .WillByDefault( 57 .WillByDefault(
58 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo)); 58 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo));
59 ON_CALL(*this, PreferredSampleRate())
60 .WillByDefault(Return(kDefaultSampleRateHz));
59 } 61 }
60 62
61 MOCK_METHOD2(GetAudioFrameWithInfo, 63 MOCK_METHOD2(GetAudioFrameWithInfo,
62 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame)); 64 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame));
63 65
64 MOCK_CONST_METHOD0(PreferredSampleRate, int()); 66 MOCK_CONST_METHOD0(PreferredSampleRate, int());
65 MOCK_CONST_METHOD0(Ssrc, int()); 67 MOCK_CONST_METHOD0(Ssrc, int());
66 68
67 AudioFrame* fake_frame() { return &fake_frame_; } 69 AudioFrame* fake_frame() { return &fake_frame_; }
68 AudioFrameInfo fake_info() { return fake_audio_frame_info_; } 70 AudioFrameInfo fake_info() { return fake_audio_frame_info_; }
(...skipping 28 matching lines...) Expand all
97 participants[i].fake_frame()->CopyFrom(frames[i]); 99 participants[i].fake_frame()->CopyFrom(frames[i]);
98 participants[i].set_fake_info(frame_info[i]); 100 participants[i].set_fake_info(frame_info[i]);
99 } 101 }
100 102
101 for (int i = 0; i < num_audio_sources; i++) { 103 for (int i = 0; i < num_audio_sources; i++) {
102 EXPECT_TRUE(mixer->AddSource(&participants[i])); 104 EXPECT_TRUE(mixer->AddSource(&participants[i]));
103 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) 105 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
104 .Times(Exactly(1)); 106 .Times(Exactly(1));
105 } 107 }
106 108
107 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); 109 mixer->Mix(1, &frame_for_mixing);
108 110
109 for (int i = 0; i < num_audio_sources; i++) { 111 for (int i = 0; i < num_audio_sources; i++) {
110 EXPECT_EQ(expected_status[i], 112 EXPECT_EQ(expected_status[i],
111 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) 113 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
112 << "Mixed status of AudioSource #" << i << " wrong."; 114 << "Mixed status of AudioSource #" << i << " wrong.";
113 } 115 }
114 } 116 }
115 117
118 void MixMonoAtGivenNativeRate(int native_sample_rate,
119 AudioFrame* mix_frame,
120 rtc::scoped_refptr<AudioMixer> mixer,
121 MockMixerAudioSource* audio_source) {
122 ON_CALL(*audio_source, PreferredSampleRate())
123 .WillByDefault(Return(native_sample_rate));
124 audio_source->fake_frame()->sample_rate_hz_ = native_sample_rate;
125 audio_source->fake_frame()->samples_per_channel_ = native_sample_rate / 100;
126
127 mixer->Mix(1, mix_frame);
128 }
129
116 TEST(AudioMixer, LargestEnergyVadActiveMixed) { 130 TEST(AudioMixer, LargestEnergyVadActiveMixed) {
117 constexpr int kAudioSources = 131 constexpr int kAudioSources =
118 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3; 132 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3;
119 133
120 const auto mixer = AudioMixerImpl::Create(); 134 const auto mixer = AudioMixerImpl::Create();
121 135
122 MockMixerAudioSource participants[kAudioSources]; 136 MockMixerAudioSource participants[kAudioSources];
123 137
124 for (int i = 0; i < kAudioSources; ++i) { 138 for (int i = 0; i < kAudioSources; ++i) {
125 ResetFrame(participants[i].fake_frame()); 139 ResetFrame(participants[i].fake_frame());
126 140
127 // We set the 80-th sample value since the first 80 samples may be 141 // We set the 80-th sample value since the first 80 samples may be
128 // modified by a ramped-in window. 142 // modified by a ramped-in window.
129 participants[i].fake_frame()->data_[80] = i; 143 participants[i].fake_frame()->data_[80] = i;
130 144
131 EXPECT_TRUE(mixer->AddSource(&participants[i])); 145 EXPECT_TRUE(mixer->AddSource(&participants[i]));
132 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1)); 146 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1));
133 } 147 }
134 148
135 // Last participant gives audio frame with passive VAD, although it has the 149 // Last participant gives audio frame with passive VAD, although it has the
136 // largest energy. 150 // largest energy.
137 participants[kAudioSources - 1].fake_frame()->vad_activity_ = 151 participants[kAudioSources - 1].fake_frame()->vad_activity_ =
138 AudioFrame::kVadPassive; 152 AudioFrame::kVadPassive;
139 153
140 AudioFrame audio_frame; 154 AudioFrame audio_frame;
141 mixer->Mix(kDefaultSampleRateHz, 155 mixer->Mix(1, // number of channels
142 1, // number of channels
143 &audio_frame); 156 &audio_frame);
144 157
145 for (int i = 0; i < kAudioSources; ++i) { 158 for (int i = 0; i < kAudioSources; ++i) {
146 bool is_mixed = 159 bool is_mixed =
147 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]); 160 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]);
148 if (i == kAudioSources - 1 || 161 if (i == kAudioSources - 1 ||
149 i < kAudioSources - 1 - 162 i < kAudioSources - 1 -
150 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) { 163 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) {
151 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i 164 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i
152 << " wrong."; 165 << " wrong.";
(...skipping 16 matching lines...) Expand all
169 for (int j = 0; j < n_samples; j++) { 182 for (int j = 0; j < n_samples; j++) {
170 participant.fake_frame()->data_[j] = j; 183 participant.fake_frame()->data_[j] = j;
171 } 184 }
172 185
173 EXPECT_TRUE(mixer->AddSource(&participant)); 186 EXPECT_TRUE(mixer->AddSource(&participant));
174 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2)); 187 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2));
175 188
176 AudioFrame audio_frame; 189 AudioFrame audio_frame;
177 // Two mix iteration to compare after the ramp-up step. 190 // Two mix iteration to compare after the ramp-up step.
178 for (int i = 0; i < 2; i++) { 191 for (int i = 0; i < 2; i++) {
179 mixer->Mix(kDefaultSampleRateHz, 192 mixer->Mix(1, // number of channels
180 1, // number of channels
181 &audio_frame); 193 &audio_frame);
182 } 194 }
183 195
184 EXPECT_EQ( 196 EXPECT_EQ(
185 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples)); 197 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples));
186 } 198 }
187 199
aleloi 2016/10/31 10:39:35 The rationale behind the change of ParticipantSamp
188 TEST(AudioMixer, ParticipantSampleRate) { 200 TEST(AudioMixer, SourceAtNativeRateShouldNeverResample) {
201 const auto mixer = AudioMixerImpl::Create();
202
203 MockMixerAudioSource audio_source;
204 ResetFrame(audio_source.fake_frame());
205
206 mixer->AddSource(&audio_source);
207
208 for (auto frequency : {8000, 16000, 32000, 48000}) {
209 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(frequency, _))
210 .Times(Exactly(1));
211
212 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
213 &audio_source);
214 }
215 }
216
217 TEST(AudioMixer, MixerShouldMixAtNativeSourceRate) {
218 const auto mixer = AudioMixerImpl::Create();
219
220 MockMixerAudioSource audio_source;
221 ResetFrame(audio_source.fake_frame());
222
223 mixer->AddSource(&audio_source);
224
225 for (auto frequency : {8000, 16000, 32000, 48000}) {
226 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
227 &audio_source);
228
229 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_);
230 }
231 }
232
233 TEST(AudioMixer, MixerShouldAlwaysMixAtNativeRate) {
189 const auto mixer = AudioMixerImpl::Create(); 234 const auto mixer = AudioMixerImpl::Create();
190 235
191 MockMixerAudioSource participant; 236 MockMixerAudioSource participant;
192 ResetFrame(participant.fake_frame()); 237 ResetFrame(participant.fake_frame());
238 mixer->AddSource(&participant);
193 239
194 EXPECT_TRUE(mixer->AddSource(&participant)); 240 const int needed_frequency = 44100;
195 for (auto frequency : {8000, 16000, 32000, 48000}) { 241 ON_CALL(participant, PreferredSampleRate())
196 EXPECT_CALL(participant, GetAudioFrameWithInfo(frequency, _)) 242 .WillByDefault(Return(needed_frequency));
197 .Times(Exactly(1)); 243
198 participant.fake_frame()->sample_rate_hz_ = frequency; 244 // We expect mixing frequency to be native and >= needed_frequency.
199 participant.fake_frame()->samples_per_channel_ = frequency / 100; 245 const int expected_mix_frequency = 48000;
200 mixer->Mix(frequency, 1, &frame_for_mixing); 246 EXPECT_CALL(participant, GetAudioFrameWithInfo(expected_mix_frequency, _))
201 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_); 247 .Times(Exactly(1));
202 } 248 participant.fake_frame()->sample_rate_hz_ = expected_mix_frequency;
249 participant.fake_frame()->samples_per_channel_ = expected_mix_frequency / 100;
250
251 mixer->Mix(1, &frame_for_mixing);
252
253 EXPECT_EQ(48000, frame_for_mixing.sample_rate_hz_);
203 } 254 }
204 255
205 TEST(AudioMixer, ParticipantNumberOfChannels) { 256 TEST(AudioMixer, ParticipantNumberOfChannels) {
206 const auto mixer = AudioMixerImpl::Create(); 257 const auto mixer = AudioMixerImpl::Create();
207 258
208 MockMixerAudioSource participant; 259 MockMixerAudioSource participant;
209 ResetFrame(participant.fake_frame()); 260 ResetFrame(participant.fake_frame());
210 261
211 EXPECT_TRUE(mixer->AddSource(&participant)); 262 EXPECT_TRUE(mixer->AddSource(&participant));
212 for (size_t number_of_channels : {1, 2}) { 263 for (size_t number_of_channels : {1, 2}) {
213 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) 264 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
214 .Times(Exactly(1)); 265 .Times(Exactly(1));
215 mixer->Mix(kDefaultSampleRateHz, number_of_channels, &frame_for_mixing); 266 mixer->Mix(number_of_channels, &frame_for_mixing);
216 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_); 267 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
217 } 268 }
218 } 269 }
219 270
220 // Maximal amount of participants are mixed one iteration, then 271 // Maximal amount of participants are mixed one iteration, then
221 // another participant with higher energy is added. 272 // another participant with higher energy is added.
222 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) { 273 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
223 constexpr int kAudioSources = 274 constexpr int kAudioSources =
224 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; 275 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
225 276
226 const auto mixer = AudioMixerImpl::Create(); 277 const auto mixer = AudioMixerImpl::Create();
227 MockMixerAudioSource participants[kAudioSources]; 278 MockMixerAudioSource participants[kAudioSources];
228 279
229 for (int i = 0; i < kAudioSources; i++) { 280 for (int i = 0; i < kAudioSources; i++) {
230 ResetFrame(participants[i].fake_frame()); 281 ResetFrame(participants[i].fake_frame());
231 // Set the participant audio energy to increase with the index 282 // Set the participant audio energy to increase with the index
232 // |i|. 283 // |i|.
233 participants[i].fake_frame()->data_[0] = 100 * i; 284 participants[i].fake_frame()->data_[0] = 100 * i;
234 } 285 }
235 286
236 // Add all participants but the loudest for mixing. 287 // Add all participants but the loudest for mixing.
237 for (int i = 0; i < kAudioSources - 1; i++) { 288 for (int i = 0; i < kAudioSources - 1; i++) {
238 EXPECT_TRUE(mixer->AddSource(&participants[i])); 289 EXPECT_TRUE(mixer->AddSource(&participants[i]));
239 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) 290 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
240 .Times(Exactly(1)); 291 .Times(Exactly(1));
241 } 292 }
242 293
243 // First mixer iteration 294 // First mixer iteration
244 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); 295 mixer->Mix(1, &frame_for_mixing);
245 296
246 // All participants but the loudest should have been mixed. 297 // All participants but the loudest should have been mixed.
247 for (int i = 0; i < kAudioSources - 1; i++) { 298 for (int i = 0; i < kAudioSources - 1; i++) {
248 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) 299 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
249 << "Mixed status of AudioSource #" << i << " wrong."; 300 << "Mixed status of AudioSource #" << i << " wrong.";
250 } 301 }
251 302
252 // Add new participant with higher energy. 303 // Add new participant with higher energy.
253 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1])); 304 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1]));
254 for (int i = 0; i < kAudioSources; i++) { 305 for (int i = 0; i < kAudioSources; i++) {
255 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) 306 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
256 .Times(Exactly(1)); 307 .Times(Exactly(1));
257 } 308 }
258 309
259 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); 310 mixer->Mix(1, &frame_for_mixing);
260 311
261 // The most quiet participant should not have been mixed. 312 // The most quiet participant should not have been mixed.
262 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0])) 313 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0]))
263 << "Mixed status of AudioSource #0 wrong."; 314 << "Mixed status of AudioSource #0 wrong.";
264 315
265 // The loudest participants should have been mixed. 316 // The loudest participants should have been mixed.
266 for (int i = 1; i < kAudioSources; i++) { 317 for (int i = 1; i < kAudioSources; i++) {
267 EXPECT_EQ(true, 318 EXPECT_EQ(true,
268 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) 319 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
269 << "Mixed status of AudioSource #" << i << " wrong."; 320 << "Mixed status of AudioSource #" << i << " wrong.";
(...skipping 14 matching lines...) Expand all
284 335
285 participant_thread->Start(); 336 participant_thread->Start();
286 EXPECT_TRUE(participant_thread->Invoke<int>( 337 EXPECT_TRUE(participant_thread->Invoke<int>(
287 RTC_FROM_HERE, 338 RTC_FROM_HERE,
288 rtc::Bind(&AudioMixer::AddSource, mixer.get(), &participant))); 339 rtc::Bind(&AudioMixer::AddSource, mixer.get(), &participant)));
289 340
290 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) 341 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
291 .Times(Exactly(1)); 342 .Times(Exactly(1));
292 343
293 // Do one mixer iteration 344 // Do one mixer iteration
294 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); 345 mixer->Mix(1, &frame_for_mixing);
295 } 346 }
296 347
297 TEST(AudioMixer, MutedShouldMixAfterUnmuted) { 348 TEST(AudioMixer, MutedShouldMixAfterUnmuted) {
298 constexpr int kAudioSources = 349 constexpr int kAudioSources =
299 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; 350 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
300 351
301 std::vector<AudioFrame> frames(kAudioSources); 352 std::vector<AudioFrame> frames(kAudioSources);
302 for (auto& frame : frames) { 353 for (auto& frame : frames) {
303 ResetFrame(&frame); 354 ResetFrame(&frame);
304 } 355 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal); 414 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
364 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted; 415 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted;
365 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100, 416 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100,
366 std::numeric_limits<int16_t>::max()); 417 std::numeric_limits<int16_t>::max());
367 std::vector<bool> expected_status(kAudioSources, true); 418 std::vector<bool> expected_status(kAudioSources, true);
368 expected_status[0] = false; 419 expected_status[0] = false;
369 420
370 MixAndCompare(frames, frame_info, expected_status); 421 MixAndCompare(frames, frame_info, expected_status);
371 } 422 }
372 } // namespace webrtc 423 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698