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

Side by Side 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: Added variable name. 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
tommi 2016/07/06 19:42:17 update this header (it's 2016)
aleloi 2016/07/07 09:20:16 Done. I also updated the other files (they are cop
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 <memory>
12
13 #include "testing/gmock/include/gmock/gmock.h"
14
15 #include "webrtc/modules/audio_conference_mixer/source/audio_frame_manipulator.h "
16 #include "webrtc/modules/audio_mixer/audio_mixer.h"
17 #include "webrtc/modules/audio_mixer/include/new_audio_conference_mixer.h"
18 #include "webrtc/modules/audio_mixer/include/audio_mixer_defines.h"
tommi 2016/07/06 19:42:17 fix include order. git cl format could help.
aleloi 2016/07/07 09:20:16 Done.
19 #include "webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.h"
20
21 namespace webrtc {
ivoc 2016/07/07 13:46:16 Move this below the "using" lines below.
aleloi 2016/07/07 14:29:12 Done.
22
23 using testing::_;
24 using testing::AtLeast;
25 using testing::Invoke;
26 using testing::Return;
27
28 using voe::AudioMixer;
29
30 class MockMixerAudioSource : public MixerAudioSource {
31 public:
32 MockMixerAudioSource() {
33 ON_CALL(*this, GetAudioFrame(_, _))
34 .WillByDefault(Invoke(this, &MockMixerAudioSource::FakeAudioFrame));
35 }
36 MOCK_METHOD2(GetAudioFrame,
37 int32_t(const int32_t id, AudioFrame* audio_frame));
38 MOCK_CONST_METHOD1(NeededFrequency, int32_t(const int32_t id));
39 AudioFrame* fake_frame() { return &fake_frame_; }
40
41 private:
42 AudioFrame fake_frame_;
43 int32_t FakeAudioFrame(const int32_t id, AudioFrame* audio_frame) {
44 audio_frame->CopyFrom(fake_frame_);
45 return 0;
46 }
47 };
48
49 class BothMixersTest : public testing::Test {
50 protected:
51 BothMixersTest() {
52 // Create an OutputMixer.
53 AudioMixer::Create(audio_mixer_, kId);
54
55 // Create one mixer participant and add it to the mixer.
56 EXPECT_EQ(0, audio_mixer_->SetMixabilityStatus(participant_, true));
57
58 // Each iteration, the participant will return a frame with this content:
59 participant_.fake_frame()->id_ = 1;
60 participant_.fake_frame()->sample_rate_hz_ = kSampleRateHz;
61 participant_.fake_frame()->speech_type_ = AudioFrame::kNormalSpeech;
62 participant_.fake_frame()->vad_activity_ = AudioFrame::kVadActive;
63 participant_.fake_frame()->num_channels_ = 1;
64
65 // We modify one sample within the RampIn window and one sample
66 // outside of it.
67 participant_.fake_frame()->data_[10] = 100;
68 participant_.fake_frame()->data_[20] = -200;
69 participant_.fake_frame()->data_[30] = 300;
70 participant_.fake_frame()->data_[90] = -400;
71
72 // Frame duration 10ms.
73 participant_.fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
74 EXPECT_CALL(participant_, NeededFrequency(_))
75 .WillRepeatedly(Return(kSampleRateHz));
76 }
77
78 ~BothMixersTest() { AudioMixer::Destroy(audio_mixer_); }
79
80 // Mark the participant as 'unmixed' last round.
81 void ResetParticipant() { participant_._mixHistory->SetIsMixed(false); }
82
83 AudioMixer* audio_mixer_;
84 MockMixerAudioSource participant_;
85 AudioFrame mixing_round_frame, mixed_results_frame_;
86
87 constexpr static int kSampleRateHz = 48000;
88 constexpr static int kId = 1;
89 };
90
91 TEST(AudioMixer, AnonymousAndNamed) {
92 const int kId = 1;
tommi 2016/07/06 19:42:17 nit: make this 'static const int kId'. For non st
aleloi 2016/07/07 09:20:16 Done. The test was mostly copied from modules/audi
93 // Should not matter even if partipants are more than
94 // kMaximumAmountOfMixedParticipants.
95 const int kNamed =
96 NewAudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1;
97 const int kAnonymous =
98 NewAudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1;
99
100 std::unique_ptr<NewAudioConferenceMixer> mixer(
101 NewAudioConferenceMixer::Create(kId));
102
103 MockMixerAudioSource named[kNamed];
104 MockMixerAudioSource anonymous[kAnonymous];
105
106 for (int i = 0; i < kNamed; ++i) {
107 EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], true));
108 EXPECT_TRUE(mixer->MixabilityStatus(named[i]));
109 }
110
111 for (int i = 0; i < kAnonymous; ++i) {
112 // Participant must be registered before turning it into anonymous.
113 EXPECT_EQ(-1, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true));
114 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[i], true));
115 EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i]));
116 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i]));
117
118 EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true));
119 EXPECT_TRUE(mixer->AnonymousMixabilityStatus(anonymous[i]));
120
121 // Anonymous participants do not show status by MixabilityStatus.
122 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[i]));
123 }
124
125 for (int i = 0; i < kNamed; ++i) {
126 EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], false));
127 EXPECT_FALSE(mixer->MixabilityStatus(named[i]));
128 }
129
130 for (int i = 0; i < kAnonymous - 1; i++) {
131 EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], false));
132 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i]));
133
134 // SetAnonymousMixabilityStatus(anonymous, false) moves anonymous to the
135 // named group.
136 EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i]));
137 }
138
139 // SetMixabilityStatus(anonymous, false) will remove anonymous from both
140 // anonymous and named groups.
141 EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false));
142 EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1]));
143 EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1]));
144 }
145
146 TEST(AudioMixer, LargestEnergyVadActiveMixed) {
147 const int kId = 1;
148 const int kParticipants =
149 NewAudioConferenceMixer::kMaximumAmountOfMixedParticipants + 3;
150 const int kSampleRateHz = 32000;
151
152 std::unique_ptr<NewAudioConferenceMixer> mixer(
153 NewAudioConferenceMixer::Create(kId));
154
155 MockMixerAudioSource participants[kParticipants];
156
157 for (int i = 0; i < kParticipants; ++i) {
158 participants[i].fake_frame()->id_ = i;
159 participants[i].fake_frame()->sample_rate_hz_ = kSampleRateHz;
160 participants[i].fake_frame()->speech_type_ = AudioFrame::kNormalSpeech;
161 participants[i].fake_frame()->vad_activity_ = AudioFrame::kVadActive;
162 participants[i].fake_frame()->num_channels_ = 1;
163
164 // Frame duration 10ms.
165 participants[i].fake_frame()->samples_per_channel_ = kSampleRateHz / 100;
166
167 // We set the 80-th sample value since the first 80 samples may be
168 // modified by a ramped-in window.
169 participants[i].fake_frame()->data_[80] = i;
170
171 EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
172 EXPECT_CALL(participants[i], GetAudioFrame(_, _)).Times(AtLeast(1));
173 EXPECT_CALL(participants[i], NeededFrequency(_))
174 .WillRepeatedly(Return(kSampleRateHz));
175 }
176
177 // Last participant gives audio frame with passive VAD, although it has the
178 // largest energy.
179 participants[kParticipants - 1].fake_frame()->vad_activity_ =
180 AudioFrame::kVadPassive;
181
182 AudioFrame audio_frame;
183 mixer->Mix(&audio_frame);
184
185 for (int i = 0; i < kParticipants; ++i) {
186 bool is_mixed = participants[i].IsMixed();
187 if (i == kParticipants - 1 ||
188 i < kParticipants - 1 -
189 NewAudioConferenceMixer::kMaximumAmountOfMixedParticipants) {
190 EXPECT_FALSE(is_mixed) << "Mixing status of Participant #" << i
191 << " wrong.";
192 } else {
193 EXPECT_TRUE(is_mixed) << "Mixing status of Participant #" << i
194 << " wrong.";
195 }
196 }
197 }
198
199 TEST_F(BothMixersTest, CompareInitialFrameAudio) {
200 EXPECT_CALL(participant_, GetAudioFrame(_, _)).Times(AtLeast(1));
201
202 // Make sure the participant is marked as 'non-mixed' so that it is
203 // ramped in next round.
204 ResetParticipant();
205
206 // Construct the expected sound for the first mixing round.
207 mixing_round_frame.CopyFrom(*participant_.fake_frame());
208 RampIn(mixing_round_frame);
209
210 // Mix frames and put the result into a frame.
211 audio_mixer_->MixActiveChannels();
212 audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_);
213
214 // Compare the received frame with the expected.
215 EXPECT_EQ(mixing_round_frame.sample_rate_hz_,
216 mixed_results_frame_.sample_rate_hz_);
217 EXPECT_EQ(mixing_round_frame.num_channels_,
218 mixed_results_frame_.num_channels_);
219 EXPECT_EQ(mixing_round_frame.samples_per_channel_,
220 mixed_results_frame_.samples_per_channel_);
221 EXPECT_EQ(0, memcmp(mixing_round_frame.data_, mixed_results_frame_.data_,
222 sizeof(mixing_round_frame.data_)));
223 }
224
225 TEST_F(BothMixersTest, CompareSecondFrameAudio) {
226 EXPECT_CALL(participant_, GetAudioFrame(_, _)).Times(AtLeast(1));
227
228 // Make sure the participant is marked as 'non-mixed' so that it is
229 // ramped in next round.
230 ResetParticipant();
231
232 // Do one mixing iteration.
233 audio_mixer_->MixActiveChannels();
234
235 // Mix frames a second time and compare with the expected frame
236 // (which is the participant's frame).
237 audio_mixer_->MixActiveChannels();
238 audio_mixer_->GetMixedAudio(kSampleRateHz, 1, &mixed_results_frame_);
239 EXPECT_EQ(0,
240 memcmp(participant_.fake_frame()->data_, mixed_results_frame_.data_,
241 sizeof(mixing_round_frame.data_)));
242 }
243
244 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698