Chromium Code Reviews| Index: webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc |
| 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 0000000000000000000000000000000000000000..13010937b38b6f3d9cd06a53798e77cbd29163de |
| --- /dev/null |
| +++ b/webrtc/modules/audio_conference_mixer/test/audio_conference_mixer_unittest.cc |
| @@ -0,0 +1,166 @@ |
| +/* |
| + * 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 "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" |
| + |
| +#include "testing/gmock/include/gmock/gmock.h" |
|
Andrew MacDonald
2015/08/18 04:03:48
This can go with the other includes.
|
| + |
| +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)); |
|
Andrew MacDonald
2015/08/18 04:03:48
If you always want this behavior, don't mock it, b
minyue-webrtc
2015/08/25 15:36:12
The reason that I mock GetAudioFrame is that I wan
ajm
2015/08/25 16:46:03
Ah OK. You can often define the methods actions di
|
| + } |
| + MOCK_METHOD2(GetAudioFrame, |
| + int32_t(const int32_t id, AudioFrame& audio_frame)); |
| + MOCK_METHOD1(NeededFrequency, int32_t(const int32_t id)); |
| + AudioFrame fake_frame_; |
|
Andrew MacDonald
2015/08/18 04:03:48
This should be private with a setter.
minyue-webrtc
2015/08/25 15:36:12
Yes, it can be nicer but the it is more complicate
ajm
2015/08/25 16:46:03
The typical way to do this is:
AudioFrame* fake_fr
minyue-webrtc
2015/08/31 14:28:39
I like the proposal, changes made accordingly.
|
| + private: |
| + int32_t FakeAudioFrame(const int32_t id, AudioFrame& audio_frame) { |
| + audio_frame.CopyFrom(fake_frame_); |
| + return 0; |
| + } |
| +}; |
| + |
| +TEST(AudioConferenceMixer, AnonymousAndUnanonymous) { |
|
Andrew MacDonald
2015/08/18 04:03:48
Nonanonymous is a bit more natural (but also weird
minyue-webrtc
2015/08/25 15:36:12
How about "Named"?
ajm
2015/08/25 16:46:03
Nice.
|
| + const int kId = 1; |
| + // Should not matter even if partipants are more than |
| + // kMaximumAmountOfMixedParticipants. |
| + const int kUnanonymous = |
| + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; |
| + const int kAnonymous = |
| + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; |
| + |
| + rtc::scoped_ptr<AudioConferenceMixer> mixer; |
| + mixer.reset(AudioConferenceMixer::Create(kId)); |
|
Andrew MacDonald
2015/08/18 04:03:48
Don't reset, assign directly:
rtc::scoped_ptr<Audi
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + |
| + MockMixerParticipant unanonymous[kUnanonymous]; |
| + MockMixerParticipant anonymous[kAnonymous]; |
|
Andrew MacDonald
2015/08/18 04:03:48
Use vectors.
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + |
| + bool ret; |
| + for (int i = 0; i < kUnanonymous; i++) { |
|
Andrew MacDonald
2015/08/18 04:03:48
nit: ++i and below
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + EXPECT_EQ(0, mixer->SetMixabilityStatus(unanonymous[i], true)); |
| + EXPECT_EQ(0, mixer->MixabilityStatus(unanonymous[i], ret)); |
|
Andrew MacDonald
2015/08/18 04:03:48
Is there any value in testing this with more than
minyue-webrtc
2015/08/25 15:36:12
May be not very needed. But I made the number of "
|
| + EXPECT_TRUE(ret); |
| + } |
| + |
| + for (int i = 0; i < kAnonymous; i++) { |
|
Andrew MacDonald
2015/08/18 04:03:48
Same here, is this loop adding any value? And the
minyue-webrtc
2015/08/25 15:36:12
I made the number of "named" to be larger than kMa
|
| + // 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_EQ(0, mixer->MixabilityStatus(anonymous[i], ret)); |
| + EXPECT_TRUE(ret); |
| + EXPECT_EQ(0, mixer->AnonymousMixabilityStatus(anonymous[i], ret)); |
| + EXPECT_FALSE(ret); |
| + |
| + EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(anonymous[i], true)); |
| + EXPECT_EQ(0, mixer->AnonymousMixabilityStatus(anonymous[i], ret)); |
| + EXPECT_TRUE(ret); |
| + |
| + // Anonymous participants do not show status by MixabilityStatus. |
| + EXPECT_EQ(0, mixer->MixabilityStatus(anonymous[i], ret)); |
| + EXPECT_FALSE(ret); |
| + } |
| + |
| + for (int i = 0; i < kUnanonymous; i++) { |
| + EXPECT_EQ(0, mixer->SetMixabilityStatus(unanonymous[i], false)); |
| + EXPECT_EQ(0, mixer->MixabilityStatus(unanonymous[i], ret)); |
| + EXPECT_FALSE(ret); |
| + } |
| + |
| + for (int i = 0; i < kAnonymous - 1; i++) { |
| + EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(anonymous[i], false)); |
| + EXPECT_EQ(0, mixer->AnonymousMixabilityStatus(anonymous[i], ret)); |
| + EXPECT_FALSE(ret); |
| + // SetAnonymousMixabilityStatus(anonymous, false) moves anonymous to the |
| + // unanonymous group. |
| + EXPECT_EQ(0, mixer->MixabilityStatus(anonymous[i], ret)); |
| + EXPECT_TRUE(ret); |
| + } |
| + |
| + // SetMixabilityStatus(anonymous, false) will remove anonymous from both |
| + // anonymous and unanonymous groups. |
| + EXPECT_EQ(0, mixer->SetMixabilityStatus(anonymous[kAnonymous - 1], false)); |
| + EXPECT_EQ(0, mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1], |
| + ret)); |
| + EXPECT_FALSE(ret); |
| + EXPECT_EQ(0, mixer->MixabilityStatus(anonymous[kAnonymous - 1], ret)); |
| + EXPECT_FALSE(ret); |
| +} |
| + |
| +TEST(AudioConferenceMixer, LargestEnergyVadActiveMixed) { |
| + const int kId = 1; |
| + const int kParticipants = |
| + AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 3; |
| + |
| + rtc::scoped_ptr<AudioConferenceMixer> mixer; |
| + mixer.reset(AudioConferenceMixer::Create(kId)); |
|
Andrew MacDonald
2015/08/18 04:03:48
As above, reset is not needed.
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + |
| + MockAudioMixerOutputReceiver output_receiver; |
| + EXPECT_EQ(0, mixer->RegisterMixedStreamCallback(output_receiver)); |
| + |
| + MockMixerParticipant participants[kParticipants]; |
|
Andrew MacDonald
2015/08/18 04:03:48
vector
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + |
| + for (int i = 0; i < kParticipants; i++) { |
| + participants[i].fake_frame_.UpdateFrame(i, 0, nullptr, 320, 32000, |
|
Andrew MacDonald
2015/08/18 04:03:48
This is a rarely used method. Could you just set t
minyue-webrtc
2015/08/25 15:36:12
I searched for its usage, and found that it is not
ajm
2015/08/25 16:46:03
I'd argue that this is _less_ readable since you h
minyue-webrtc
2015/08/31 14:28:39
I'd take your initial suggestion.
|
| + AudioFrame::kNormalSpeech, |
| + AudioFrame::kVadActive, 1, 0); |
| + // Use 80 to escape from ramped-in window. |
|
Andrew MacDonald
2015/08/18 04:03:48
Do you mean that you need to choose a late enough
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + 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(32000)); |
| + } |
| + |
| + // 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()); |
| + |
| + bool ret; |
|
Andrew MacDonald
2015/08/18 04:03:48
Instead of ret, name this what it is: is_mixed.
minyue-webrtc
2015/08/25 15:36:12
Done.
|
| + for (int i = 0; i < kParticipants; i++) { |
| + EXPECT_EQ(0, participants[i].IsMixed(ret)); |
| + if (i == kParticipants - 1 || i < kParticipants - 1 - |
| + AudioConferenceMixer::kMaximumAmountOfMixedParticipants) { |
| + EXPECT_FALSE(ret) << "Mixing status of Participant #" << i << " wrong."; |
| + } else { |
| + EXPECT_TRUE(ret) << "Mixing status of Participant #" << i << " wrong."; |
| + } |
| + } |
| + |
| + EXPECT_EQ(0, mixer->UnRegisterMixedStreamCallback()); |
| +} |
| + |
| +} // namespace webrtc |