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 |