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

Unified Diff: webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc

Issue 2111293003: Removed callback between old AudioConferenceMixer and OutputMixer. The audio frame with mixed audio… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@new_mixer_format
Patch Set: Renamed variables, removed DCHECK(false), changed back copyright years. Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc
diff --git a/webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc b/webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5071386bc4aaa51d57e371b39839dcdcb6354dd2
--- /dev/null
+++ b/webrtc/modules/audio_mixer/test/audio_mixer_unittest.cc
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2016 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 <memory>
+
+#include "testing/gmock/include/gmock/gmock.h"
+
+#include "webrtc/modules/audio_conference_mixer/source/audio_frame_manipulator.h"
+#include "webrtc/modules/audio_mixer/audio_mixer.h"
+#include "webrtc/modules/audio_mixer/include/audio_mixer_defines.h"
+#include "webrtc/modules/audio_mixer/include/new_audio_conference_mixer.h"
+#include "webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.h"
+
+using testing::_;
+using testing::AtLeast;
+using testing::Invoke;
+using testing::Return;
+
+using webrtc::voe::AudioMixer;
+
+namespace webrtc {
+class MockMixerAudioSource : public MixerAudioSource {
+ public:
+ MockMixerAudioSource() {
+ ON_CALL(*this, GetAudioFrame(_, _))
+ .WillByDefault(Invoke(this, &MockMixerAudioSource::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;
+ }
+};
+
+class BothMixersTest : public testing::Test {
+ protected:
+ BothMixersTest() {
+ // Create an OutputMixer.
+ AudioMixer::Create(audio_mixer_, kId);
+
+ // Create one mixer participant and add it to the mixer.
+ EXPECT_EQ(0, audio_mixer_->SetMixabilityStatus(participant_, true));
+
+ // Each iteration, the participant will return a frame with this content:
+ participant_.fake_frame()->id_ = 1;
+ participant_.fake_frame()->sample_rate_hz_ = kSampleRateHz;
+ participant_.fake_frame()->speech_type_ = AudioFrame::kNormalSpeech;
+ participant_.fake_frame()->vad_activity_ = AudioFrame::kVadActive;
+ participant_.fake_frame()->num_channels_ = 1;
+
+ // We modify one sample within the RampIn window and one sample
+ // outside of it.
+ participant_.fake_frame()->data_[10] = 100;
+ participant_.fake_frame()->data_[20] = -200;
+ participant_.fake_frame()->data_[30] = 300;
+ participant_.fake_frame()->data_[90] = -400;
+
+ // Frame duration 10ms.
+ participant_.fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
+ EXPECT_CALL(participant_, NeededFrequency(_))
+ .WillRepeatedly(Return(kSampleRateHz));
+ }
+
+ ~BothMixersTest() { AudioMixer::Destroy(audio_mixer_); }
+
+ // Mark the participant as 'unmixed' last round.
+ void ResetAudioSource() { participant_._mixHistory->SetIsMixed(false); }
+
+ AudioMixer* audio_mixer_;
+ MockMixerAudioSource participant_;
+ AudioFrame mixing_round_frame, mixed_results_frame_;
+
+ constexpr static int kSampleRateHz = 48000;
+ constexpr static int kId = 1;
+};
+
+TEST(AudioMixer, AnonymousAndNamed) {
+ constexpr int kId = 1;
+ // Should not matter even if partipants are more than
+ // kMaximumAmountOfMixedAudioSources.
+ constexpr int kNamed =
+ NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
+ constexpr int kAnonymous =
+ NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 1;
+
+ std::unique_ptr<NewAudioConferenceMixer> mixer(
+ NewAudioConferenceMixer::Create(kId));
+
+ MockMixerAudioSource named[kNamed];
+ MockMixerAudioSource 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) {
+ // AudioSource 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(AudioMixer, LargestEnergyVadActiveMixed) {
+ const int kId = 1;
+ const int kAudioSources =
+ NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources + 3;
+ const int kSampleRateHz = 32000;
+
+ std::unique_ptr<NewAudioConferenceMixer> mixer(
+ NewAudioConferenceMixer::Create(kId));
+
+ MockMixerAudioSource participants[kAudioSources];
+
+ for (int i = 0; i < kAudioSources; ++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[kAudioSources - 1].fake_frame()->vad_activity_ =
+ AudioFrame::kVadPassive;
+
+ AudioFrame audio_frame;
+ mixer->Mix(&audio_frame);
+
+ for (int i = 0; i < kAudioSources; ++i) {
+ bool is_mixed = participants[i].IsMixed();
+ if (i == kAudioSources - 1 ||
+ i < kAudioSources - 1 -
+ NewAudioConferenceMixer::kMaximumAmountOfMixedAudioSources) {
+ EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i
+ << " wrong.";
+ } else {
+ EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i
+ << " wrong.";
+ }
+ }
+}
+
+TEST_F(BothMixersTest, CompareInitialFrameAudio) {
+ EXPECT_CALL(participant_, GetAudioFrame(_, _)).Times(AtLeast(1));
+
+ // Make sure the participant is marked as 'non-mixed' so that it is
+ // ramped in next round.
+ ResetAudioSource();
+
+ // Construct the expected sound for the first mixing round.
+ mixing_round_frame.CopyFrom(*participant_.fake_frame());
+ RampIn(mixing_round_frame);
+
+ // Mix frames and put the result into a frame.
+ audio_mixer_->MixActiveChannels();
+ audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_);
+
+ // Compare the received frame with the expected.
+ EXPECT_EQ(mixing_round_frame.sample_rate_hz_,
+ mixed_results_frame_.sample_rate_hz_);
+ EXPECT_EQ(mixing_round_frame.num_channels_,
+ mixed_results_frame_.num_channels_);
+ EXPECT_EQ(mixing_round_frame.samples_per_channel_,
+ mixed_results_frame_.samples_per_channel_);
+ EXPECT_EQ(0, memcmp(mixing_round_frame.data_, mixed_results_frame_.data_,
+ sizeof(mixing_round_frame.data_)));
+}
+
+TEST_F(BothMixersTest, CompareSecondFrameAudio) {
+ EXPECT_CALL(participant_, GetAudioFrame(_, _)).Times(AtLeast(1));
+
+ // Make sure the participant is marked as 'non-mixed' so that it is
+ // ramped in next round.
+ ResetAudioSource();
+
+ // Do one mixing iteration.
+ audio_mixer_->MixActiveChannels();
+
+ // Mix frames a second time and compare with the expected frame
+ // (which is the participant's frame).
+ audio_mixer_->MixActiveChannels();
+ audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_);
+ EXPECT_EQ(0,
+ memcmp(participant_.fake_frame()->data_, mixed_results_frame_.data_,
+ sizeof(mixing_round_frame.data_)));
+}
+
+} // namespace webrtc
« no previous file with comments | « webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698