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 |