aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc
diff options
context:
space:
mode:
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.cc165
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