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