blob: 4461e6e038dc15c42134a858652b875b4e064ec8 [file] [log] [blame]
aleloi09f45102016-07-28 03:52:15 -07001/*
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
aleloi311525e2016-09-07 06:13:12 -070011#include <string.h>
12
aleloi116ec6d2016-10-12 06:07:07 -070013#include <limits>
aleloi09f45102016-07-28 03:52:15 -070014#include <memory>
aleloi24899e52017-02-21 05:06:29 -080015#include <sstream>
16#include <string>
aleloif3882572016-07-29 02:12:41 -070017#include <utility>
aleloi09f45102016-07-28 03:52:15 -070018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/audio/audio_mixer.h"
20#include "modules/audio_mixer/audio_mixer_impl.h"
21#include "modules/audio_mixer/default_output_rate_calculator.h"
22#include "rtc_base/bind.h"
23#include "rtc_base/checks.h"
24#include "rtc_base/event.h"
25#include "rtc_base/task_queue.h"
26#include "test/gmock.h"
aleloi09f45102016-07-28 03:52:15 -070027
28using testing::_;
aleloia0db81f2016-07-28 06:36:22 -070029using testing::Exactly;
aleloi09f45102016-07-28 03:52:15 -070030using testing::Invoke;
31using testing::Return;
32
aleloi09f45102016-07-28 03:52:15 -070033namespace webrtc {
aleloif3882572016-07-29 02:12:41 -070034
aleloi30be5d72016-08-24 01:38:44 -070035namespace {
aleloif3882572016-07-29 02:12:41 -070036
aleloi30be5d72016-08-24 01:38:44 -070037constexpr int kDefaultSampleRateHz = 48000;
aleloif3882572016-07-29 02:12:41 -070038
aleloi30be5d72016-08-24 01:38:44 -070039// Utility function that resets the frame member variables with
40// sensible defaults.
41void ResetFrame(AudioFrame* frame) {
aleloi30be5d72016-08-24 01:38:44 -070042 frame->sample_rate_hz_ = kDefaultSampleRateHz;
43 frame->num_channels_ = 1;
44
45 // Frame duration 10ms.
46 frame->samples_per_channel_ = kDefaultSampleRateHz / 100;
47 frame->vad_activity_ = AudioFrame::kVadActive;
48 frame->speech_type_ = AudioFrame::kNormalSpeech;
49}
50
aleloi24899e52017-02-21 05:06:29 -080051std::string ProduceDebugText(int sample_rate_hz,
52 int number_of_channels,
53 int number_of_sources) {
54 std::ostringstream ss;
55 ss << "Sample rate: " << sample_rate_hz << " ";
56 ss << "Number of channels: " << number_of_channels << " ";
57 ss << "Number of sources: " << number_of_sources;
58 return ss.str();
59}
60
aleloi30be5d72016-08-24 01:38:44 -070061AudioFrame frame_for_mixing;
62
63} // namespace
aleloif3882572016-07-29 02:12:41 -070064
aleloie8914152016-10-11 06:18:31 -070065class MockMixerAudioSource : public AudioMixer::Source {
aleloi09f45102016-07-28 03:52:15 -070066 public:
aleloif3882572016-07-29 02:12:41 -070067 MockMixerAudioSource()
aleloie8914152016-10-11 06:18:31 -070068 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) {
aleloi6c278492016-10-20 14:24:39 -070069 ON_CALL(*this, GetAudioFrameWithInfo(_, _))
aleloia0db81f2016-07-28 06:36:22 -070070 .WillByDefault(
aleloie8914152016-10-11 06:18:31 -070071 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo));
aleloi95611832016-11-08 06:39:50 -080072 ON_CALL(*this, PreferredSampleRate())
73 .WillByDefault(Return(kDefaultSampleRateHz));
aleloi09f45102016-07-28 03:52:15 -070074 }
aleloif3882572016-07-29 02:12:41 -070075
aleloi6c278492016-10-20 14:24:39 -070076 MOCK_METHOD2(GetAudioFrameWithInfo,
77 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame));
aleloia0db81f2016-07-28 06:36:22 -070078
aleloi051f6782016-10-31 03:26:40 -070079 MOCK_CONST_METHOD0(PreferredSampleRate, int());
80 MOCK_CONST_METHOD0(Ssrc, int());
aleloi116ec6d2016-10-12 06:07:07 -070081
aleloi09f45102016-07-28 03:52:15 -070082 AudioFrame* fake_frame() { return &fake_frame_; }
aleloif3882572016-07-29 02:12:41 -070083 AudioFrameInfo fake_info() { return fake_audio_frame_info_; }
84 void set_fake_info(const AudioFrameInfo audio_frame_info) {
85 fake_audio_frame_info_ = audio_frame_info;
86 }
aleloi09f45102016-07-28 03:52:15 -070087
88 private:
aleloi6c278492016-10-20 14:24:39 -070089 AudioFrameInfo FakeAudioFrameWithInfo(int sample_rate_hz,
90 AudioFrame* audio_frame) {
91 audio_frame->CopyFrom(fake_frame_);
aleloi95611832016-11-08 06:39:50 -080092 audio_frame->sample_rate_hz_ = sample_rate_hz;
aleloi24899e52017-02-21 05:06:29 -080093 audio_frame->samples_per_channel_ =
94 rtc::CheckedDivExact(sample_rate_hz, 100);
aleloi6c278492016-10-20 14:24:39 -070095 return fake_info();
aleloi09f45102016-07-28 03:52:15 -070096 }
aleloi95611832016-11-08 06:39:50 -080097
98 AudioFrame fake_frame_;
99 AudioFrameInfo fake_audio_frame_info_;
aleloi09f45102016-07-28 03:52:15 -0700100};
101
aleloi623427c2016-12-08 02:37:58 -0800102class CustomRateCalculator : public OutputRateCalculator {
103 public:
104 explicit CustomRateCalculator(int rate) : rate_(rate) {}
aleloi24899e52017-02-21 05:06:29 -0800105 int CalculateOutputRate(const std::vector<int>& preferred_rates) override {
aleloi623427c2016-12-08 02:37:58 -0800106 return rate_;
107 }
108
109 private:
110 const int rate_;
111};
112
aleloi30be5d72016-08-24 01:38:44 -0700113// Creates participants from |frames| and |frame_info| and adds them
114// to the mixer. Compares mixed status with |expected_status|
115void MixAndCompare(
116 const std::vector<AudioFrame>& frames,
aleloie8914152016-10-11 06:18:31 -0700117 const std::vector<AudioMixer::Source::AudioFrameInfo>& frame_info,
aleloi30be5d72016-08-24 01:38:44 -0700118 const std::vector<bool>& expected_status) {
aleloi24899e52017-02-21 05:06:29 -0800119 const size_t num_audio_sources = frames.size();
aleloi30be5d72016-08-24 01:38:44 -0700120 RTC_DCHECK(frames.size() == frame_info.size());
121 RTC_DCHECK(frame_info.size() == expected_status.size());
aleloif3882572016-07-29 02:12:41 -0700122
aleloi116ec6d2016-10-12 06:07:07 -0700123 const auto mixer = AudioMixerImpl::Create();
aleloi30be5d72016-08-24 01:38:44 -0700124 std::vector<MockMixerAudioSource> participants(num_audio_sources);
aleloif3882572016-07-29 02:12:41 -0700125
aleloi24899e52017-02-21 05:06:29 -0800126 for (size_t i = 0; i < num_audio_sources; ++i) {
aleloi30be5d72016-08-24 01:38:44 -0700127 participants[i].fake_frame()->CopyFrom(frames[i]);
128 participants[i].set_fake_info(frame_info[i]);
aleloif3882572016-07-29 02:12:41 -0700129 }
130
aleloi24899e52017-02-21 05:06:29 -0800131 for (size_t i = 0; i < num_audio_sources; ++i) {
aleloi116ec6d2016-10-12 06:07:07 -0700132 EXPECT_TRUE(mixer->AddSource(&participants[i]));
aleloi6c278492016-10-20 14:24:39 -0700133 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
aleloi30be5d72016-08-24 01:38:44 -0700134 .Times(Exactly(1));
aleloif3882572016-07-29 02:12:41 -0700135 }
136
aleloi95611832016-11-08 06:39:50 -0800137 mixer->Mix(1, &frame_for_mixing);
aleloi30be5d72016-08-24 01:38:44 -0700138
aleloi24899e52017-02-21 05:06:29 -0800139 for (size_t i = 0; i < num_audio_sources; ++i) {
aleloi36542512016-10-07 05:28:32 -0700140 EXPECT_EQ(expected_status[i],
141 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
aleloi30be5d72016-08-24 01:38:44 -0700142 << "Mixed status of AudioSource #" << i << " wrong.";
aleloif3882572016-07-29 02:12:41 -0700143 }
aleloi30be5d72016-08-24 01:38:44 -0700144}
aleloi09f45102016-07-28 03:52:15 -0700145
aleloi95611832016-11-08 06:39:50 -0800146void MixMonoAtGivenNativeRate(int native_sample_rate,
147 AudioFrame* mix_frame,
148 rtc::scoped_refptr<AudioMixer> mixer,
149 MockMixerAudioSource* audio_source) {
150 ON_CALL(*audio_source, PreferredSampleRate())
151 .WillByDefault(Return(native_sample_rate));
152 audio_source->fake_frame()->sample_rate_hz_ = native_sample_rate;
153 audio_source->fake_frame()->samples_per_channel_ = native_sample_rate / 100;
154
155 mixer->Mix(1, mix_frame);
156}
157
aleloi09f45102016-07-28 03:52:15 -0700158TEST(AudioMixer, LargestEnergyVadActiveMixed) {
aleloi616df1e2016-08-24 01:17:12 -0700159 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700160 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3;
aleloi09f45102016-07-28 03:52:15 -0700161
aleloi116ec6d2016-10-12 06:07:07 -0700162 const auto mixer = AudioMixerImpl::Create();
aleloi09f45102016-07-28 03:52:15 -0700163
164 MockMixerAudioSource participants[kAudioSources];
165
166 for (int i = 0; i < kAudioSources; ++i) {
aleloi30be5d72016-08-24 01:38:44 -0700167 ResetFrame(participants[i].fake_frame());
aleloi09f45102016-07-28 03:52:15 -0700168
169 // We set the 80-th sample value since the first 80 samples may be
170 // modified by a ramped-in window.
yujo36b1a5f2017-06-12 12:45:32 -0700171 participants[i].fake_frame()->mutable_data()[80] = i;
aleloi09f45102016-07-28 03:52:15 -0700172
aleloi116ec6d2016-10-12 06:07:07 -0700173 EXPECT_TRUE(mixer->AddSource(&participants[i]));
aleloi6c278492016-10-20 14:24:39 -0700174 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1));
aleloi09f45102016-07-28 03:52:15 -0700175 }
176
177 // Last participant gives audio frame with passive VAD, although it has the
178 // largest energy.
179 participants[kAudioSources - 1].fake_frame()->vad_activity_ =
180 AudioFrame::kVadPassive;
181
182 AudioFrame audio_frame;
aleloi95611832016-11-08 06:39:50 -0800183 mixer->Mix(1, // number of channels
aleloi44968092016-08-08 10:18:58 -0700184 &audio_frame);
aleloi09f45102016-07-28 03:52:15 -0700185
186 for (int i = 0; i < kAudioSources; ++i) {
aleloi36542512016-10-07 05:28:32 -0700187 bool is_mixed =
188 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]);
aleloi09f45102016-07-28 03:52:15 -0700189 if (i == kAudioSources - 1 ||
aleloi116ec6d2016-10-12 06:07:07 -0700190 i < kAudioSources - 1 -
191 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) {
aleloi09f45102016-07-28 03:52:15 -0700192 EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i
193 << " wrong.";
194 } else {
195 EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i
196 << " wrong.";
197 }
198 }
199}
200
aleloi311525e2016-09-07 06:13:12 -0700201TEST(AudioMixer, FrameNotModifiedForSingleParticipant) {
aleloi116ec6d2016-10-12 06:07:07 -0700202 const auto mixer = AudioMixerImpl::Create();
aleloi311525e2016-09-07 06:13:12 -0700203
204 MockMixerAudioSource participant;
205
206 ResetFrame(participant.fake_frame());
aleloi24899e52017-02-21 05:06:29 -0800207 const size_t n_samples = participant.fake_frame()->samples_per_channel_;
aleloi311525e2016-09-07 06:13:12 -0700208
209 // Modify the frame so that it's not zero.
yujo36b1a5f2017-06-12 12:45:32 -0700210 int16_t* fake_frame_data = participant.fake_frame()->mutable_data();
aleloi24899e52017-02-21 05:06:29 -0800211 for (size_t j = 0; j < n_samples; ++j) {
yujo36b1a5f2017-06-12 12:45:32 -0700212 fake_frame_data[j] = static_cast<int16_t>(j);
aleloi311525e2016-09-07 06:13:12 -0700213 }
214
aleloi116ec6d2016-10-12 06:07:07 -0700215 EXPECT_TRUE(mixer->AddSource(&participant));
aleloi6c278492016-10-20 14:24:39 -0700216 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2));
aleloi311525e2016-09-07 06:13:12 -0700217
218 AudioFrame audio_frame;
219 // Two mix iteration to compare after the ramp-up step.
aleloi24899e52017-02-21 05:06:29 -0800220 for (int i = 0; i < 2; ++i) {
aleloi95611832016-11-08 06:39:50 -0800221 mixer->Mix(1, // number of channels
aleloi311525e2016-09-07 06:13:12 -0700222 &audio_frame);
223 }
224
225 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700226 0,
227 memcmp(participant.fake_frame()->data(), audio_frame.data(), n_samples));
aleloi311525e2016-09-07 06:13:12 -0700228}
229
aleloi95611832016-11-08 06:39:50 -0800230TEST(AudioMixer, SourceAtNativeRateShouldNeverResample) {
231 const auto mixer = AudioMixerImpl::Create();
232
233 MockMixerAudioSource audio_source;
234 ResetFrame(audio_source.fake_frame());
235
236 mixer->AddSource(&audio_source);
237
238 for (auto frequency : {8000, 16000, 32000, 48000}) {
239 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(frequency, _))
240 .Times(Exactly(1));
241
242 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
243 &audio_source);
244 }
245}
246
247TEST(AudioMixer, MixerShouldMixAtNativeSourceRate) {
248 const auto mixer = AudioMixerImpl::Create();
249
250 MockMixerAudioSource audio_source;
251 ResetFrame(audio_source.fake_frame());
252
253 mixer->AddSource(&audio_source);
254
255 for (auto frequency : {8000, 16000, 32000, 48000}) {
256 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
257 &audio_source);
258
259 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_);
260 }
261}
262
263TEST(AudioMixer, MixerShouldAlwaysMixAtNativeRate) {
aleloi116ec6d2016-10-12 06:07:07 -0700264 const auto mixer = AudioMixerImpl::Create();
aleloi44968092016-08-08 10:18:58 -0700265
266 MockMixerAudioSource participant;
aleloi30be5d72016-08-24 01:38:44 -0700267 ResetFrame(participant.fake_frame());
aleloi95611832016-11-08 06:39:50 -0800268 mixer->AddSource(&participant);
aleloi44968092016-08-08 10:18:58 -0700269
aleloi95611832016-11-08 06:39:50 -0800270 const int needed_frequency = 44100;
271 ON_CALL(participant, PreferredSampleRate())
272 .WillByDefault(Return(needed_frequency));
273
274 // We expect mixing frequency to be native and >= needed_frequency.
275 const int expected_mix_frequency = 48000;
276 EXPECT_CALL(participant, GetAudioFrameWithInfo(expected_mix_frequency, _))
277 .Times(Exactly(1));
278 participant.fake_frame()->sample_rate_hz_ = expected_mix_frequency;
279 participant.fake_frame()->samples_per_channel_ = expected_mix_frequency / 100;
280
281 mixer->Mix(1, &frame_for_mixing);
282
283 EXPECT_EQ(48000, frame_for_mixing.sample_rate_hz_);
284}
285
286// Check that the mixing rate is always >= participants preferred rate.
287TEST(AudioMixer, ShouldNotCauseQualityLossForMultipleSources) {
288 const auto mixer = AudioMixerImpl::Create();
289
290 std::vector<MockMixerAudioSource> audio_sources(2);
291 const std::vector<int> source_sample_rates = {8000, 16000};
292 for (int i = 0; i < 2; ++i) {
293 auto& source = audio_sources[i];
294 ResetFrame(source.fake_frame());
295 mixer->AddSource(&source);
296 const auto sample_rate = source_sample_rates[i];
297 EXPECT_CALL(source, PreferredSampleRate()).WillOnce(Return(sample_rate));
298
299 EXPECT_CALL(source, GetAudioFrameWithInfo(testing::Ge(sample_rate), _));
aleloi44968092016-08-08 10:18:58 -0700300 }
aleloi95611832016-11-08 06:39:50 -0800301 mixer->Mix(1, &frame_for_mixing);
aleloi44968092016-08-08 10:18:58 -0700302}
303
304TEST(AudioMixer, ParticipantNumberOfChannels) {
aleloi116ec6d2016-10-12 06:07:07 -0700305 const auto mixer = AudioMixerImpl::Create();
aleloi44968092016-08-08 10:18:58 -0700306
307 MockMixerAudioSource participant;
aleloi30be5d72016-08-24 01:38:44 -0700308 ResetFrame(participant.fake_frame());
aleloi44968092016-08-08 10:18:58 -0700309
aleloi116ec6d2016-10-12 06:07:07 -0700310 EXPECT_TRUE(mixer->AddSource(&participant));
aleloi44968092016-08-08 10:18:58 -0700311 for (size_t number_of_channels : {1, 2}) {
aleloi6c278492016-10-20 14:24:39 -0700312 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
aleloi30be5d72016-08-24 01:38:44 -0700313 .Times(Exactly(1));
aleloi95611832016-11-08 06:39:50 -0800314 mixer->Mix(number_of_channels, &frame_for_mixing);
aleloi44968092016-08-08 10:18:58 -0700315 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
316 }
317}
318
aleloi30be5d72016-08-24 01:38:44 -0700319// Maximal amount of participants are mixed one iteration, then
320// another participant with higher energy is added.
321TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
322 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700323 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
aleloi09f45102016-07-28 03:52:15 -0700324
aleloi116ec6d2016-10-12 06:07:07 -0700325 const auto mixer = AudioMixerImpl::Create();
aleloi30be5d72016-08-24 01:38:44 -0700326 MockMixerAudioSource participants[kAudioSources];
aleloi09f45102016-07-28 03:52:15 -0700327
aleloi24899e52017-02-21 05:06:29 -0800328 for (int i = 0; i < kAudioSources; ++i) {
aleloi30be5d72016-08-24 01:38:44 -0700329 ResetFrame(participants[i].fake_frame());
330 // Set the participant audio energy to increase with the index
331 // |i|.
yujo36b1a5f2017-06-12 12:45:32 -0700332 participants[i].fake_frame()->mutable_data()[0] = 100 * i;
aleloi30be5d72016-08-24 01:38:44 -0700333 }
aleloi09f45102016-07-28 03:52:15 -0700334
aleloi30be5d72016-08-24 01:38:44 -0700335 // Add all participants but the loudest for mixing.
aleloi24899e52017-02-21 05:06:29 -0800336 for (int i = 0; i < kAudioSources - 1; ++i) {
aleloi116ec6d2016-10-12 06:07:07 -0700337 EXPECT_TRUE(mixer->AddSource(&participants[i]));
aleloi6c278492016-10-20 14:24:39 -0700338 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
aleloi30be5d72016-08-24 01:38:44 -0700339 .Times(Exactly(1));
340 }
aleloi09f45102016-07-28 03:52:15 -0700341
aleloi30be5d72016-08-24 01:38:44 -0700342 // First mixer iteration
aleloi95611832016-11-08 06:39:50 -0800343 mixer->Mix(1, &frame_for_mixing);
aleloi09f45102016-07-28 03:52:15 -0700344
aleloi30be5d72016-08-24 01:38:44 -0700345 // All participants but the loudest should have been mixed.
aleloi24899e52017-02-21 05:06:29 -0800346 for (int i = 0; i < kAudioSources - 1; ++i) {
aleloi36542512016-10-07 05:28:32 -0700347 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
348 << "Mixed status of AudioSource #" << i << " wrong.";
aleloi30be5d72016-08-24 01:38:44 -0700349 }
aleloi09f45102016-07-28 03:52:15 -0700350
aleloi30be5d72016-08-24 01:38:44 -0700351 // Add new participant with higher energy.
aleloi116ec6d2016-10-12 06:07:07 -0700352 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1]));
aleloi24899e52017-02-21 05:06:29 -0800353 for (int i = 0; i < kAudioSources; ++i) {
aleloi6c278492016-10-20 14:24:39 -0700354 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
aleloi30be5d72016-08-24 01:38:44 -0700355 .Times(Exactly(1));
356 }
aleloi09f45102016-07-28 03:52:15 -0700357
aleloi95611832016-11-08 06:39:50 -0800358 mixer->Mix(1, &frame_for_mixing);
aleloif3882572016-07-29 02:12:41 -0700359
aleloi30be5d72016-08-24 01:38:44 -0700360 // The most quiet participant should not have been mixed.
aleloi36542512016-10-07 05:28:32 -0700361 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0]))
aleloi30be5d72016-08-24 01:38:44 -0700362 << "Mixed status of AudioSource #0 wrong.";
aleloif3882572016-07-29 02:12:41 -0700363
aleloi30be5d72016-08-24 01:38:44 -0700364 // The loudest participants should have been mixed.
aleloi24899e52017-02-21 05:06:29 -0800365 for (int i = 1; i < kAudioSources; ++i) {
aleloi36542512016-10-07 05:28:32 -0700366 EXPECT_EQ(true,
367 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
aleloi30be5d72016-08-24 01:38:44 -0700368 << "Mixed status of AudioSource #" << i << " wrong.";
aleloif3882572016-07-29 02:12:41 -0700369 }
370}
371
aleloi311525e2016-09-07 06:13:12 -0700372// This test checks that the initialization and participant addition
373// can be done on a different thread.
374TEST(AudioMixer, ConstructFromOtherThread) {
tommic45d6d92017-07-11 06:17:10 -0700375 rtc::TaskQueue init_queue("init");
376 rtc::scoped_refptr<AudioMixer> mixer;
377 rtc::Event event(false, false);
378 init_queue.PostTask([&mixer, &event]() {
379 mixer = AudioMixerImpl::Create();
380 event.Set();
381 });
382 event.Wait(rtc::Event::kForever);
383
aleloi311525e2016-09-07 06:13:12 -0700384 MockMixerAudioSource participant;
tommic45d6d92017-07-11 06:17:10 -0700385 EXPECT_CALL(participant, PreferredSampleRate())
386 .WillRepeatedly(Return(kDefaultSampleRateHz));
aleloi311525e2016-09-07 06:13:12 -0700387
388 ResetFrame(participant.fake_frame());
389
tommic45d6d92017-07-11 06:17:10 -0700390 rtc::TaskQueue participant_queue("participant");
391 participant_queue.PostTask([&mixer, &event, &participant]() {
392 mixer->AddSource(&participant);
393 event.Set();
394 });
395 event.Wait(rtc::Event::kForever);
aleloi311525e2016-09-07 06:13:12 -0700396
aleloi6c278492016-10-20 14:24:39 -0700397 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
aleloi311525e2016-09-07 06:13:12 -0700398 .Times(Exactly(1));
399
400 // Do one mixer iteration
aleloi95611832016-11-08 06:39:50 -0800401 mixer->Mix(1, &frame_for_mixing);
aleloi311525e2016-09-07 06:13:12 -0700402}
403
aleloi30be5d72016-08-24 01:38:44 -0700404TEST(AudioMixer, MutedShouldMixAfterUnmuted) {
405 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700406 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
aleloif3882572016-07-29 02:12:41 -0700407
aleloi30be5d72016-08-24 01:38:44 -0700408 std::vector<AudioFrame> frames(kAudioSources);
409 for (auto& frame : frames) {
410 ResetFrame(&frame);
aleloif3882572016-07-29 02:12:41 -0700411 }
aleloi30be5d72016-08-24 01:38:44 -0700412
aleloie8914152016-10-11 06:18:31 -0700413 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
414 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
415 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted;
aleloi30be5d72016-08-24 01:38:44 -0700416 std::vector<bool> expected_status(kAudioSources, true);
417 expected_status[0] = false;
418
419 MixAndCompare(frames, frame_info, expected_status);
aleloif3882572016-07-29 02:12:41 -0700420}
421
aleloi30be5d72016-08-24 01:38:44 -0700422TEST(AudioMixer, PassiveShouldMixAfterNormal) {
423 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700424 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
aleloif3882572016-07-29 02:12:41 -0700425
aleloi30be5d72016-08-24 01:38:44 -0700426 std::vector<AudioFrame> frames(kAudioSources);
427 for (auto& frame : frames) {
428 ResetFrame(&frame);
aleloif3882572016-07-29 02:12:41 -0700429 }
430
aleloie8914152016-10-11 06:18:31 -0700431 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
432 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
aleloi30be5d72016-08-24 01:38:44 -0700433 frames[0].vad_activity_ = AudioFrame::kVadPassive;
434 std::vector<bool> expected_status(kAudioSources, true);
435 expected_status[0] = false;
436
437 MixAndCompare(frames, frame_info, expected_status);
aleloif3882572016-07-29 02:12:41 -0700438}
439
aleloi30be5d72016-08-24 01:38:44 -0700440TEST(AudioMixer, ActiveShouldMixBeforeLoud) {
441 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700442 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
aleloi30be5d72016-08-24 01:38:44 -0700443
444 std::vector<AudioFrame> frames(kAudioSources);
445 for (auto& frame : frames) {
446 ResetFrame(&frame);
447 }
448
aleloie8914152016-10-11 06:18:31 -0700449 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
450 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
aleloi30be5d72016-08-24 01:38:44 -0700451 frames[0].vad_activity_ = AudioFrame::kVadPassive;
yujo36b1a5f2017-06-12 12:45:32 -0700452 int16_t* frame_data = frames[0].mutable_data();
453 std::fill(frame_data, frame_data + kDefaultSampleRateHz / 100,
aleloi30be5d72016-08-24 01:38:44 -0700454 std::numeric_limits<int16_t>::max());
455 std::vector<bool> expected_status(kAudioSources, true);
456 expected_status[0] = false;
457
458 MixAndCompare(frames, frame_info, expected_status);
459}
460
461TEST(AudioMixer, UnmutedShouldMixBeforeLoud) {
462 constexpr int kAudioSources =
aleloi116ec6d2016-10-12 06:07:07 -0700463 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
aleloi30be5d72016-08-24 01:38:44 -0700464
465 std::vector<AudioFrame> frames(kAudioSources);
466 for (auto& frame : frames) {
467 ResetFrame(&frame);
468 }
469
aleloie8914152016-10-11 06:18:31 -0700470 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
471 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
472 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted;
yujo36b1a5f2017-06-12 12:45:32 -0700473 int16_t* frame_data = frames[0].mutable_data();
474 std::fill(frame_data, frame_data + kDefaultSampleRateHz / 100,
aleloi30be5d72016-08-24 01:38:44 -0700475 std::numeric_limits<int16_t>::max());
476 std::vector<bool> expected_status(kAudioSources, true);
477 expected_status[0] = false;
478
479 MixAndCompare(frames, frame_info, expected_status);
480}
aleloi623427c2016-12-08 02:37:58 -0800481
482TEST(AudioMixer, MixingRateShouldBeDecidedByRateCalculator) {
483 constexpr int kOutputRate = 22000;
aleloi087613c2017-02-21 08:27:08 -0800484 const auto mixer =
485 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
486 new CustomRateCalculator(kOutputRate)),
487 true);
aleloi623427c2016-12-08 02:37:58 -0800488 MockMixerAudioSource audio_source;
489 mixer->AddSource(&audio_source);
490 ResetFrame(audio_source.fake_frame());
491
492 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(kOutputRate, _))
493 .Times(Exactly(1));
494
495 mixer->Mix(1, &frame_for_mixing);
496}
497
498TEST(AudioMixer, ZeroSourceRateShouldBeDecidedByRateCalculator) {
499 constexpr int kOutputRate = 8000;
aleloi087613c2017-02-21 08:27:08 -0800500 const auto mixer =
501 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
502 new CustomRateCalculator(kOutputRate)),
503 true);
aleloi623427c2016-12-08 02:37:58 -0800504
505 mixer->Mix(1, &frame_for_mixing);
506
507 EXPECT_EQ(kOutputRate, frame_for_mixing.sample_rate_hz_);
508}
aleloi24899e52017-02-21 05:06:29 -0800509
510TEST(AudioMixer, NoLimiterBasicApiCalls) {
aleloi087613c2017-02-21 08:27:08 -0800511 const auto mixer = AudioMixerImpl::Create(
aleloi24899e52017-02-21 05:06:29 -0800512 std::unique_ptr<OutputRateCalculator>(new DefaultOutputRateCalculator()),
513 false);
514 mixer->Mix(1, &frame_for_mixing);
515}
516
517TEST(AudioMixer, AnyRateIsPossibleWithNoLimiter) {
518 // No APM limiter means no AudioProcessing::NativeRate restriction
519 // on mixing rate. The rate has to be divisible by 100 since we use
520 // 10 ms frames, though.
521 for (const auto rate : {8000, 20000, 24000, 32000, 44100}) {
522 for (const size_t number_of_channels : {1, 2}) {
523 for (const auto number_of_sources : {0, 1, 2, 3, 4}) {
524 SCOPED_TRACE(
525 ProduceDebugText(rate, number_of_sources, number_of_sources));
526 const auto mixer =
aleloi087613c2017-02-21 08:27:08 -0800527 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
528 new CustomRateCalculator(rate)),
529 false);
aleloi24899e52017-02-21 05:06:29 -0800530
531 std::vector<MockMixerAudioSource> sources(number_of_sources);
532 for (auto& source : sources) {
533 mixer->AddSource(&source);
534 }
535
536 mixer->Mix(number_of_channels, &frame_for_mixing);
537 EXPECT_EQ(rate, frame_for_mixing.sample_rate_hz_);
538 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
539 }
540 }
541 }
542}
aleloi09f45102016-07-28 03:52:15 -0700543} // namespace webrtc