OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 class MockMixerAudioSource : public AudioMixer::Source { | 52 class MockMixerAudioSource : public AudioMixer::Source { |
53 public: | 53 public: |
54 MockMixerAudioSource() | 54 MockMixerAudioSource() |
55 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) { | 55 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) { |
56 ON_CALL(*this, GetAudioFrameWithInfo(_, _)) | 56 ON_CALL(*this, GetAudioFrameWithInfo(_, _)) |
57 .WillByDefault( | 57 .WillByDefault( |
58 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo)); | 58 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo)); |
59 ON_CALL(*this, PreferredSampleRate()) | |
60 .WillByDefault(Return(kDefaultSampleRateHz)); | |
59 } | 61 } |
60 | 62 |
61 MOCK_METHOD2(GetAudioFrameWithInfo, | 63 MOCK_METHOD2(GetAudioFrameWithInfo, |
62 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame)); | 64 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame)); |
63 | 65 |
64 MOCK_CONST_METHOD0(PreferredSampleRate, int()); | 66 MOCK_CONST_METHOD0(PreferredSampleRate, int()); |
65 MOCK_CONST_METHOD0(Ssrc, int()); | 67 MOCK_CONST_METHOD0(Ssrc, int()); |
66 | 68 |
67 AudioFrame* fake_frame() { return &fake_frame_; } | 69 AudioFrame* fake_frame() { return &fake_frame_; } |
68 AudioFrameInfo fake_info() { return fake_audio_frame_info_; } | 70 AudioFrameInfo fake_info() { return fake_audio_frame_info_; } |
(...skipping 28 matching lines...) Expand all Loading... | |
97 participants[i].fake_frame()->CopyFrom(frames[i]); | 99 participants[i].fake_frame()->CopyFrom(frames[i]); |
98 participants[i].set_fake_info(frame_info[i]); | 100 participants[i].set_fake_info(frame_info[i]); |
99 } | 101 } |
100 | 102 |
101 for (int i = 0; i < num_audio_sources; i++) { | 103 for (int i = 0; i < num_audio_sources; i++) { |
102 EXPECT_TRUE(mixer->AddSource(&participants[i])); | 104 EXPECT_TRUE(mixer->AddSource(&participants[i])); |
103 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) | 105 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) |
104 .Times(Exactly(1)); | 106 .Times(Exactly(1)); |
105 } | 107 } |
106 | 108 |
107 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 109 mixer->Mix(1, &frame_for_mixing); |
108 | 110 |
109 for (int i = 0; i < num_audio_sources; i++) { | 111 for (int i = 0; i < num_audio_sources; i++) { |
110 EXPECT_EQ(expected_status[i], | 112 EXPECT_EQ(expected_status[i], |
111 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) | 113 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) |
112 << "Mixed status of AudioSource #" << i << " wrong."; | 114 << "Mixed status of AudioSource #" << i << " wrong."; |
113 } | 115 } |
114 } | 116 } |
115 | 117 |
118 void MixMonoAtGivenNativeRate(int native_sample_rate, | |
119 AudioFrame* mix_frame, | |
120 rtc::scoped_refptr<AudioMixer> mixer, | |
121 MockMixerAudioSource* audio_source) { | |
122 ON_CALL(*audio_source, PreferredSampleRate()) | |
123 .WillByDefault(Return(native_sample_rate)); | |
124 audio_source->fake_frame()->sample_rate_hz_ = native_sample_rate; | |
125 audio_source->fake_frame()->samples_per_channel_ = native_sample_rate / 100; | |
126 | |
127 mixer->Mix(1, mix_frame); | |
128 } | |
129 | |
116 TEST(AudioMixer, LargestEnergyVadActiveMixed) { | 130 TEST(AudioMixer, LargestEnergyVadActiveMixed) { |
117 constexpr int kAudioSources = | 131 constexpr int kAudioSources = |
118 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3; | 132 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3; |
119 | 133 |
120 const auto mixer = AudioMixerImpl::Create(); | 134 const auto mixer = AudioMixerImpl::Create(); |
121 | 135 |
122 MockMixerAudioSource participants[kAudioSources]; | 136 MockMixerAudioSource participants[kAudioSources]; |
123 | 137 |
124 for (int i = 0; i < kAudioSources; ++i) { | 138 for (int i = 0; i < kAudioSources; ++i) { |
125 ResetFrame(participants[i].fake_frame()); | 139 ResetFrame(participants[i].fake_frame()); |
126 | 140 |
127 // We set the 80-th sample value since the first 80 samples may be | 141 // We set the 80-th sample value since the first 80 samples may be |
128 // modified by a ramped-in window. | 142 // modified by a ramped-in window. |
129 participants[i].fake_frame()->data_[80] = i; | 143 participants[i].fake_frame()->data_[80] = i; |
130 | 144 |
131 EXPECT_TRUE(mixer->AddSource(&participants[i])); | 145 EXPECT_TRUE(mixer->AddSource(&participants[i])); |
132 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1)); | 146 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1)); |
133 } | 147 } |
134 | 148 |
135 // Last participant gives audio frame with passive VAD, although it has the | 149 // Last participant gives audio frame with passive VAD, although it has the |
136 // largest energy. | 150 // largest energy. |
137 participants[kAudioSources - 1].fake_frame()->vad_activity_ = | 151 participants[kAudioSources - 1].fake_frame()->vad_activity_ = |
138 AudioFrame::kVadPassive; | 152 AudioFrame::kVadPassive; |
139 | 153 |
140 AudioFrame audio_frame; | 154 AudioFrame audio_frame; |
141 mixer->Mix(kDefaultSampleRateHz, | 155 mixer->Mix(1, // number of channels |
142 1, // number of channels | |
143 &audio_frame); | 156 &audio_frame); |
144 | 157 |
145 for (int i = 0; i < kAudioSources; ++i) { | 158 for (int i = 0; i < kAudioSources; ++i) { |
146 bool is_mixed = | 159 bool is_mixed = |
147 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]); | 160 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]); |
148 if (i == kAudioSources - 1 || | 161 if (i == kAudioSources - 1 || |
149 i < kAudioSources - 1 - | 162 i < kAudioSources - 1 - |
150 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) { | 163 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) { |
151 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i | 164 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i |
152 << " wrong."; | 165 << " wrong."; |
(...skipping 16 matching lines...) Expand all Loading... | |
169 for (int j = 0; j < n_samples; j++) { | 182 for (int j = 0; j < n_samples; j++) { |
170 participant.fake_frame()->data_[j] = j; | 183 participant.fake_frame()->data_[j] = j; |
171 } | 184 } |
172 | 185 |
173 EXPECT_TRUE(mixer->AddSource(&participant)); | 186 EXPECT_TRUE(mixer->AddSource(&participant)); |
174 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2)); | 187 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2)); |
175 | 188 |
176 AudioFrame audio_frame; | 189 AudioFrame audio_frame; |
177 // Two mix iteration to compare after the ramp-up step. | 190 // Two mix iteration to compare after the ramp-up step. |
178 for (int i = 0; i < 2; i++) { | 191 for (int i = 0; i < 2; i++) { |
179 mixer->Mix(kDefaultSampleRateHz, | 192 mixer->Mix(1, // number of channels |
180 1, // number of channels | |
181 &audio_frame); | 193 &audio_frame); |
182 } | 194 } |
183 | 195 |
184 EXPECT_EQ( | 196 EXPECT_EQ( |
185 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples)); | 197 0, memcmp(participant.fake_frame()->data_, audio_frame.data_, n_samples)); |
186 } | 198 } |
187 | 199 |
aleloi
2016/10/31 10:39:35
The rationale behind the change of ParticipantSamp
| |
188 TEST(AudioMixer, ParticipantSampleRate) { | 200 TEST(AudioMixer, SourceAtNativeRateShouldNeverResample) { |
201 const auto mixer = AudioMixerImpl::Create(); | |
202 | |
203 MockMixerAudioSource audio_source; | |
204 ResetFrame(audio_source.fake_frame()); | |
205 | |
206 mixer->AddSource(&audio_source); | |
207 | |
208 for (auto frequency : {8000, 16000, 32000, 48000}) { | |
209 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(frequency, _)) | |
210 .Times(Exactly(1)); | |
211 | |
212 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer, | |
213 &audio_source); | |
214 } | |
215 } | |
216 | |
217 TEST(AudioMixer, MixerShouldMixAtNativeSourceRate) { | |
218 const auto mixer = AudioMixerImpl::Create(); | |
219 | |
220 MockMixerAudioSource audio_source; | |
221 ResetFrame(audio_source.fake_frame()); | |
222 | |
223 mixer->AddSource(&audio_source); | |
224 | |
225 for (auto frequency : {8000, 16000, 32000, 48000}) { | |
226 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer, | |
227 &audio_source); | |
228 | |
229 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_); | |
230 } | |
231 } | |
232 | |
233 TEST(AudioMixer, MixerShouldAlwaysMixAtNativeRate) { | |
189 const auto mixer = AudioMixerImpl::Create(); | 234 const auto mixer = AudioMixerImpl::Create(); |
190 | 235 |
191 MockMixerAudioSource participant; | 236 MockMixerAudioSource participant; |
192 ResetFrame(participant.fake_frame()); | 237 ResetFrame(participant.fake_frame()); |
238 mixer->AddSource(&participant); | |
193 | 239 |
194 EXPECT_TRUE(mixer->AddSource(&participant)); | 240 const int needed_frequency = 44100; |
195 for (auto frequency : {8000, 16000, 32000, 48000}) { | 241 ON_CALL(participant, PreferredSampleRate()) |
196 EXPECT_CALL(participant, GetAudioFrameWithInfo(frequency, _)) | 242 .WillByDefault(Return(needed_frequency)); |
197 .Times(Exactly(1)); | 243 |
198 participant.fake_frame()->sample_rate_hz_ = frequency; | 244 // We expect mixing frequency to be native and >= needed_frequency. |
199 participant.fake_frame()->samples_per_channel_ = frequency / 100; | 245 const int expected_mix_frequency = 48000; |
200 mixer->Mix(frequency, 1, &frame_for_mixing); | 246 EXPECT_CALL(participant, GetAudioFrameWithInfo(expected_mix_frequency, _)) |
201 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_); | 247 .Times(Exactly(1)); |
202 } | 248 participant.fake_frame()->sample_rate_hz_ = expected_mix_frequency; |
249 participant.fake_frame()->samples_per_channel_ = expected_mix_frequency / 100; | |
250 | |
251 mixer->Mix(1, &frame_for_mixing); | |
252 | |
253 EXPECT_EQ(48000, frame_for_mixing.sample_rate_hz_); | |
203 } | 254 } |
204 | 255 |
205 TEST(AudioMixer, ParticipantNumberOfChannels) { | 256 TEST(AudioMixer, ParticipantNumberOfChannels) { |
206 const auto mixer = AudioMixerImpl::Create(); | 257 const auto mixer = AudioMixerImpl::Create(); |
207 | 258 |
208 MockMixerAudioSource participant; | 259 MockMixerAudioSource participant; |
209 ResetFrame(participant.fake_frame()); | 260 ResetFrame(participant.fake_frame()); |
210 | 261 |
211 EXPECT_TRUE(mixer->AddSource(&participant)); | 262 EXPECT_TRUE(mixer->AddSource(&participant)); |
212 for (size_t number_of_channels : {1, 2}) { | 263 for (size_t number_of_channels : {1, 2}) { |
213 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) | 264 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) |
214 .Times(Exactly(1)); | 265 .Times(Exactly(1)); |
215 mixer->Mix(kDefaultSampleRateHz, number_of_channels, &frame_for_mixing); | 266 mixer->Mix(number_of_channels, &frame_for_mixing); |
216 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_); | 267 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_); |
217 } | 268 } |
218 } | 269 } |
219 | 270 |
220 // Maximal amount of participants are mixed one iteration, then | 271 // Maximal amount of participants are mixed one iteration, then |
221 // another participant with higher energy is added. | 272 // another participant with higher energy is added. |
222 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) { | 273 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) { |
223 constexpr int kAudioSources = | 274 constexpr int kAudioSources = |
224 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; | 275 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; |
225 | 276 |
226 const auto mixer = AudioMixerImpl::Create(); | 277 const auto mixer = AudioMixerImpl::Create(); |
227 MockMixerAudioSource participants[kAudioSources]; | 278 MockMixerAudioSource participants[kAudioSources]; |
228 | 279 |
229 for (int i = 0; i < kAudioSources; i++) { | 280 for (int i = 0; i < kAudioSources; i++) { |
230 ResetFrame(participants[i].fake_frame()); | 281 ResetFrame(participants[i].fake_frame()); |
231 // Set the participant audio energy to increase with the index | 282 // Set the participant audio energy to increase with the index |
232 // |i|. | 283 // |i|. |
233 participants[i].fake_frame()->data_[0] = 100 * i; | 284 participants[i].fake_frame()->data_[0] = 100 * i; |
234 } | 285 } |
235 | 286 |
236 // Add all participants but the loudest for mixing. | 287 // Add all participants but the loudest for mixing. |
237 for (int i = 0; i < kAudioSources - 1; i++) { | 288 for (int i = 0; i < kAudioSources - 1; i++) { |
238 EXPECT_TRUE(mixer->AddSource(&participants[i])); | 289 EXPECT_TRUE(mixer->AddSource(&participants[i])); |
239 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) | 290 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) |
240 .Times(Exactly(1)); | 291 .Times(Exactly(1)); |
241 } | 292 } |
242 | 293 |
243 // First mixer iteration | 294 // First mixer iteration |
244 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 295 mixer->Mix(1, &frame_for_mixing); |
245 | 296 |
246 // All participants but the loudest should have been mixed. | 297 // All participants but the loudest should have been mixed. |
247 for (int i = 0; i < kAudioSources - 1; i++) { | 298 for (int i = 0; i < kAudioSources - 1; i++) { |
248 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) | 299 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) |
249 << "Mixed status of AudioSource #" << i << " wrong."; | 300 << "Mixed status of AudioSource #" << i << " wrong."; |
250 } | 301 } |
251 | 302 |
252 // Add new participant with higher energy. | 303 // Add new participant with higher energy. |
253 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1])); | 304 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1])); |
254 for (int i = 0; i < kAudioSources; i++) { | 305 for (int i = 0; i < kAudioSources; i++) { |
255 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) | 306 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) |
256 .Times(Exactly(1)); | 307 .Times(Exactly(1)); |
257 } | 308 } |
258 | 309 |
259 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 310 mixer->Mix(1, &frame_for_mixing); |
260 | 311 |
261 // The most quiet participant should not have been mixed. | 312 // The most quiet participant should not have been mixed. |
262 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0])) | 313 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0])) |
263 << "Mixed status of AudioSource #0 wrong."; | 314 << "Mixed status of AudioSource #0 wrong."; |
264 | 315 |
265 // The loudest participants should have been mixed. | 316 // The loudest participants should have been mixed. |
266 for (int i = 1; i < kAudioSources; i++) { | 317 for (int i = 1; i < kAudioSources; i++) { |
267 EXPECT_EQ(true, | 318 EXPECT_EQ(true, |
268 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) | 319 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i])) |
269 << "Mixed status of AudioSource #" << i << " wrong."; | 320 << "Mixed status of AudioSource #" << i << " wrong."; |
(...skipping 14 matching lines...) Expand all Loading... | |
284 | 335 |
285 participant_thread->Start(); | 336 participant_thread->Start(); |
286 EXPECT_TRUE(participant_thread->Invoke<int>( | 337 EXPECT_TRUE(participant_thread->Invoke<int>( |
287 RTC_FROM_HERE, | 338 RTC_FROM_HERE, |
288 rtc::Bind(&AudioMixer::AddSource, mixer.get(), &participant))); | 339 rtc::Bind(&AudioMixer::AddSource, mixer.get(), &participant))); |
289 | 340 |
290 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) | 341 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) |
291 .Times(Exactly(1)); | 342 .Times(Exactly(1)); |
292 | 343 |
293 // Do one mixer iteration | 344 // Do one mixer iteration |
294 mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing); | 345 mixer->Mix(1, &frame_for_mixing); |
295 } | 346 } |
296 | 347 |
297 TEST(AudioMixer, MutedShouldMixAfterUnmuted) { | 348 TEST(AudioMixer, MutedShouldMixAfterUnmuted) { |
298 constexpr int kAudioSources = | 349 constexpr int kAudioSources = |
299 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; | 350 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1; |
300 | 351 |
301 std::vector<AudioFrame> frames(kAudioSources); | 352 std::vector<AudioFrame> frames(kAudioSources); |
302 for (auto& frame : frames) { | 353 for (auto& frame : frames) { |
303 ResetFrame(&frame); | 354 ResetFrame(&frame); |
304 } | 355 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal); | 414 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal); |
364 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted; | 415 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted; |
365 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100, | 416 std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100, |
366 std::numeric_limits<int16_t>::max()); | 417 std::numeric_limits<int16_t>::max()); |
367 std::vector<bool> expected_status(kAudioSources, true); | 418 std::vector<bool> expected_status(kAudioSources, true); |
368 expected_status[0] = false; | 419 expected_status[0] = false; |
369 | 420 |
370 MixAndCompare(frames, frame_info, expected_status); | 421 MixAndCompare(frames, frame_info, expected_status); |
371 } | 422 } |
372 } // namespace webrtc | 423 } // namespace webrtc |
OLD | NEW |