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 "modules/audio_mixer/audio_mixer_impl.h"
12
13 #include <string.h>
14
15 #include <limits>
16 #include <memory>
17 #include <string>
18 #include <utility>
19
20 #include "api/audio/audio_mixer.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/strings/string_builder.h"
25 #include "rtc_base/task_queue_for_test.h"
26 #include "test/gmock.h"
27 #include "test/gtest.h"
28
29 using ::testing::_;
30 using ::testing::Exactly;
31 using ::testing::Invoke;
32 using ::testing::Return;
33
34 namespace webrtc {
35
36 namespace {
37
38 constexpr int kDefaultSampleRateHz = 48000;
39
40 // Utility function that resets the frame member variables with
41 // sensible defaults.
ResetFrame(AudioFrame * frame)42 void ResetFrame(AudioFrame* frame) {
43 frame->sample_rate_hz_ = kDefaultSampleRateHz;
44 frame->num_channels_ = 1;
45
46 // Frame duration 10ms.
47 frame->samples_per_channel_ = kDefaultSampleRateHz / 100;
48 frame->vad_activity_ = AudioFrame::kVadActive;
49 frame->speech_type_ = AudioFrame::kNormalSpeech;
50 }
51
ProduceDebugText(int sample_rate_hz,int number_of_channels,int number_of_sources)52 std::string ProduceDebugText(int sample_rate_hz,
53 int number_of_channels,
54 int number_of_sources) {
55 rtc::StringBuilder ss;
56 ss << "Sample rate: " << sample_rate_hz << " ";
57 ss << "Number of channels: " << number_of_channels << " ";
58 ss << "Number of sources: " << number_of_sources;
59 return ss.Release();
60 }
61
62 AudioFrame frame_for_mixing;
63
64 } // namespace
65
66 class MockMixerAudioSource : public ::testing::NiceMock<AudioMixer::Source> {
67 public:
MockMixerAudioSource()68 MockMixerAudioSource()
69 : fake_audio_frame_info_(AudioMixer::Source::AudioFrameInfo::kNormal) {
70 ON_CALL(*this, GetAudioFrameWithInfo(_, _))
71 .WillByDefault(
72 Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithInfo));
73 ON_CALL(*this, PreferredSampleRate())
74 .WillByDefault(Return(kDefaultSampleRateHz));
75 }
76
77 MOCK_METHOD(AudioFrameInfo,
78 GetAudioFrameWithInfo,
79 (int sample_rate_hz, AudioFrame* audio_frame),
80 (override));
81
82 MOCK_METHOD(int, PreferredSampleRate, (), (const, override));
83 MOCK_METHOD(int, Ssrc, (), (const, override));
84
fake_frame()85 AudioFrame* fake_frame() { return &fake_frame_; }
fake_info()86 AudioFrameInfo fake_info() { return fake_audio_frame_info_; }
set_fake_info(const AudioFrameInfo audio_frame_info)87 void set_fake_info(const AudioFrameInfo audio_frame_info) {
88 fake_audio_frame_info_ = audio_frame_info;
89 }
90
91 private:
FakeAudioFrameWithInfo(int sample_rate_hz,AudioFrame * audio_frame)92 AudioFrameInfo FakeAudioFrameWithInfo(int sample_rate_hz,
93 AudioFrame* audio_frame) {
94 audio_frame->CopyFrom(fake_frame_);
95 audio_frame->sample_rate_hz_ = sample_rate_hz;
96 audio_frame->samples_per_channel_ =
97 rtc::CheckedDivExact(sample_rate_hz, 100);
98 return fake_info();
99 }
100
101 AudioFrame fake_frame_;
102 AudioFrameInfo fake_audio_frame_info_;
103 };
104
105 class CustomRateCalculator : public OutputRateCalculator {
106 public:
CustomRateCalculator(int rate)107 explicit CustomRateCalculator(int rate) : rate_(rate) {}
CalculateOutputRateFromRange(rtc::ArrayView<const int> preferred_rates)108 int CalculateOutputRateFromRange(
109 rtc::ArrayView<const int> preferred_rates) override {
110 return rate_;
111 }
112
113 private:
114 const int rate_;
115 };
116
117 // Creates participants from |frames| and |frame_info| and adds them
118 // to the mixer. Compares mixed status with |expected_status|
MixAndCompare(const std::vector<AudioFrame> & frames,const std::vector<AudioMixer::Source::AudioFrameInfo> & frame_info,const std::vector<bool> & expected_status)119 void MixAndCompare(
120 const std::vector<AudioFrame>& frames,
121 const std::vector<AudioMixer::Source::AudioFrameInfo>& frame_info,
122 const std::vector<bool>& expected_status) {
123 const size_t num_audio_sources = frames.size();
124 RTC_DCHECK(frames.size() == frame_info.size());
125 RTC_DCHECK(frame_info.size() == expected_status.size());
126
127 const auto mixer = AudioMixerImpl::Create();
128 std::vector<MockMixerAudioSource> participants(num_audio_sources);
129
130 for (size_t i = 0; i < num_audio_sources; ++i) {
131 participants[i].fake_frame()->CopyFrom(frames[i]);
132 participants[i].set_fake_info(frame_info[i]);
133 }
134
135 for (size_t i = 0; i < num_audio_sources; ++i) {
136 EXPECT_TRUE(mixer->AddSource(&participants[i]));
137 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
138 .Times(Exactly(1));
139 }
140
141 mixer->Mix(1, &frame_for_mixing);
142
143 for (size_t i = 0; i < num_audio_sources; ++i) {
144 EXPECT_EQ(expected_status[i],
145 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
146 << "Mixed status of AudioSource #" << i << " wrong.";
147 }
148 }
149
MixMonoAtGivenNativeRate(int native_sample_rate,AudioFrame * mix_frame,rtc::scoped_refptr<AudioMixer> mixer,MockMixerAudioSource * audio_source)150 void MixMonoAtGivenNativeRate(int native_sample_rate,
151 AudioFrame* mix_frame,
152 rtc::scoped_refptr<AudioMixer> mixer,
153 MockMixerAudioSource* audio_source) {
154 ON_CALL(*audio_source, PreferredSampleRate())
155 .WillByDefault(Return(native_sample_rate));
156 audio_source->fake_frame()->sample_rate_hz_ = native_sample_rate;
157 audio_source->fake_frame()->samples_per_channel_ = native_sample_rate / 100;
158
159 mixer->Mix(1, mix_frame);
160 }
161
TEST(AudioMixer,LargestEnergyVadActiveMixed)162 TEST(AudioMixer, LargestEnergyVadActiveMixed) {
163 constexpr int kAudioSources =
164 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 3;
165
166 const auto mixer = AudioMixerImpl::Create();
167
168 MockMixerAudioSource participants[kAudioSources];
169
170 for (int i = 0; i < kAudioSources; ++i) {
171 ResetFrame(participants[i].fake_frame());
172
173 // We set the 80-th sample value since the first 80 samples may be
174 // modified by a ramped-in window.
175 participants[i].fake_frame()->mutable_data()[80] = i;
176
177 EXPECT_TRUE(mixer->AddSource(&participants[i]));
178 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(_, _)).Times(Exactly(1));
179 }
180
181 // Last participant gives audio frame with passive VAD, although it has the
182 // largest energy.
183 participants[kAudioSources - 1].fake_frame()->vad_activity_ =
184 AudioFrame::kVadPassive;
185
186 AudioFrame audio_frame;
187 mixer->Mix(1, // number of channels
188 &audio_frame);
189
190 for (int i = 0; i < kAudioSources; ++i) {
191 bool is_mixed =
192 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]);
193 if (i == kAudioSources - 1 ||
194 i < kAudioSources - 1 -
195 AudioMixerImpl::kMaximumAmountOfMixedAudioSources) {
196 EXPECT_FALSE(is_mixed)
197 << "Mixing status of AudioSource #" << i << " wrong.";
198 } else {
199 EXPECT_TRUE(is_mixed)
200 << "Mixing status of AudioSource #" << i << " wrong.";
201 }
202 }
203 }
204
TEST(AudioMixer,FrameNotModifiedForSingleParticipant)205 TEST(AudioMixer, FrameNotModifiedForSingleParticipant) {
206 const auto mixer = AudioMixerImpl::Create();
207
208 MockMixerAudioSource participant;
209
210 ResetFrame(participant.fake_frame());
211 const size_t n_samples = participant.fake_frame()->samples_per_channel_;
212
213 // Modify the frame so that it's not zero.
214 int16_t* fake_frame_data = participant.fake_frame()->mutable_data();
215 for (size_t j = 0; j < n_samples; ++j) {
216 fake_frame_data[j] = static_cast<int16_t>(j);
217 }
218
219 EXPECT_TRUE(mixer->AddSource(&participant));
220 EXPECT_CALL(participant, GetAudioFrameWithInfo(_, _)).Times(Exactly(2));
221
222 AudioFrame audio_frame;
223 // Two mix iteration to compare after the ramp-up step.
224 for (int i = 0; i < 2; ++i) {
225 mixer->Mix(1, // number of channels
226 &audio_frame);
227 }
228
229 EXPECT_EQ(0, memcmp(participant.fake_frame()->data(), audio_frame.data(),
230 n_samples));
231 }
232
TEST(AudioMixer,SourceAtNativeRateShouldNeverResample)233 TEST(AudioMixer, SourceAtNativeRateShouldNeverResample) {
234 const auto mixer = AudioMixerImpl::Create();
235
236 MockMixerAudioSource audio_source;
237 ResetFrame(audio_source.fake_frame());
238
239 mixer->AddSource(&audio_source);
240
241 for (auto frequency : {8000, 16000, 32000, 48000}) {
242 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(frequency, _))
243 .Times(Exactly(1));
244
245 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
246 &audio_source);
247 }
248 }
249
TEST(AudioMixer,MixerShouldMixAtNativeSourceRate)250 TEST(AudioMixer, MixerShouldMixAtNativeSourceRate) {
251 const auto mixer = AudioMixerImpl::Create();
252
253 MockMixerAudioSource audio_source;
254 ResetFrame(audio_source.fake_frame());
255
256 mixer->AddSource(&audio_source);
257
258 for (auto frequency : {8000, 16000, 32000, 48000}) {
259 MixMonoAtGivenNativeRate(frequency, &frame_for_mixing, mixer,
260 &audio_source);
261
262 EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_);
263 }
264 }
265
TEST(AudioMixer,MixerShouldAlwaysMixAtNativeRate)266 TEST(AudioMixer, MixerShouldAlwaysMixAtNativeRate) {
267 const auto mixer = AudioMixerImpl::Create();
268
269 MockMixerAudioSource participant;
270 ResetFrame(participant.fake_frame());
271 mixer->AddSource(&participant);
272
273 const int needed_frequency = 44100;
274 ON_CALL(participant, PreferredSampleRate())
275 .WillByDefault(Return(needed_frequency));
276
277 // We expect mixing frequency to be native and >= needed_frequency.
278 const int expected_mix_frequency = 48000;
279 EXPECT_CALL(participant, GetAudioFrameWithInfo(expected_mix_frequency, _))
280 .Times(Exactly(1));
281 participant.fake_frame()->sample_rate_hz_ = expected_mix_frequency;
282 participant.fake_frame()->samples_per_channel_ = expected_mix_frequency / 100;
283
284 mixer->Mix(1, &frame_for_mixing);
285
286 EXPECT_EQ(48000, frame_for_mixing.sample_rate_hz_);
287 }
288
289 // Check that the mixing rate is always >= participants preferred rate.
TEST(AudioMixer,ShouldNotCauseQualityLossForMultipleSources)290 TEST(AudioMixer, ShouldNotCauseQualityLossForMultipleSources) {
291 const auto mixer = AudioMixerImpl::Create();
292
293 std::vector<MockMixerAudioSource> audio_sources(2);
294 const std::vector<int> source_sample_rates = {8000, 16000};
295 for (int i = 0; i < 2; ++i) {
296 auto& source = audio_sources[i];
297 ResetFrame(source.fake_frame());
298 mixer->AddSource(&source);
299 const auto sample_rate = source_sample_rates[i];
300 EXPECT_CALL(source, PreferredSampleRate()).WillOnce(Return(sample_rate));
301
302 EXPECT_CALL(source, GetAudioFrameWithInfo(::testing::Ge(sample_rate), _));
303 }
304 mixer->Mix(1, &frame_for_mixing);
305 }
306
TEST(AudioMixer,ParticipantNumberOfChannels)307 TEST(AudioMixer, ParticipantNumberOfChannels) {
308 const auto mixer = AudioMixerImpl::Create();
309
310 MockMixerAudioSource participant;
311 ResetFrame(participant.fake_frame());
312
313 EXPECT_TRUE(mixer->AddSource(&participant));
314 for (size_t number_of_channels : {1, 2}) {
315 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
316 .Times(Exactly(1));
317 mixer->Mix(number_of_channels, &frame_for_mixing);
318 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
319 }
320 }
321
322 // Maximal amount of participants are mixed one iteration, then
323 // another participant with higher energy is added.
TEST(AudioMixer,RampedOutSourcesShouldNotBeMarkedMixed)324 TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
325 constexpr int kAudioSources =
326 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
327
328 const auto mixer = AudioMixerImpl::Create();
329 MockMixerAudioSource participants[kAudioSources];
330
331 for (int i = 0; i < kAudioSources; ++i) {
332 ResetFrame(participants[i].fake_frame());
333 // Set the participant audio energy to increase with the index
334 // |i|.
335 participants[i].fake_frame()->mutable_data()[0] = 100 * i;
336 }
337
338 // Add all participants but the loudest for mixing.
339 for (int i = 0; i < kAudioSources - 1; ++i) {
340 EXPECT_TRUE(mixer->AddSource(&participants[i]));
341 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
342 .Times(Exactly(1));
343 }
344
345 // First mixer iteration
346 mixer->Mix(1, &frame_for_mixing);
347
348 // All participants but the loudest should have been mixed.
349 for (int i = 0; i < kAudioSources - 1; ++i) {
350 EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
351 << "Mixed status of AudioSource #" << i << " wrong.";
352 }
353
354 // Add new participant with higher energy.
355 EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1]));
356 for (int i = 0; i < kAudioSources; ++i) {
357 EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
358 .Times(Exactly(1));
359 }
360
361 mixer->Mix(1, &frame_for_mixing);
362
363 // The most quiet participant should not have been mixed.
364 EXPECT_FALSE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[0]))
365 << "Mixed status of AudioSource #0 wrong.";
366
367 // The loudest participants should have been mixed.
368 for (int i = 1; i < kAudioSources; ++i) {
369 EXPECT_EQ(true,
370 mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
371 << "Mixed status of AudioSource #" << i << " wrong.";
372 }
373 }
374
375 // This test checks that the initialization and participant addition
376 // can be done on a different thread.
TEST(AudioMixer,ConstructFromOtherThread)377 TEST(AudioMixer, ConstructFromOtherThread) {
378 TaskQueueForTest init_queue("init");
379 rtc::scoped_refptr<AudioMixer> mixer;
380 init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); },
381 RTC_FROM_HERE);
382
383 MockMixerAudioSource participant;
384 EXPECT_CALL(participant, PreferredSampleRate())
385 .WillRepeatedly(Return(kDefaultSampleRateHz));
386
387 ResetFrame(participant.fake_frame());
388
389 TaskQueueForTest participant_queue("participant");
390 participant_queue.SendTask(
391 [&mixer, &participant]() { mixer->AddSource(&participant); },
392 RTC_FROM_HERE);
393
394 EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
395 .Times(Exactly(1));
396
397 // Do one mixer iteration
398 mixer->Mix(1, &frame_for_mixing);
399 }
400
TEST(AudioMixer,MutedShouldMixAfterUnmuted)401 TEST(AudioMixer, MutedShouldMixAfterUnmuted) {
402 constexpr int kAudioSources =
403 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
404
405 std::vector<AudioFrame> frames(kAudioSources);
406 for (auto& frame : frames) {
407 ResetFrame(&frame);
408 }
409
410 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
411 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
412 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted;
413 std::vector<bool> expected_status(kAudioSources, true);
414 expected_status[0] = false;
415
416 MixAndCompare(frames, frame_info, expected_status);
417 }
418
TEST(AudioMixer,PassiveShouldMixAfterNormal)419 TEST(AudioMixer, PassiveShouldMixAfterNormal) {
420 constexpr int kAudioSources =
421 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
422
423 std::vector<AudioFrame> frames(kAudioSources);
424 for (auto& frame : frames) {
425 ResetFrame(&frame);
426 }
427
428 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
429 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
430 frames[0].vad_activity_ = AudioFrame::kVadPassive;
431 std::vector<bool> expected_status(kAudioSources, true);
432 expected_status[0] = false;
433
434 MixAndCompare(frames, frame_info, expected_status);
435 }
436
TEST(AudioMixer,ActiveShouldMixBeforeLoud)437 TEST(AudioMixer, ActiveShouldMixBeforeLoud) {
438 constexpr int kAudioSources =
439 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
440
441 std::vector<AudioFrame> frames(kAudioSources);
442 for (auto& frame : frames) {
443 ResetFrame(&frame);
444 }
445
446 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
447 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
448 frames[0].vad_activity_ = AudioFrame::kVadPassive;
449 int16_t* frame_data = frames[0].mutable_data();
450 std::fill(frame_data, frame_data + kDefaultSampleRateHz / 100,
451 std::numeric_limits<int16_t>::max());
452 std::vector<bool> expected_status(kAudioSources, true);
453 expected_status[0] = false;
454
455 MixAndCompare(frames, frame_info, expected_status);
456 }
457
TEST(AudioMixer,UnmutedShouldMixBeforeLoud)458 TEST(AudioMixer, UnmutedShouldMixBeforeLoud) {
459 constexpr int kAudioSources =
460 AudioMixerImpl::kMaximumAmountOfMixedAudioSources + 1;
461
462 std::vector<AudioFrame> frames(kAudioSources);
463 for (auto& frame : frames) {
464 ResetFrame(&frame);
465 }
466
467 std::vector<AudioMixer::Source::AudioFrameInfo> frame_info(
468 kAudioSources, AudioMixer::Source::AudioFrameInfo::kNormal);
469 frame_info[0] = AudioMixer::Source::AudioFrameInfo::kMuted;
470 int16_t* frame_data = frames[0].mutable_data();
471 std::fill(frame_data, frame_data + kDefaultSampleRateHz / 100,
472 std::numeric_limits<int16_t>::max());
473 std::vector<bool> expected_status(kAudioSources, true);
474 expected_status[0] = false;
475
476 MixAndCompare(frames, frame_info, expected_status);
477 }
478
TEST(AudioMixer,MixingRateShouldBeDecidedByRateCalculator)479 TEST(AudioMixer, MixingRateShouldBeDecidedByRateCalculator) {
480 constexpr int kOutputRate = 22000;
481 const auto mixer =
482 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
483 new CustomRateCalculator(kOutputRate)),
484 true);
485 MockMixerAudioSource audio_source;
486 mixer->AddSource(&audio_source);
487 ResetFrame(audio_source.fake_frame());
488
489 EXPECT_CALL(audio_source, GetAudioFrameWithInfo(kOutputRate, _))
490 .Times(Exactly(1));
491
492 mixer->Mix(1, &frame_for_mixing);
493 }
494
TEST(AudioMixer,ZeroSourceRateShouldBeDecidedByRateCalculator)495 TEST(AudioMixer, ZeroSourceRateShouldBeDecidedByRateCalculator) {
496 constexpr int kOutputRate = 8000;
497 const auto mixer =
498 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
499 new CustomRateCalculator(kOutputRate)),
500 true);
501
502 mixer->Mix(1, &frame_for_mixing);
503
504 EXPECT_EQ(kOutputRate, frame_for_mixing.sample_rate_hz_);
505 }
506
TEST(AudioMixer,NoLimiterBasicApiCalls)507 TEST(AudioMixer, NoLimiterBasicApiCalls) {
508 const auto mixer = AudioMixerImpl::Create(
509 std::unique_ptr<OutputRateCalculator>(new DefaultOutputRateCalculator()),
510 false);
511 mixer->Mix(1, &frame_for_mixing);
512 }
513
TEST(AudioMixer,AnyRateIsPossibleWithNoLimiter)514 TEST(AudioMixer, AnyRateIsPossibleWithNoLimiter) {
515 // No APM limiter means no AudioProcessing::NativeRate restriction
516 // on mixing rate. The rate has to be divisible by 100 since we use
517 // 10 ms frames, though.
518 for (const auto rate : {8000, 20000, 24000, 32000, 44100}) {
519 for (const size_t number_of_channels : {1, 2}) {
520 for (const auto number_of_sources : {0, 1, 2, 3, 4}) {
521 SCOPED_TRACE(
522 ProduceDebugText(rate, number_of_sources, number_of_sources));
523 const auto mixer =
524 AudioMixerImpl::Create(std::unique_ptr<OutputRateCalculator>(
525 new CustomRateCalculator(rate)),
526 false);
527
528 std::vector<MockMixerAudioSource> sources(number_of_sources);
529 for (auto& source : sources) {
530 ResetFrame(source.fake_frame());
531 mixer->AddSource(&source);
532 }
533
534 mixer->Mix(number_of_channels, &frame_for_mixing);
535 EXPECT_EQ(rate, frame_for_mixing.sample_rate_hz_);
536 EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
537 }
538 }
539 }
540 }
541
TEST(AudioMixer,MultipleChannelsOneParticipant)542 TEST(AudioMixer, MultipleChannelsOneParticipant) {
543 // Set up a participant with a 6-channel frame, and make sure a 6-channel
544 // frame with the right sample values comes out from the mixer. There are 2
545 // Mix calls because of ramp-up.
546 constexpr size_t kNumberOfChannels = 6;
547 MockMixerAudioSource source;
548 ResetFrame(source.fake_frame());
549 const auto mixer = AudioMixerImpl::Create();
550 mixer->AddSource(&source);
551 mixer->Mix(1, &frame_for_mixing);
552 auto* frame = source.fake_frame();
553 frame->num_channels_ = kNumberOfChannels;
554 std::fill(frame->mutable_data(),
555 frame->mutable_data() + AudioFrame::kMaxDataSizeSamples, 0);
556 for (size_t i = 0; i < kNumberOfChannels; ++i) {
557 frame->mutable_data()[100 * frame->num_channels_ + i] = 1000 * i;
558 }
559
560 mixer->Mix(kNumberOfChannels, &frame_for_mixing);
561
562 EXPECT_EQ(frame_for_mixing.num_channels_, kNumberOfChannels);
563 for (size_t i = 0; i < kNumberOfChannels; ++i) {
564 EXPECT_EQ(frame_for_mixing.data()[100 * frame_for_mixing.num_channels_ + i],
565 static_cast<int16_t>(1000 * i));
566 }
567 }
568
TEST(AudioMixer,MultipleChannelsManyParticipants)569 TEST(AudioMixer, MultipleChannelsManyParticipants) {
570 // Sets up 2 participants. One has a 6-channel frame. Make sure a 6-channel
571 // frame with the right sample values comes out from the mixer. There are 2
572 // Mix calls because of ramp-up.
573 constexpr size_t kNumberOfChannels = 6;
574 MockMixerAudioSource source;
575 const auto mixer = AudioMixerImpl::Create();
576 mixer->AddSource(&source);
577 ResetFrame(source.fake_frame());
578 mixer->Mix(1, &frame_for_mixing);
579 auto* frame = source.fake_frame();
580 frame->num_channels_ = kNumberOfChannels;
581 std::fill(frame->mutable_data(),
582 frame->mutable_data() + AudioFrame::kMaxDataSizeSamples, 0);
583 for (size_t i = 0; i < kNumberOfChannels; ++i) {
584 frame->mutable_data()[100 * frame->num_channels_ + i] = 1000 * i;
585 }
586 MockMixerAudioSource other_source;
587 ResetFrame(other_source.fake_frame());
588 mixer->AddSource(&other_source);
589
590 mixer->Mix(kNumberOfChannels, &frame_for_mixing);
591
592 EXPECT_EQ(frame_for_mixing.num_channels_, kNumberOfChannels);
593 for (size_t i = 0; i < kNumberOfChannels; ++i) {
594 EXPECT_EQ(frame_for_mixing.data()[100 * frame_for_mixing.num_channels_ + i],
595 static_cast<int16_t>(1000 * i));
596 }
597 }
598
599 class HighOutputRateCalculator : public OutputRateCalculator {
600 public:
601 static const int kDefaultFrequency = 76000;
CalculateOutputRateFromRange(rtc::ArrayView<const int> preferred_sample_rates)602 int CalculateOutputRateFromRange(
603 rtc::ArrayView<const int> preferred_sample_rates) override {
604 return kDefaultFrequency;
605 }
~HighOutputRateCalculator()606 ~HighOutputRateCalculator() override {}
607 };
608 const int HighOutputRateCalculator::kDefaultFrequency;
609
TEST(AudioMixerDeathTest,MultipleChannelsAndHighRate)610 TEST(AudioMixerDeathTest, MultipleChannelsAndHighRate) {
611 constexpr size_t kSamplesPerChannel =
612 HighOutputRateCalculator::kDefaultFrequency / 100;
613 // As many channels as an AudioFrame can fit:
614 constexpr size_t kNumberOfChannels =
615 AudioFrame::kMaxDataSizeSamples / kSamplesPerChannel;
616 MockMixerAudioSource source;
617 const auto mixer = AudioMixerImpl::Create(
618 std::make_unique<HighOutputRateCalculator>(), true);
619 mixer->AddSource(&source);
620 ResetFrame(source.fake_frame());
621 mixer->Mix(1, &frame_for_mixing);
622 auto* frame = source.fake_frame();
623 frame->num_channels_ = kNumberOfChannels;
624 frame->sample_rate_hz_ = HighOutputRateCalculator::kDefaultFrequency;
625 frame->samples_per_channel_ = kSamplesPerChannel;
626
627 std::fill(frame->mutable_data(),
628 frame->mutable_data() + AudioFrame::kMaxDataSizeSamples, 0);
629 MockMixerAudioSource other_source;
630 ResetFrame(other_source.fake_frame());
631 auto* other_frame = other_source.fake_frame();
632 other_frame->num_channels_ = kNumberOfChannels;
633 other_frame->sample_rate_hz_ = HighOutputRateCalculator::kDefaultFrequency;
634 other_frame->samples_per_channel_ = kSamplesPerChannel;
635 mixer->AddSource(&other_source);
636
637 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
638 EXPECT_DEATH(mixer->Mix(kNumberOfChannels, &frame_for_mixing), "");
639 #elif !RTC_DCHECK_IS_ON
640 mixer->Mix(kNumberOfChannels, &frame_for_mixing);
641 EXPECT_EQ(frame_for_mixing.num_channels_, kNumberOfChannels);
642 EXPECT_EQ(frame_for_mixing.sample_rate_hz_,
643 HighOutputRateCalculator::kDefaultFrequency);
644 #endif
645 }
646
647 } // namespace webrtc
648