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

Side by Side Diff: webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc

Issue 2253153004: Updated mixer unittests and fixed a related bug in the new mixer. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@remove_comments_add_level_indicator_dep
Patch Set: Rebase from upstream. Created 4 years, 4 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
« no previous file with comments | « webrtc/modules/audio_mixer/new_audio_conference_mixer_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 #include <memory> 11 #include <memory>
12 #include <utility> 12 #include <utility>
13 13
14 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
15
16 #include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer.h "
17 #include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer_d efines.h"
18 #include "webrtc/modules/audio_conference_mixer/source/audio_frame_manipulator.h "
19 #include "webrtc/modules/audio_mixer/audio_mixer.h"
20 #include "webrtc/modules/audio_mixer/audio_mixer_defines.h" 15 #include "webrtc/modules/audio_mixer/audio_mixer_defines.h"
21 #include "webrtc/modules/audio_mixer/new_audio_conference_mixer.h" 16 #include "webrtc/modules/audio_mixer/new_audio_conference_mixer.h"
22 #include "webrtc/modules/audio_mixer/new_audio_conference_mixer_impl.h"
23 17
24 using testing::_; 18 using testing::_;
25 using testing::Exactly; 19 using testing::Exactly;
26 using testing::Invoke; 20 using testing::Invoke;
27 using testing::Return; 21 using testing::Return;
28 22
29 using webrtc::voe::AudioMixer; 23 namespace webrtc {
30 24
31 namespace webrtc { 25 namespace {
32 class MockAudioMixerParticipant : public MixerParticipant {
33 public:
34 MockAudioMixerParticipant()
35 : fake_audio_frame_info_(MixerParticipant::AudioFrameInfo::kNormal) {
36 ON_CALL(*this, GetAudioFrameWithMuted(_, _))
37 .WillByDefault(
38 Invoke(this, &MockAudioMixerParticipant::FakeAudioFrameWithMuted));
39 }
40 26
41 MOCK_METHOD2(GetAudioFrameWithMuted, 27 constexpr int kDefaultSampleRateHz = 48000;
42 AudioFrameInfo(const int32_t id, AudioFrame* audio_frame)); 28 constexpr int kId = 1;
43 MOCK_CONST_METHOD1(NeededFrequency, int32_t(const int32_t id));
44 29
45 AudioFrame* fake_frame() { return &fake_frame_; } 30 // Utility function that resets the frame member variables with
46 AudioFrameInfo fake_info() { return this->fake_audio_frame_info_; } 31 // sensible defaults.
47 void set_fake_info(const AudioFrameInfo audio_frame_info) { 32 void ResetFrame(AudioFrame* frame) {
48 fake_audio_frame_info_ = audio_frame_info; 33 frame->id_ = kId;
49 } 34 frame->sample_rate_hz_ = kDefaultSampleRateHz;
35 frame->num_channels_ = 1;
50 36
51 private: 37 // Frame duration 10ms.
52 AudioFrame fake_frame_; 38 frame->samples_per_channel_ = kDefaultSampleRateHz / 100;
53 AudioFrameInfo fake_audio_frame_info_; 39 frame->vad_activity_ = AudioFrame::kVadActive;
54 AudioFrameInfo FakeAudioFrameWithMuted(const int32_t id, 40 frame->speech_type_ = AudioFrame::kNormalSpeech;
55 AudioFrame* audio_frame) { 41 }
56 audio_frame->CopyFrom(*fake_frame()); 42
57 return fake_info(); 43 AudioFrame frame_for_mixing;
58 } 44
59 }; 45 } // namespace
60 46
61 class MockMixerAudioSource : public MixerAudioSource { 47 class MockMixerAudioSource : public MixerAudioSource {
62 public: 48 public:
63 MockMixerAudioSource() 49 MockMixerAudioSource()
64 : fake_audio_frame_info_(MixerAudioSource::AudioFrameInfo::kNormal) { 50 : fake_audio_frame_info_(MixerAudioSource::AudioFrameInfo::kNormal) {
65 ON_CALL(*this, GetAudioFrameWithMuted(_, _)) 51 ON_CALL(*this, GetAudioFrameWithMuted(_, _))
66 .WillByDefault( 52 .WillByDefault(
67 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithMuted)); 53 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithMuted));
68 } 54 }
69 55
70 MOCK_METHOD2(GetAudioFrameWithMuted, 56 MOCK_METHOD2(GetAudioFrameWithMuted,
71 AudioFrameWithMuted(const int32_t id, int sample_rate_hz)); 57 AudioFrameWithMuted(const int32_t id, int sample_rate_hz));
72 58
73 AudioFrame* fake_frame() { return &fake_frame_; } 59 AudioFrame* fake_frame() { return &fake_frame_; }
74 AudioFrameInfo fake_info() { return fake_audio_frame_info_; } 60 AudioFrameInfo fake_info() { return fake_audio_frame_info_; }
75 void set_fake_info(const AudioFrameInfo audio_frame_info) { 61 void set_fake_info(const AudioFrameInfo audio_frame_info) {
76 fake_audio_frame_info_ = audio_frame_info; 62 fake_audio_frame_info_ = audio_frame_info;
77 } 63 }
78 64
79 private: 65 private:
80 AudioFrame fake_frame_, output_frame_; 66 AudioFrame fake_frame_, fake_output_frame_;
81 AudioFrameInfo fake_audio_frame_info_; 67 AudioFrameInfo fake_audio_frame_info_;
82 AudioFrameWithMuted FakeAudioFrameWithMuted(const int32_t id, 68 AudioFrameWithMuted FakeAudioFrameWithMuted(const int32_t id,
83 int sample_rate_hz) { 69 int sample_rate_hz) {
84 output_frame_.CopyFrom(fake_frame_); 70 fake_output_frame_.CopyFrom(fake_frame_);
85 return { 71 return {
86 &output_frame_, // audio_frame_pointer 72 &fake_output_frame_, // audio_frame_pointer
87 fake_info(), // audio_frame_info 73 fake_info(), // audio_frame_info
88 }; 74 };
89 } 75 }
90 }; 76 };
91 77
92 // Keeps two identical sets of participants and two mixers to test 78 // Creates participants from |frames| and |frame_info| and adds them
93 // that the same participants are chosen for mixing. 79 // to the mixer. Compares mixed status with |expected_status|
94 class CompareWithOldMixerTest : public testing::Test, AudioMixerOutputReceiver { 80 void MixAndCompare(
95 protected: 81 const std::vector<AudioFrame>& frames,
96 constexpr static int kId = 1; 82 const std::vector<MixerAudioSource::AudioFrameInfo>& frame_info,
97 constexpr static int kSampleRateHz = 32000; 83 const std::vector<bool>& expected_status) {
84 int num_audio_sources = frames.size();
85 RTC_DCHECK(frames.size() == frame_info.size());
86 RTC_DCHECK(frame_info.size() == expected_status.size());
98 87
99 CompareWithOldMixerTest() 88 std::unique_ptr<NewAudioConferenceMixer> mixer(
100 : old_mixer_(AudioConferenceMixer::Create(kId)), 89 NewAudioConferenceMixer::Create(kId));
101 new_mixer_(NewAudioConferenceMixer::Create(kId)) {} 90 std::vector<MockMixerAudioSource> participants(num_audio_sources);
102 91
103 ~CompareWithOldMixerTest() { Reset(); } 92 for (int i = 0; i < num_audio_sources; i++) {
104 93 participants[i].fake_frame()->CopyFrom(frames[i]);
105 // Mixes with both mixers and compares results: resulting frames and 94 participants[i].set_fake_info(frame_info[i]);
106 // mix statuses.
107 void MixAndCompare() {
108 old_mixer_->Process();
109 new_mixer_->Mix(kSampleRateHz,
110 1, // number of channels
111 &new_mixer_frame_);
112 EXPECT_EQ(0, memcmp(old_mixer_frame_.data_, new_mixer_frame_.data_,
113 sizeof(old_mixer_frame_.data_)));
114
115 for (auto& participant_pair : participants_) {
116 EXPECT_EQ(participant_pair.first->IsMixed(),
117 participant_pair.second->IsMixed());
118 }
119 } 95 }
120 96
121 std::unique_ptr<AudioFrame> last_mixed_audio_old() { 97 for (int i = 0; i < num_audio_sources; i++) {
122 std::unique_ptr<AudioFrame> result(new AudioFrame); 98 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
123 result->CopyFrom(old_mixer_frame_); 99 EXPECT_CALL(participants[i],
124 return result; 100 GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
101 .Times(Exactly(1));
125 } 102 }
126 103
127 void Reset() { 104 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
128 old_mixer_.reset(AudioConferenceMixer::Create(kId)); 105
129 new_mixer_.reset(NewAudioConferenceMixer::Create(kId)); 106 for (int i = 0; i < num_audio_sources; i++) {
130 for (auto& participant_pair : participants_) { 107 EXPECT_EQ(participants[i].IsMixed(), expected_status[i])
131 delete participant_pair.first; 108 << "Mixed status of AudioSource #" << i << " wrong.";
132 delete participant_pair.second;
133 }
134 participants_.clear();
135 } 109 }
136 110 }
137 void ResetFrame(AudioFrame* audio_frame) {
138 audio_frame->sample_rate_hz_ = kSampleRateHz;
139 audio_frame->speech_type_ = AudioFrame::kNormalSpeech;
140 audio_frame->vad_activity_ = AudioFrame::kVadActive;
141 audio_frame->num_channels_ = 1;
142 }
143
144 void AddParticipant(AudioFrame* audio_frame,
145 MixerParticipant::AudioFrameInfo audio_frame_info) {
146 auto old_participant = new MockAudioMixerParticipant;
147 auto new_participant = new MockMixerAudioSource;
148 old_participant->fake_frame()->CopyFrom(*audio_frame);
149 new_participant->fake_frame()->CopyFrom(*audio_frame);
150 old_participant->set_fake_info(audio_frame_info);
151 MixerAudioSource::AudioFrameInfo new_audio_frame_info;
152 switch (audio_frame_info) {
153 case MixerParticipant::AudioFrameInfo::kNormal:
154 new_audio_frame_info = MixerAudioSource::AudioFrameInfo::kNormal;
155 break;
156 case MixerParticipant::AudioFrameInfo::kMuted:
157 new_audio_frame_info = MixerAudioSource::AudioFrameInfo::kMuted;
158 break;
159 default:
160 new_audio_frame_info = MixerAudioSource::AudioFrameInfo::kError;
161 }
162 new_participant->set_fake_info(new_audio_frame_info);
163 participants_.emplace_back(old_participant, new_participant);
164 }
165
166 void NewMixedAudio(const int32_t id,
167 const AudioFrame& generalAudioFrame,
168 const AudioFrame** uniqueAudioFrames,
169 const uint32_t size) override {
170 old_mixer_frame_.CopyFrom(generalAudioFrame);
171 }
172
173 AudioFrame old_mixer_frame_;
174 AudioFrame new_mixer_frame_;
175
176 std::vector<std::pair<MockAudioMixerParticipant*, MockMixerAudioSource*>>
177 participants_;
178 std::unique_ptr<AudioConferenceMixer> old_mixer_;
179 std::unique_ptr<NewAudioConferenceMixer> new_mixer_;
180 };
181
182 class BothMixersTest : public testing::Test {
183 protected:
184 BothMixersTest() {
185 // Create an OutputMixer.
186 AudioMixer::Create(audio_mixer_, kId);
187
188 // Create one mixer participant and add it to the mixer.
189 EXPECT_EQ(0, audio_mixer_->SetMixabilityStatus(participant_, true));
190
191 // Each iteration, the participant will return a frame with this content:
192 participant_.fake_frame()->id_ = 1;
193 participant_.fake_frame()->sample_rate_hz_ = kSampleRateHz;
194 participant_.fake_frame()->speech_type_ = AudioFrame::kNormalSpeech;
195 participant_.fake_frame()->vad_activity_ = AudioFrame::kVadActive;
196 participant_.fake_frame()->num_channels_ = 1;
197
198 // We modify one sample within the RampIn window and one sample
199 // outside of it.
200 participant_.fake_frame()->data_[10] = 100;
201 participant_.fake_frame()->data_[20] = -200;
202 participant_.fake_frame()->data_[30] = 300;
203 participant_.fake_frame()->data_[90] = -400;
204
205 // Frame duration 10ms.
206 participant_.fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
207 }
208
209 ~BothMixersTest() { AudioMixer::Destroy(audio_mixer_); }
210
211 // Mark the participant as 'unmixed' last round.
212 void ResetAudioSource() { participant_._mixHistory->SetIsMixed(false); }
213
214 AudioMixer* audio_mixer_;
215 MockMixerAudioSource participant_;
216 AudioFrame mixing_round_frame, mixed_results_frame_;
217
218 constexpr static int kSampleRateHz = 48000;
219 constexpr static int kId = 1;
220 };
221 111
222 TEST(AudioMixer, AnonymousAndNamed) { 112 TEST(AudioMixer, AnonymousAndNamed) {
223 constexpr int kId = 1;
224 // Should not matter even if partipants are more than 113 // Should not matter even if partipants are more than
225 // kMaximumAmountOfMixedAudioSources. 114 // kMaximumAmountOfMixedAudioSources.
226 constexpr int kNamed = 115 constexpr int kNamed =
227 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1; 116 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
228 constexpr int kAnonymous = 117 constexpr int kAnonymous =
229 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1; 118 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
230 119
231 std::unique_ptr<NewAudioConferenceMixer> mixer( 120 std::unique_ptr<NewAudioConferenceMixer> mixer(
232 NewAudioConferenceMixer::Create(kId)); 121 NewAudioConferenceMixer::Create(kId));
233 122
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 157 }
269 158
270 // SetMixabilityStatus(anonymous, false) will remove anonymous from both 159 // SetMixabilityStatus(anonymous, false) will remove anonymous from both
271 // anonymous and named groups. 160 // anonymous and named groups.
272 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false)); 161 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false));
273 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1])); 162 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1]));
274 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1])); 163 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1]));
275 } 164 }
276 165
277 TEST(AudioMixer, LargestEnergyVadActiveMixed) { 166 TEST(AudioMixer, LargestEnergyVadActiveMixed) {
278 constexpr int kId = 1;
279 constexpr int kAudioSources = 167 constexpr int kAudioSources =
280 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 3; 168 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 3;
281 constexpr int kSampleRateHz = 32000;
282 169
283 std::unique_ptr<NewAudioConferenceMixer> mixer( 170 std::unique_ptr<NewAudioConferenceMixer> mixer(
284 NewAudioConferenceMixer::Create(kId)); 171 NewAudioConferenceMixer::Create(kId));
285 172
286 MockMixerAudioSource participants[kAudioSources]; 173 MockMixerAudioSource participants[kAudioSources];
287 174
288 for (int i = 0; i < kAudioSources; ++i) { 175 for (int i = 0; i < kAudioSources; ++i) {
289 participants[i].fake_frame()->id_ = i; 176 ResetFrame(participants[i].fake_frame());
290 participants[i].fake_frame()->sample_rate_hz_ = kSampleRateHz;
291 participants[i].fake_frame()->speech_type_ = AudioFrame::kNormalSpeech;
292 participants[i].fake_frame()->vad_activity_ = AudioFrame::kVadActive;
293 participants[i].fake_frame()->num_channels_ = 1;
294
295 // Frame duration 10ms.
296 participants[i].fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
297 177
298 // We set the 80-th sample value since the first 80 samples may be 178 // We set the 80-th sample value since the first 80 samples may be
299 // modified by a ramped-in window. 179 // modified by a ramped-in window.
300 participants[i].fake_frame()->data_[80] = i; 180 participants[i].fake_frame()->data_[80] = i;
301 181
302 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true)); 182 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
303 EXPECT_CALL(participants[i], GetAudioFrameWithMuted(_, _)) 183 EXPECT_CALL(participants[i], GetAudioFrameWithMuted(_, _))
304 .Times(Exactly(1)); 184 .Times(Exactly(1));
305 } 185 }
306 186
307 // Last participant gives audio frame with passive VAD, although it has the 187 // Last participant gives audio frame with passive VAD, although it has the
308 // largest energy. 188 // largest energy.
309 participants[kAudioSources - 1].fake_frame()->vad_activity_ = 189 participants[kAudioSources - 1].fake_frame()->vad_activity_ =
310 AudioFrame::kVadPassive; 190 AudioFrame::kVadPassive;
311 191
312 AudioFrame audio_frame; 192 AudioFrame audio_frame;
313 mixer->Mix(kSampleRateHz, 193 mixer->Mix(kDefaultSampleRateHz,
314 1, // number of channels 194 1, // number of channels
315 &audio_frame); 195 &audio_frame);
316 196
317 for (int i = 0; i < kAudioSources; ++i) { 197 for (int i = 0; i < kAudioSources; ++i) {
318 bool is_mixed = participants[i].IsMixed(); 198 bool is_mixed = participants[i].IsMixed();
319 if (i == kAudioSources - 1 || 199 if (i == kAudioSources - 1 ||
320 i < kAudioSources - 1 - 200 i < kAudioSources - 1 -
321 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources) { 201 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources) {
322 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i 202 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i
323 << " wrong."; 203 << " wrong.";
324 } else { 204 } else {
325 EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i 205 EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i
326 << " wrong."; 206 << " wrong.";
327 } 207 }
328 } 208 }
329 } 209 }
330 210
331 TEST(AudioMixer, ParticipantSampleRate) { 211 TEST(AudioMixer, ParticipantSampleRate) {
332 constexpr int kId = 1;
333 std::unique_ptr<NewAudioConferenceMixer> mixer( 212 std::unique_ptr<NewAudioConferenceMixer> mixer(
334 NewAudioConferenceMixer::Create(kId)); 213 NewAudioConferenceMixer::Create(kId));
335 AudioFrame frame_for_mixing;
336 214
337 MockMixerAudioSource participant; 215 MockMixerAudioSource participant;
338 participant.fake_frame()->sample_rate_hz_ = 8000; 216 ResetFrame(participant.fake_frame());
339 participant.fake_frame()->num_channels_ = 1;
340
341 // Frame duration 10ms.
342 participant.fake_frame()->samples_per_channel_ = 8000 / 100;
343 217
344 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); 218 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
345 for (auto frequency : {8000, 16000, 32000, 48000}) { 219 for (auto frequency : {8000, 16000, 32000, 48000}) {
346 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, frequency)) 220 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, frequency))
347 .Times(Exactly(1)); 221 .Times(Exactly(1));
348 mixer->Mix(frequency, 1, &frame_for_mixing); 222 mixer->Mix(frequency, 1, &frame_for_mixing);
349 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_); 223 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_);
350 } 224 }
351 } 225 }
352 226
353 TEST(AudioMixer, ParticipantNumberOfChannels) { 227 TEST(AudioMixer, ParticipantNumberOfChannels) {
354 constexpr int kId = 1;
355 std::unique_ptr<NewAudioConferenceMixer> mixer( 228 std::unique_ptr<NewAudioConferenceMixer> mixer(
356 NewAudioConferenceMixer::Create(kId)); 229 NewAudioConferenceMixer::Create(kId));
357 AudioFrame frame_for_mixing;
358 230
359 MockMixerAudioSource participant; 231 MockMixerAudioSource participant;
360 participant.fake_frame()->sample_rate_hz_ = 8000; 232 ResetFrame(participant.fake_frame());
361 participant.fake_frame()->num_channels_ = 1;
362
363 // Frame duration 10ms.
364 participant.fake_frame()->samples_per_channel_ = 8000 / 100;
365 233
366 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); 234 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
367 for (size_t number_of_channels : {1, 2}) { 235 for (size_t number_of_channels : {1, 2}) {
368 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, 8000)).Times(Exactly(1)); 236 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
369 mixer->Mix(8000, number_of_channels, &frame_for_mixing); 237 .Times(Exactly(1));
238 mixer->Mix(kDefaultSampleRateHz, number_of_channels, &frame_for_mixing);
370 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_); 239 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
371 } 240 }
372 } 241 }
373 242
374 // Test that the volume is reported as zero when the mixer input 243 // Test that the volume is reported as zero when the mixer input
375 // comprises only zero values. 244 // comprises only zero values.
376 TEST(AudioMixer, LevelIsZeroWhenMixingZeroes) { 245 TEST(AudioMixer, LevelIsZeroWhenMixingZeroes) {
377 constexpr int kId = 1;
378 constexpr int kSampleRateHz = 8000;
379 std::unique_ptr<NewAudioConferenceMixer> mixer( 246 std::unique_ptr<NewAudioConferenceMixer> mixer(
380 NewAudioConferenceMixer::Create(kId)); 247 NewAudioConferenceMixer::Create(kId));
381 AudioFrame frame_for_mixing;
382 248
383 MockMixerAudioSource participant; 249 MockMixerAudioSource participant;
384 participant.fake_frame()->sample_rate_hz_ = kSampleRateHz; 250 ResetFrame(participant.fake_frame());
385 participant.fake_frame()->num_channels_ = 1;
386
387 // Frame duration 10ms.
388 participant.fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
389 251
390 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); 252 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
391 for (size_t i = 0; i < 11; i++) { 253 for (int i = 0; i < 11; i++) {
392 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kSampleRateHz)) 254 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
393 .Times(Exactly(1)); 255 .Times(Exactly(1));
394 mixer->Mix(8000, 1, &frame_for_mixing); 256 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
395 } 257 }
396 258
397 EXPECT_EQ(0, mixer->GetOutputAudioLevel()); 259 EXPECT_EQ(0, mixer->GetOutputAudioLevel());
398 EXPECT_EQ(0, mixer->GetOutputAudioLevelFullRange()); 260 EXPECT_EQ(0, mixer->GetOutputAudioLevelFullRange());
399 } 261 }
400 262
401 // Test that the reported volume is maximal when the mixer 263 // Test that the reported volume is maximal when the mixer
402 // input comprises frames with maximal values. 264 // input comprises frames with maximal values.
403 TEST(AudioMixer, LevelIsMaximalWhenMixingMaximalValues) { 265 TEST(AudioMixer, LevelIsMaximalWhenMixingMaximalValues) {
404 constexpr int kId = 1;
405 constexpr int kSampleRateHz = 8000;
406 std::unique_ptr<NewAudioConferenceMixer> mixer( 266 std::unique_ptr<NewAudioConferenceMixer> mixer(
407 NewAudioConferenceMixer::Create(kId)); 267 NewAudioConferenceMixer::Create(kId));
408 AudioFrame frame_for_mixing;
409 268
410 MockMixerAudioSource participant; 269 MockMixerAudioSource participant;
411 participant.fake_frame()->sample_rate_hz_ = kSampleRateHz; 270 ResetFrame(participant.fake_frame());
412 participant.fake_frame()->num_channels_ = 1;
413
414 // Frame duration 10ms.
415 participant.fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
416 271
417 // Fill participant frame data with maximal sound. 272 // Fill participant frame data with maximal sound.
418 std::fill(participant.fake_frame()->data_, 273 std::fill(participant.fake_frame()->data_,
419 participant.fake_frame()->data_ + kSampleRateHz / 100, 274 participant.fake_frame()->data_ + kDefaultSampleRateHz / 100,
420 std::numeric_limits<int16_t>::max()); 275 std::numeric_limits<int16_t>::max());
421 276
422 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); 277 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
423 for (size_t i = 0; i < 11; i++) { 278
424 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kSampleRateHz)) 279 // We do >10 iterations, because the audio level indicator only
280 // updates once every 10 calls.
281 for (int i = 0; i < 11; i++) {
282 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
425 .Times(Exactly(1)); 283 .Times(Exactly(1));
426 mixer->Mix(8000, 1, &frame_for_mixing); 284 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
427 } 285 }
428 286
429 // 9 is the highest possible audio level 287 // 9 is the highest possible audio level
430 EXPECT_EQ(9, mixer->GetOutputAudioLevel()); 288 EXPECT_EQ(9, mixer->GetOutputAudioLevel());
431 289
432 // 0x7fff = 32767 is the highest full range audio level. 290 // 0x7fff = 32767 is the highest full range audio level.
433 EXPECT_EQ(std::numeric_limits<int16_t>::max(), 291 EXPECT_EQ(std::numeric_limits<int16_t>::max(),
434 mixer->GetOutputAudioLevelFullRange()); 292 mixer->GetOutputAudioLevelFullRange());
435 } 293 }
436 294
437 TEST_F(BothMixersTest, CompareInitialFrameAudio) { 295 // Maximal amount of participants are mixed one iteration, then
438 EXPECT_CALL(participant_, GetAudioFrameWithMuted(_, _)).Times(Exactly(1)); 296 // another participant with higher energy is added.
297 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
298 constexpr int kAudioSources =
299 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
439 300
440 // Make sure the participant is marked as 'non-mixed' so that it is 301 std::unique_ptr<NewAudioConferenceMixer> mixer(
441 // ramped in next round. 302 NewAudioConferenceMixer::Create(kId));
442 ResetAudioSource(); 303 MockMixerAudioSource participants[kAudioSources];
443 304
444 // Construct the expected sound for the first mixing round. 305 for (int i = 0; i < kAudioSources; i++) {
445 mixing_round_frame.CopyFrom(*participant_.fake_frame()); 306 ResetFrame(participants[i].fake_frame());
446 RampIn(mixing_round_frame); 307 // Set the participant audio energy to increase with the index
308 // |i|.
309 participants[i].fake_frame()->data_[0] = 100 * i;
310 }
447 311
448 // Mix frames and put the result into a frame. 312 // Add all participants but the loudest for mixing.
449 audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_); 313 for (int i = 0; i < kAudioSources - 1; i++) {
314 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
315 EXPECT_CALL(participants[i],
316 GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
317 .Times(Exactly(1));
318 }
450 319
451 // Compare the received frame with the expected. 320 // First mixer iteration
452 EXPECT_EQ(mixing_round_frame.sample_rate_hz_, 321 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
453 mixed_results_frame_.sample_rate_hz_);
454 EXPECT_EQ(mixing_round_frame.num_channels_,
455 mixed_results_frame_.num_channels_);
456 EXPECT_EQ(mixing_round_frame.samples_per_channel_,
457 mixed_results_frame_.samples_per_channel_);
458 EXPECT_EQ(0, memcmp(mixing_round_frame.data_, mixed_results_frame_.data_,
459 sizeof(mixing_round_frame.data_)));
460 }
461 322
462 TEST_F(BothMixersTest, CompareSecondFrameAudio) { 323 // All participants but the loudest should have been mixed.
463 EXPECT_CALL(participant_, GetAudioFrameWithMuted(_, _)).Times(Exactly(2)); 324 for (int i = 0; i < kAudioSources - 1; i++) {
325 EXPECT_TRUE(participants[i].IsMixed()) << "Mixed status of AudioSource #"
326 << i << " wrong.";
327 }
464 328
465 // Make sure the participant is marked as 'non-mixed' so that it is 329 // Add new participant with higher energy.
466 // ramped in next round. 330 EXPECT_EQ(0,
467 ResetAudioSource(); 331 mixer->SetMixabilityStatus(&participants[kAudioSources - 1], true));
332 for (int i = 0; i < kAudioSources; i++) {
333 EXPECT_CALL(participants[i],
334 GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
335 .Times(Exactly(1));
336 }
468 337
469 // Do one mixing iteration. 338 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
470 audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_);
471 339
472 // Mix frames a second time and compare with the expected frame 340 // The most quiet participant should not have been mixed.
473 // (which is the participant's frame). 341 EXPECT_FALSE(participants[0].IsMixed())
474 audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_); 342 << "Mixed status of AudioSource #0 wrong.";
475 EXPECT_EQ(0,
476 memcmp(participant_.fake_frame()->data_, mixed_results_frame_.data_,
477 sizeof(mixing_round_frame.data_)));
478 }
479 343
480 TEST_F(CompareWithOldMixerTest, TwoParticipantsNormalFrames) { 344 // The loudest participants should have been mixed.
481 Reset(); 345 for (int i = 1; i < kAudioSources; i++) {
482 AudioFrame first_frame, second_frame; 346 EXPECT_EQ(participants[i].IsMixed(), true)
483 347 << "Mixed status of AudioSource #" << i << " wrong.";
484 ResetFrame(&first_frame);
485 ResetFrame(&second_frame);
486
487 first_frame.id_ = 1;
488 second_frame.id_ = 2;
489
490 AddParticipant(&first_frame, MixerParticipant::AudioFrameInfo::kNormal);
491 AddParticipant(&second_frame, MixerParticipant::AudioFrameInfo::kNormal);
492
493 for (int i = 0; i < 3; ++i) {
494 MixAndCompare();
495 } 348 }
496 } 349 }
497 350
498 TEST_F(CompareWithOldMixerTest, ThreeParticipantsDifferentFrames) { 351 TEST(AudioMixer, MutedShouldMixAfterUnmuted) {
499 Reset(); 352 constexpr int kAudioSources =
500 AudioFrame first_frame, second_frame, third_frame; 353 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
501 354
502 ResetFrame(&first_frame); 355 std::vector<AudioFrame> frames(kAudioSources);
503 ResetFrame(&second_frame); 356 for (auto& frame : frames) {
504 ResetFrame(&third_frame); 357 ResetFrame(&frame);
358 }
505 359
506 first_frame.id_ = 1; 360 std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
507 second_frame.id_ = 2; 361 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
508 third_frame.id_ = 3; 362 frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted;
509 second_frame.vad_activity_ = AudioFrame::kVadPassive; 363 std::vector<bool> expected_status(kAudioSources, true);
364 expected_status[0] = false;
510 365
511 AddParticipant(&first_frame, MixerParticipant::AudioFrameInfo::kNormal); 366 MixAndCompare(frames, frame_info, expected_status);
512 AddParticipant(&second_frame, MixerParticipant::AudioFrameInfo::kMuted);
513 AddParticipant(&third_frame, MixerParticipant::AudioFrameInfo::kMuted);
514
515 for (int i = 0; i < 3; ++i) {
516 MixAndCompare();
517 }
518 } 367 }
519 368
520 TEST_F(CompareWithOldMixerTest, ManyParticipantsDifferentFrames) { 369 TEST(AudioMixer, PassiveShouldMixAfterNormal) {
521 Reset(); 370 constexpr int kAudioSources =
522 constexpr int kNumParticipants = 20; 371 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
523 AudioFrame audio_frames[kNumParticipants];
524 372
525 for (int i = 0; i < kNumParticipants; ++i) { 373 std::vector<AudioFrame> frames(kAudioSources);
526 ResetFrame(&audio_frames[i]); 374 for (auto& frame : frames) {
527 audio_frames[i].id_ = 1; 375 ResetFrame(&frame);
528 audio_frames[i].data_[10] = 100 * (i % 5);
529 audio_frames[i].data_[100] = 100 * (i % 5);
530 if (i % 2 == 0) {
531 audio_frames[i].vad_activity_ = AudioFrame::kVadPassive;
532 }
533 } 376 }
534 377
535 for (int i = 0; i < kNumParticipants; ++i) { 378 std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
536 if (i % 2 == 0) { 379 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
537 AddParticipant(&audio_frames[i], 380 frames[0].vad_activity_ = AudioFrame::kVadPassive;
538 MixerParticipant::AudioFrameInfo::kMuted); 381 std::vector<bool> expected_status(kAudioSources, true);
539 } else { 382 expected_status[0] = false;
540 AddParticipant(&audio_frames[i], 383
541 MixerParticipant::AudioFrameInfo::kNormal); 384 MixAndCompare(frames, frame_info, expected_status);
542 }
543 MixAndCompare();
544 }
545 } 385 }
546 386
387 TEST(AudioMixer, ActiveShouldMixBeforeLoud) {
388 constexpr int kAudioSources =
389 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
390
391 std::vector<AudioFrame> frames(kAudioSources);
392 for (auto& frame : frames) {
393 ResetFrame(&frame);
394 }
395
396 std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
397 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
398 frames[0].vad_activity_ = AudioFrame::kVadPassive;
399 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100,
400 std::numeric_limits<int16_t>::max());
401 std::vector<bool> expected_status(kAudioSources, true);
402 expected_status[0] = false;
403
404 MixAndCompare(frames, frame_info, expected_status);
405 }
406
407 TEST(AudioMixer, UnmutedShouldMixBeforeLoud) {
408 constexpr int kAudioSources =
409 NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
410
411 std::vector<AudioFrame> frames(kAudioSources);
412 for (auto& frame : frames) {
413 ResetFrame(&frame);
414 }
415
416 std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
417 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
418 frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted;
419 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100,
420 std::numeric_limits<int16_t>::max());
421 std::vector<bool> expected_status(kAudioSources, true);
422 expected_status[0] = false;
423
424 MixAndCompare(frames, frame_info, expected_status);
425 }
547 } // namespace webrtc 426 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_mixer/new_audio_conference_mixer_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698