OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 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 |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "testing/gmock/include/gmock/gmock.h" |
| 12 #include "webrtc/base/scoped_ptr.h" |
| 13 #include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer
.h" |
| 14 #include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer
_defines.h" |
| 15 |
| 16 namespace webrtc { |
| 17 |
| 18 using testing::_; |
| 19 using testing::AtLeast; |
| 20 using testing::Invoke; |
| 21 using testing::Return; |
| 22 |
| 23 class MockAudioMixerOutputReceiver : public AudioMixerOutputReceiver { |
| 24 public: |
| 25 MOCK_METHOD4(NewMixedAudio, void(const int32_t id, |
| 26 const AudioFrame& general_audio_frame, |
| 27 const AudioFrame** unique_audio_frames, |
| 28 const uint32_t size)); |
| 29 }; |
| 30 |
| 31 class MockMixerParticipant : public MixerParticipant { |
| 32 public: |
| 33 MockMixerParticipant() { |
| 34 ON_CALL(*this, GetAudioFrame(_, _)) |
| 35 .WillByDefault(Invoke(this, &MockMixerParticipant::FakeAudioFrame)); |
| 36 } |
| 37 MOCK_METHOD2(GetAudioFrame, |
| 38 int32_t(const int32_t id, AudioFrame* audio_frame)); |
| 39 MOCK_CONST_METHOD1(NeededFrequency, int32_t(const int32_t id)); |
| 40 AudioFrame* fake_frame() { return &fake_frame_; } |
| 41 |
| 42 private: |
| 43 AudioFrame fake_frame_; |
| 44 int32_t FakeAudioFrame(const int32_t id, AudioFrame* audio_frame) { |
| 45 audio_frame->CopyFrom(fake_frame_); |
| 46 return 0; |
| 47 } |
| 48 }; |
| 49 |
| 50 TEST(AudioConferenceMixer, AnonymousAndNamed) { |
| 51 const int kId = 1; |
| 52 // Should not matter even if partipants are more than |
| 53 // kMaximumAmountOfMixedParticipants. |
| 54 const int kNamed = |
| 55 AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; |
| 56 const int kAnonymous = |
| 57 AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1; |
| 58 |
| 59 rtc::scoped_ptr<AudioConferenceMixer> mixer( |
| 60 AudioConferenceMixer::Create(kId)); |
| 61 |
| 62 std::vector<MockMixerParticipant> named(kNamed); |
| 63 std::vector<MockMixerParticipant> anonymous(kAnonymous); |
| 64 |
| 65 for (int i = 0; i < kNamed; ++i) { |
| 66 EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], true)); |
| 67 EXPECT_TRUE(mixer->MixabilityStatus(named[i])); |
| 68 } |
| 69 |
| 70 for (int i = 0; i < kAnonymous; ++i) { |
| 71 // Participant must be registered before turning it into anonymous. |
| 72 EXPECT_EQ(-1, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true)); |
| 73 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[i], true)); |
| 74 EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i])); |
| 75 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i])); |
| 76 |
| 77 EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true)); |
| 78 EXPECT_TRUE(mixer->AnonymousMixabilityStatus(anonymous[i])); |
| 79 |
| 80 // Anonymous participants do not show status by MixabilityStatus. |
| 81 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[i])); |
| 82 } |
| 83 |
| 84 for (int i = 0; i < kNamed; ++i) { |
| 85 EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], false)); |
| 86 EXPECT_FALSE(mixer->MixabilityStatus(named[i])); |
| 87 } |
| 88 |
| 89 for (int i = 0; i < kAnonymous - 1; i++) { |
| 90 EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], false)); |
| 91 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i])); |
| 92 |
| 93 // SetAnonymousMixabilityStatus(anonymous, false) moves anonymous to the |
| 94 // named group. |
| 95 EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i])); |
| 96 } |
| 97 |
| 98 // SetMixabilityStatus(anonymous, false) will remove anonymous from both |
| 99 // anonymous and named groups. |
| 100 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false)); |
| 101 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1])); |
| 102 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1])); |
| 103 } |
| 104 |
| 105 TEST(AudioConferenceMixer, LargestEnergyVadActiveMixed) { |
| 106 const int kId = 1; |
| 107 const int kParticipants = |
| 108 AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 3; |
| 109 const int kSampleRateHz = 32000; |
| 110 |
| 111 rtc::scoped_ptr<AudioConferenceMixer> mixer( |
| 112 AudioConferenceMixer::Create(kId)); |
| 113 |
| 114 MockAudioMixerOutputReceiver output_receiver; |
| 115 EXPECT_EQ(0, mixer->RegisterMixedStreamCallback(&output_receiver)); |
| 116 |
| 117 std::vector<MockMixerParticipant> participants(kParticipants); |
| 118 |
| 119 for (int i = 0; i < kParticipants; ++i) { |
| 120 participants[i].fake_frame()->id_ = i; |
| 121 participants[i].fake_frame()->sample_rate_hz_ = kSampleRateHz; |
| 122 participants[i].fake_frame()->speech_type_ = AudioFrame::kNormalSpeech; |
| 123 participants[i].fake_frame()->vad_activity_ = AudioFrame::kVadActive; |
| 124 participants[i].fake_frame()->num_channels_ = 1; |
| 125 |
| 126 // Frame duration 10ms. |
| 127 participants[i].fake_frame()->samples_per_channel_ = kSampleRateHz / 100; |
| 128 |
| 129 // We set the 80-th sample value since the first 80 samples may be |
| 130 // modified by a ramped-in window. |
| 131 participants[i].fake_frame()->data_[80] = i; |
| 132 |
| 133 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true)); |
| 134 EXPECT_CALL(participants[i], GetAudioFrame(_, _)) |
| 135 .Times(AtLeast(1)); |
| 136 EXPECT_CALL(participants[i], NeededFrequency(_)) |
| 137 .WillRepeatedly(Return(kSampleRateHz)); |
| 138 } |
| 139 |
| 140 // Last participant gives audio frame with passive VAD, although it has the |
| 141 // largest energy. |
| 142 participants[kParticipants - 1].fake_frame()->vad_activity_ = |
| 143 AudioFrame::kVadPassive; |
| 144 |
| 145 EXPECT_CALL(output_receiver, NewMixedAudio(_, _, _, _)) |
| 146 .Times(AtLeast(1)); |
| 147 |
| 148 EXPECT_EQ(0, mixer->Process()); |
| 149 |
| 150 for (int i = 0; i < kParticipants; ++i) { |
| 151 bool is_mixed = participants[i].IsMixed(); |
| 152 if (i == kParticipants - 1 || i < kParticipants - 1 - |
| 153 AudioConferenceMixer::kMaximumAmountOfMixedParticipants) { |
| 154 EXPECT_FALSE(is_mixed) << "Mixing status of Participant #" |
| 155 << i << " wrong."; |
| 156 } else { |
| 157 EXPECT_TRUE(is_mixed) << "Mixing status of Participant #" |
| 158 << i << " wrong."; |
| 159 } |
| 160 } |
| 161 |
| 162 EXPECT_EQ(0, mixer->UnRegisterMixedStreamCallback()); |
| 163 } |
| 164 |
| 165 } // namespace webrtc |
OLD | NEW |