| Index: webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc
|
| diff --git a/webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc b/webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc
|
| index e90dac1e70e9839f032da4db4f91b8eb0d002686..f651fe978315fa01dbcad9ab0f0dc873a3129c2d 100644
|
| --- a/webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc
|
| +++ b/webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc
|
| @@ -12,10 +12,13 @@
|
|
|
| #include <limits>
|
| #include <memory>
|
| +#include <sstream>
|
| +#include <string>
|
| #include <utility>
|
|
|
| #include "webrtc/api/audio/audio_mixer.h"
|
| #include "webrtc/base/bind.h"
|
| +#include "webrtc/base/checks.h"
|
| #include "webrtc/base/thread.h"
|
| #include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
|
| #include "webrtc/modules/audio_mixer/default_output_rate_calculator.h"
|
| @@ -46,6 +49,16 @@ void ResetFrame(AudioFrame* frame) {
|
| frame->speech_type_ = AudioFrame::kNormalSpeech;
|
| }
|
|
|
| +std::string ProduceDebugText(int sample_rate_hz,
|
| + int number_of_channels,
|
| + int number_of_sources) {
|
| + std::ostringstream ss;
|
| + ss << "Sample rate: " << sample_rate_hz << " ";
|
| + ss << "Number of channels: " << number_of_channels << " ";
|
| + ss << "Number of sources: " << number_of_sources;
|
| + return ss.str();
|
| +}
|
| +
|
| AudioFrame frame_for_mixing;
|
|
|
| } // namespace
|
| @@ -78,7 +91,8 @@ class MockMixerAudioSource : public AudioMixer::Source {
|
| AudioFrame* audio_frame) {
|
| audio_frame->CopyFrom(fake_frame_);
|
| audio_frame->sample_rate_hz_ = sample_rate_hz;
|
| - audio_frame->samples_per_channel_ = sample_rate_hz / 100;
|
| + audio_frame->samples_per_channel_ =
|
| + rtc::CheckedDivExact(sample_rate_hz, 100);
|
| return fake_info();
|
| }
|
|
|
| @@ -89,7 +103,7 @@ class MockMixerAudioSource : public AudioMixer::Source {
|
| class CustomRateCalculator : public OutputRateCalculator {
|
| public:
|
| explicit CustomRateCalculator(int rate) : rate_(rate) {}
|
| - int CalculateOutputRate(const std::vector<int>& preferred_rates) {
|
| + int CalculateOutputRate(const std::vector<int>& preferred_rates) override {
|
| return rate_;
|
| }
|
|
|
| @@ -103,19 +117,19 @@ void MixAndCompare(
|
| const std::vector<AudioFrame>& frames,
|
| const std::vector<AudioMixer::Source::AudioFrameInfo>& frame_info,
|
| const std::vector<bool>& expected_status) {
|
| - int num_audio_sources = frames.size();
|
| + const size_t num_audio_sources = frames.size();
|
| RTC_DCHECK(frames.size() == frame_info.size());
|
| RTC_DCHECK(frame_info.size() == expected_status.size());
|
|
|
| const auto mixer = AudioMixerImpl::Create();
|
| std::vector<MockMixerAudioSource> participants(num_audio_sources);
|
|
|
| - for (int i = 0; i < num_audio_sources; i++) {
|
| + for (size_t i = 0; i < num_audio_sources; ++i) {
|
| participants[i].fake_frame()->CopyFrom(frames[i]);
|
| participants[i].set_fake_info(frame_info[i]);
|
| }
|
|
|
| - for (int i = 0; i < num_audio_sources; i++) {
|
| + for (size_t i = 0; i < num_audio_sources; ++i) {
|
| EXPECT_TRUE(mixer->AddSource(&participants[i]));
|
| EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
|
| .Times(Exactly(1));
|
| @@ -123,7 +137,7 @@ void MixAndCompare(
|
|
|
| mixer->Mix(1, &frame_for_mixing);
|
|
|
| - for (int i = 0; i < num_audio_sources; i++) {
|
| + for (size_t i = 0; i < num_audio_sources; ++i) {
|
| EXPECT_EQ(expected_status[i],
|
| mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
|
| << "Mixed status of AudioSource #" << i << " wrong.";
|
| @@ -191,11 +205,11 @@ TEST(AudioMixer, FrameNotModifiedForSingleParticipant) {
|
| MockMixerAudioSource participant;
|
|
|
| ResetFrame(participant.fake_frame());
|
| - const int n_samples = participant.fake_frame()->samples_per_channel_;
|
| + const size_t n_samples = participant.fake_frame()->samples_per_channel_;
|
|
|
| // Modify the frame so that it's not zero.
|
| - for (int j = 0; j < n_samples; j++) {
|
| - participant.fake_frame()->data_[j] = j;
|
| + for (size_t j = 0; j < n_samples; ++j) {
|
| + participant.fake_frame()->data_[j] = static_cast<int16_t>(j);
|
| }
|
|
|
| EXPECT_TRUE(mixer->AddSource(&participant));
|
| @@ -203,7 +217,7 @@ TEST(AudioMixer, FrameNotModifiedForSingleParticipant) {
|
|
|
| AudioFrame audio_frame;
|
| // Two mix iteration to compare after the ramp-up step.
|
| - for (int i = 0; i < 2; i++) {
|
| + for (int i = 0; i < 2; ++i) {
|
| mixer->Mix(1, // number of channels
|
| &audio_frame);
|
| }
|
| @@ -310,7 +324,7 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
|
| const auto mixer = AudioMixerImpl::Create();
|
| MockMixerAudioSource participants[kAudioSources];
|
|
|
| - for (int i = 0; i < kAudioSources; i++) {
|
| + for (int i = 0; i < kAudioSources; ++i) {
|
| ResetFrame(participants[i].fake_frame());
|
| // Set the participant audio energy to increase with the index
|
| // |i|.
|
| @@ -318,7 +332,7 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
|
| }
|
|
|
| // Add all participants but the loudest for mixing.
|
| - for (int i = 0; i < kAudioSources - 1; i++) {
|
| + for (int i = 0; i < kAudioSources - 1; ++i) {
|
| EXPECT_TRUE(mixer->AddSource(&participants[i]));
|
| EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
|
| .Times(Exactly(1));
|
| @@ -328,14 +342,14 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
|
| mixer->Mix(1, &frame_for_mixing);
|
|
|
| // All participants but the loudest should have been mixed.
|
| - for (int i = 0; i < kAudioSources - 1; i++) {
|
| + for (int i = 0; i < kAudioSources - 1; ++i) {
|
| EXPECT_TRUE(mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
|
| << "Mixed status of AudioSource #" << i << " wrong.";
|
| }
|
|
|
| // Add new participant with higher energy.
|
| EXPECT_TRUE(mixer->AddSource(&participants[kAudioSources - 1]));
|
| - for (int i = 0; i < kAudioSources; i++) {
|
| + for (int i = 0; i < kAudioSources; ++i) {
|
| EXPECT_CALL(participants[i], GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
|
| .Times(Exactly(1));
|
| }
|
| @@ -347,7 +361,7 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
|
| << "Mixed status of AudioSource #0 wrong.";
|
|
|
| // The loudest participants should have been mixed.
|
| - for (int i = 1; i < kAudioSources; i++) {
|
| + for (int i = 1; i < kAudioSources; ++i) {
|
| EXPECT_EQ(true,
|
| mixer->GetAudioSourceMixabilityStatusForTest(&participants[i]))
|
| << "Mixed status of AudioSource #" << i << " wrong.";
|
| @@ -456,9 +470,10 @@ TEST(AudioMixer, UnmutedShouldMixBeforeLoud) {
|
|
|
| TEST(AudioMixer, MixingRateShouldBeDecidedByRateCalculator) {
|
| constexpr int kOutputRate = 22000;
|
| - const auto mixer = AudioMixerImpl::CreateWithOutputRateCalculator(
|
| + const auto mixer = AudioMixerImpl::CreateWithOutputRateCalculatorAndLimiter(
|
| std::unique_ptr<OutputRateCalculator>(
|
| - new CustomRateCalculator(kOutputRate)));
|
| + new CustomRateCalculator(kOutputRate)),
|
| + true);
|
| MockMixerAudioSource audio_source;
|
| mixer->AddSource(&audio_source);
|
| ResetFrame(audio_source.fake_frame());
|
| @@ -471,12 +486,48 @@ TEST(AudioMixer, MixingRateShouldBeDecidedByRateCalculator) {
|
|
|
| TEST(AudioMixer, ZeroSourceRateShouldBeDecidedByRateCalculator) {
|
| constexpr int kOutputRate = 8000;
|
| - const auto mixer = AudioMixerImpl::CreateWithOutputRateCalculator(
|
| + const auto mixer = AudioMixerImpl::CreateWithOutputRateCalculatorAndLimiter(
|
| std::unique_ptr<OutputRateCalculator>(
|
| - new CustomRateCalculator(kOutputRate)));
|
| + new CustomRateCalculator(kOutputRate)),
|
| + true);
|
|
|
| mixer->Mix(1, &frame_for_mixing);
|
|
|
| EXPECT_EQ(kOutputRate, frame_for_mixing.sample_rate_hz_);
|
| }
|
| +
|
| +TEST(AudioMixer, NoLimiterBasicApiCalls) {
|
| + const auto mixer = AudioMixerImpl::CreateWithOutputRateCalculatorAndLimiter(
|
| + std::unique_ptr<OutputRateCalculator>(new DefaultOutputRateCalculator()),
|
| + false);
|
| + mixer->Mix(1, &frame_for_mixing);
|
| +}
|
| +
|
| +TEST(AudioMixer, AnyRateIsPossibleWithNoLimiter) {
|
| + // No APM limiter means no AudioProcessing::NativeRate restriction
|
| + // on mixing rate. The rate has to be divisible by 100 since we use
|
| + // 10 ms frames, though.
|
| + for (const auto rate : {8000, 20000, 24000, 32000, 44100}) {
|
| + for (const size_t number_of_channels : {1, 2}) {
|
| + for (const auto number_of_sources : {0, 1, 2, 3, 4}) {
|
| + SCOPED_TRACE(
|
| + ProduceDebugText(rate, number_of_sources, number_of_sources));
|
| + const auto mixer =
|
| + AudioMixerImpl::CreateWithOutputRateCalculatorAndLimiter(
|
| + std::unique_ptr<OutputRateCalculator>(
|
| + new CustomRateCalculator(rate)),
|
| + false);
|
| +
|
| + std::vector<MockMixerAudioSource> sources(number_of_sources);
|
| + for (auto& source : sources) {
|
| + mixer->AddSource(&source);
|
| + }
|
| +
|
| + mixer->Mix(number_of_channels, &frame_for_mixing);
|
| + EXPECT_EQ(rate, frame_for_mixing.sample_rate_hz_);
|
| + EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
|
| + }
|
| + }
|
| + }
|
| +}
|
| } // namespace webrtc
|
|
|