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