diff options
Diffstat (limited to 'webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc')
-rw-r--r-- | webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc b/webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc new file mode 100644 index 0000000000..d4fbd205f1 --- /dev/null +++ b/webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "testing/gmock/include/gmock/gmock.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h" +#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h" + +namespace webrtc { + +using testing::_; +using testing::AtLeast; +using testing::Invoke; +using testing::Return; + +class MockAudioMixerOutputReceiver : public AudioMixerOutputReceiver { + public: + MOCK_METHOD4(NewMixedAudio, void(const int32_t id, + const AudioFrame& general_audio_frame, + const AudioFrame** unique_audio_frames, + const uint32_t size)); +}; + +class MockMixerParticipant : public MixerParticipant { + public: + MockMixerParticipant() { + ON_CALL(*this, GetAudioFrame(_, _)) + .WillByDefault(Invoke(this, &MockMixerParticipant::FakeAudioFrame)); + } + MOCK_METHOD2(GetAudioFrame, + int32_t(const int32_t id, AudioFrame* audio_frame)); + MOCK_CONST_METHOD1(NeededFrequency, int32_t(const int32_t id)); + AudioFrame* fake_frame() { return &fake_frame_; } + + private: + AudioFrame fake_frame_; + int32_t FakeAudioFrame(const int32_t id, AudioFrame* audio_frame) { + audio_frame->CopyFrom(fake_frame_); + return 0; + } +}; + +TEST(AudioConferenceMixer, AnonymousAndNamed) { + const int kId = 1; + // Should not matter even if partipants are more than + // kMaximumAmountOfMixedParticipants. + const int kNamed = + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; + const int kAnonymous = + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; + + rtc::scoped_ptr<AudioConferenceMixer> mixer( + AudioConferenceMixer::Create(kId)); + + MockMixerParticipant named[kNamed]; + MockMixerParticipant anonymous[kAnonymous]; + + for (int i = 0; i < kNamed; ++i) { + EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], true)); + EXPECT_TRUE(mixer->MixabilityStatus(named[i])); + } + + for (int i = 0; i < kAnonymous; ++i) { + // Participant must be registered before turning it into anonymous. + EXPECT_EQ(-1, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true)); + EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[i], true)); + EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i])); + EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i])); + + EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true)); + EXPECT_TRUE(mixer->AnonymousMixabilityStatus(anonymous[i])); + + // Anonymous participants do not show status by MixabilityStatus. + EXPECT_FALSE(mixer->MixabilityStatus(anonymous[i])); + } + + for (int i = 0; i < kNamed; ++i) { + EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], false)); + EXPECT_FALSE(mixer->MixabilityStatus(named[i])); + } + + for (int i = 0; i < kAnonymous - 1; i++) { + EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], false)); + EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i])); + + // SetAnonymousMixabilityStatus(anonymous, false) moves anonymous to the + // named group. + EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i])); + } + + // SetMixabilityStatus(anonymous, false) will remove anonymous from both + // anonymous and named groups. + EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false)); + EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1])); + EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1])); +} + +TEST(AudioConferenceMixer, LargestEnergyVadActiveMixed) { + const int kId = 1; + const int kParticipants = + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 3; + const int kSampleRateHz = 32000; + + rtc::scoped_ptr<AudioConferenceMixer> mixer( + AudioConferenceMixer::Create(kId)); + + MockAudioMixerOutputReceiver output_receiver; + EXPECT_EQ(0, mixer->RegisterMixedStreamCallback(&output_receiver)); + + MockMixerParticipant participants[kParticipants]; + + for (int i = 0; i < kParticipants; ++i) { + participants[i].fake_frame()->id_ = i; + participants[i].fake_frame()->sample_rate_hz_ = kSampleRateHz; + participants[i].fake_frame()->speech_type_ = AudioFrame::kNormalSpeech; + participants[i].fake_frame()->vad_activity_ = AudioFrame::kVadActive; + participants[i].fake_frame()->num_channels_ = 1; + + // Frame duration 10ms. + participants[i].fake_frame()->samples_per_channel_ = kSampleRateHz / 100; + + // We set the 80-th sample value since the first 80 samples may be + // modified by a ramped-in window. + participants[i].fake_frame()->data_[80] = i; + + EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true)); + EXPECT_CALL(participants[i], GetAudioFrame(_, _)) + .Times(AtLeast(1)); + EXPECT_CALL(participants[i], NeededFrequency(_)) + .WillRepeatedly(Return(kSampleRateHz)); + } + + // Last participant gives audio frame with passive VAD, although it has the + // largest energy. + participants[kParticipants - 1].fake_frame()->vad_activity_ = + AudioFrame::kVadPassive; + + EXPECT_CALL(output_receiver, NewMixedAudio(_, _, _, _)) + .Times(AtLeast(1)); + + EXPECT_EQ(0, mixer->Process()); + + for (int i = 0; i < kParticipants; ++i) { + bool is_mixed = participants[i].IsMixed(); + if (i == kParticipants - 1 || i < kParticipants - 1 - + AudioConferenceMixer::kMaximumAmountOfMixedParticipants) { + EXPECT_FALSE(is_mixed) << "Mixing status of Participant #" + << i << " wrong."; + } else { + EXPECT_TRUE(is_mixed) << "Mixing status of Participant #" + << i << " wrong."; + } + } + + EXPECT_EQ(0, mixer->UnRegisterMixedStreamCallback()); +} + +} // namespace webrtc |