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 <string.h> |
| 12 |
11 #include <memory> | 13 #include <memory> |
12 #include <utility> | 14 #include <utility> |
13 | 15 |
14 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "webrtc/base/bind.h" |
| 18 #include "webrtc/base/thread.h" |
15 #include "webrtc/modules/audio_mixer/audio_mixer_defines.h" | 19 #include "webrtc/modules/audio_mixer/audio_mixer_defines.h" |
16 #include "webrtc/modules/audio_mixer/audio_mixer.h" | 20 #include "webrtc/modules/audio_mixer/audio_mixer.h" |
17 | 21 |
18 using testing::_; | 22 using testing::_; |
19 using testing::Exactly; | 23 using testing::Exactly; |
20 using testing::Invoke; | 24 using testing::Invoke; |
21 using testing::Return; | 25 using testing::Return; |
22 | 26 |
23 namespace webrtc { | 27 namespace webrtc { |
24 | 28 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 for (int i = 0; i < num_audio_sources; i++) { | 100 for (int i = 0; i < num_audio_sources; i++) { |
97 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true)); | 101 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true)); |
98 EXPECT_CALL(participants[i], | 102 EXPECT_CALL(participants[i], |
99 GetAudioFrameWithMuted(_, kDefaultSampleRateHz)) | 103 GetAudioFrameWithMuted(_, kDefaultSampleRateHz)) |
100 .Times(Exactly(1)); | 104 .Times(Exactly(1)); |
101 } | 105 } |
102 | 106 |
103 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 107 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); |
104 | 108 |
105 for (int i = 0; i < num_audio_sources; i++) { | 109 for (int i = 0; i < num_audio_sources; i++) { |
106 EXPECT_EQ(participants[i].IsMixed(), expected_status[i]) | 110 EXPECT_EQ(expected_status[i], participants[i].IsMixed()) |
107 << "Mixed status of AudioSource #" << i << " wrong."; | 111 << "Mixed status of AudioSource #" << i << " wrong."; |
108 } | 112 } |
109 } | 113 } |
110 | 114 |
111 TEST(AudioMixer, AnonymousAndNamed) { | 115 TEST(AudioMixer, AnonymousAndNamed) { |
112 // Should not matter even if partipants are more than | 116 // Should not matter even if partipants are more than |
113 // kMaximumAmountOfMixedAudioSources. | 117 // kMaximumAmountOfMixedAudioSources. |
114 constexpr int kNamed = AudioMixer::kMaximumAmountOfMixedAudioSources + 1; | 118 constexpr int kNamed = AudioMixer::kMaximumAmountOfMixedAudioSources + 1; |
115 constexpr int kAnonymous = AudioMixer::kMaximumAmountOfMixedAudioSources + 1; | 119 constexpr int kAnonymous = AudioMixer::kMaximumAmountOfMixedAudioSources + 1; |
116 | 120 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 i < kAudioSources - 1 - AudioMixer::kMaximumAmountOfMixedAudioSources) { | 199 i < kAudioSources - 1 - AudioMixer::kMaximumAmountOfMixedAudioSources) { |
196 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i | 200 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i |
197 << " wrong."; | 201 << " wrong."; |
198 } else { | 202 } else { |
199 EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i | 203 EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i |
200 << " wrong."; | 204 << " wrong."; |
201 } | 205 } |
202 } | 206 } |
203 } | 207 } |
204 | 208 |
| 209 TEST(AudioMixer, FrameNotModifiedForSingleParticipant) { |
| 210 const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId)); |
| 211 |
| 212 MockMixerAudioSource participant; |
| 213 |
| 214 ResetFrame(participant.fake_frame()); |
| 215 const int n_samples = participant.fake_frame()->samples_per_channel_; |
| 216 |
| 217 // Modify the frame so that it's not zero. |
| 218 for (int j = 0; j < n_samples; j++) { |
| 219 participant.fake_frame()->data_[j] = j; |
| 220 } |
| 221 |
| 222 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); |
| 223 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, _)).Times(Exactly(2)); |
| 224 |
| 225 AudioFrame audio_frame; |
| 226 // Two mix iteration to compare after the ramp-up step. |
| 227 for (int i = 0; i < 2; i++) { |
| 228 mixer->Mix(kDefaultSampleRateHz, |
| 229 1, // number of channels |
| 230 &audio_frame); |
| 231 } |
| 232 |
| 233 EXPECT_EQ( |
| 234 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples)); |
| 235 } |
| 236 |
| 237 TEST(AudioMixer, FrameNotModifiedForSingleAnonymousParticipant) { |
| 238 const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId)); |
| 239 |
| 240 MockMixerAudioSource participant; |
| 241 |
| 242 ResetFrame(participant.fake_frame()); |
| 243 const int n_samples = participant.fake_frame()->samples_per_channel_; |
| 244 |
| 245 // Modify the frame so that it's not zero. |
| 246 for (int j = 0; j < n_samples; j++) { |
| 247 participant.fake_frame()->data_[j] = j; |
| 248 } |
| 249 |
| 250 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); |
| 251 EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&participant, true)); |
| 252 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, _)).Times(Exactly(2)); |
| 253 |
| 254 AudioFrame audio_frame; |
| 255 // Two mix iteration to compare after the ramp-up step. |
| 256 for (int i = 0; i < 2; i++) { |
| 257 mixer->Mix(kDefaultSampleRateHz, |
| 258 1, // number of channels |
| 259 &audio_frame); |
| 260 } |
| 261 |
| 262 EXPECT_EQ( |
| 263 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples)); |
| 264 } |
| 265 |
205 TEST(AudioMixer, ParticipantSampleRate) { | 266 TEST(AudioMixer, ParticipantSampleRate) { |
206 const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId)); | 267 const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId)); |
207 | 268 |
208 MockMixerAudioSource participant; | 269 MockMixerAudioSource participant; |
209 ResetFrame(participant.fake_frame()); | 270 ResetFrame(participant.fake_frame()); |
210 | 271 |
211 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); | 272 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true)); |
212 for (auto frequency : {8000, 16000, 32000, 48000}) { | 273 for (auto frequency : {8000, 16000, 32000, 48000}) { |
213 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, frequency)) | 274 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, frequency)) |
214 .Times(Exactly(1)); | 275 .Times(Exactly(1)); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 386 } |
326 | 387 |
327 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 388 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); |
328 | 389 |
329 // The most quiet participant should not have been mixed. | 390 // The most quiet participant should not have been mixed. |
330 EXPECT_FALSE(participants[0].IsMixed()) | 391 EXPECT_FALSE(participants[0].IsMixed()) |
331 << "Mixed status of AudioSource #0 wrong."; | 392 << "Mixed status of AudioSource #0 wrong."; |
332 | 393 |
333 // The loudest participants should have been mixed. | 394 // The loudest participants should have been mixed. |
334 for (int i = 1; i < kAudioSources; i++) { | 395 for (int i = 1; i < kAudioSources; i++) { |
335 EXPECT_EQ(participants[i].IsMixed(), true) | 396 EXPECT_EQ(true, participants[i].IsMixed()) |
336 << "Mixed status of AudioSource #" << i << " wrong."; | 397 << "Mixed status of AudioSource #" << i << " wrong."; |
337 } | 398 } |
338 } | 399 } |
339 | 400 |
| 401 // This test checks that the initialization and participant addition |
| 402 // can be done on a different thread. |
| 403 TEST(AudioMixer, ConstructFromOtherThread) { |
| 404 std::unique_ptr<rtc::Thread> init_thread = rtc::Thread::Create(); |
| 405 std::unique_ptr<rtc::Thread> participant_thread = rtc::Thread::Create(); |
| 406 init_thread->Start(); |
| 407 std::unique_ptr<AudioMixer> mixer( |
| 408 init_thread->Invoke<std::unique_ptr<AudioMixer>>( |
| 409 RTC_FROM_HERE, std::bind(&AudioMixer::Create, kId))); |
| 410 MockMixerAudioSource participant; |
| 411 |
| 412 ResetFrame(participant.fake_frame()); |
| 413 |
| 414 participant_thread->Start(); |
| 415 EXPECT_EQ(0, participant_thread->Invoke<int>( |
| 416 RTC_FROM_HERE, rtc::Bind(&AudioMixer::SetMixabilityStatus, |
| 417 mixer.get(), &participant, true))); |
| 418 |
| 419 EXPECT_EQ( |
| 420 0, participant_thread->Invoke<int>( |
| 421 RTC_FROM_HERE, rtc::Bind(&AudioMixer::SetAnonymousMixabilityStatus, |
| 422 mixer.get(), &participant, true))); |
| 423 |
| 424 EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz)) |
| 425 .Times(Exactly(1)); |
| 426 |
| 427 // Do one mixer iteration |
| 428 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); |
| 429 } |
| 430 |
340 TEST(AudioMixer, MutedShouldMixAfterUnmuted) { | 431 TEST(AudioMixer, MutedShouldMixAfterUnmuted) { |
341 constexpr int kAudioSources = | 432 constexpr int kAudioSources = |
342 AudioMixer::kMaximumAmountOfMixedAudioSources + 1; | 433 AudioMixer::kMaximumAmountOfMixedAudioSources + 1; |
343 | 434 |
344 std::vector<AudioFrame> frames(kAudioSources); | 435 std::vector<AudioFrame> frames(kAudioSources); |
345 for (auto& frame : frames) { | 436 for (auto& frame : frames) { |
346 ResetFrame(&frame); | 437 ResetFrame(&frame); |
347 } | 438 } |
348 | 439 |
349 std::vector<MixerAudioSource::AudioFrameInfo> frame_info( | 440 std::vector<MixerAudioSource::AudioFrameInfo> frame_info( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal); | 497 kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal); |
407 frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted; | 498 frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted; |
408 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100, | 499 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100, |
409 std::numeric_limits<int16_t>::max()); | 500 std::numeric_limits<int16_t>::max()); |
410 std::vector<bool> expected_status(kAudioSources, true); | 501 std::vector<bool> expected_status(kAudioSources, true); |
411 expected_status[0] = false; | 502 expected_status[0] = false; |
412 | 503 |
413 MixAndCompare(frames, frame_info, expected_status); | 504 MixAndCompare(frames, frame_info, expected_status); |
414 } | 505 } |
415 } // namespace webrtc | 506 } // namespace webrtc |
OLD | NEW |