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

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