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