Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1318)

Unified Diff: webrtc/modules/audio_mixer/audio_mixer_impl.cc

Issue 2692333002: Optionally disable APM limiter in AudioMixer. (Closed)
Patch Set: Fix int16_t <-> size_t compilation warnings. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_mixer/audio_mixer_impl.cc
diff --git a/webrtc/modules/audio_mixer/audio_mixer_impl.cc b/webrtc/modules/audio_mixer/audio_mixer_impl.cc
index 3da1be227071da85ea62b08f4ec3cdf3611286e5..e2fa80d1dca8c9b5df2046f3a499442d4bb34563 100644
--- a/webrtc/modules/audio_mixer/audio_mixer_impl.cc
+++ b/webrtc/modules/audio_mixer/audio_mixer_impl.cc
@@ -15,7 +15,6 @@
#include <iterator>
#include <utility>
-#include "webrtc/audio/utility/audio_frame_operations.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/audio_mixer/audio_frame_manipulator.h"
#include "webrtc/modules/audio_mixer/default_output_rate_calculator.h"
@@ -79,45 +78,6 @@ void RampAndUpdateGain(
}
}
-// Mix the AudioFrames stored in audioFrameList into mixed_audio.
-int32_t MixFromList(AudioFrame* mixed_audio,
- const AudioFrameList& audio_frame_list,
- bool use_limiter) {
- if (audio_frame_list.empty()) {
- return 0;
- }
-
- if (audio_frame_list.size() == 1) {
- mixed_audio->timestamp_ = audio_frame_list.front()->timestamp_;
- mixed_audio->elapsed_time_ms_ = audio_frame_list.front()->elapsed_time_ms_;
- } else {
- // TODO(wu): Issue 3390.
- // Audio frame timestamp is only supported in one channel case.
- mixed_audio->timestamp_ = 0;
- mixed_audio->elapsed_time_ms_ = -1;
- }
-
- for (const auto& frame : audio_frame_list) {
- RTC_DCHECK_EQ(mixed_audio->sample_rate_hz_, frame->sample_rate_hz_);
- RTC_DCHECK_EQ(
- frame->samples_per_channel_,
- static_cast<size_t>((mixed_audio->sample_rate_hz_ *
- webrtc::AudioMixerImpl::kFrameDurationInMs) /
- 1000));
-
- // Mix |f.frame| into |mixed_audio|, with saturation protection.
- // These effect is applied to |f.frame| itself prior to mixing.
- if (use_limiter) {
- // This is to avoid saturation in the mixing. It is only
- // meaningful if the limiter will be used.
- AudioFrameOperations::ApplyHalfGain(frame);
- }
- RTC_DCHECK_EQ(frame->num_channels_, mixed_audio->num_channels_);
- AudioFrameOperations::Add(*frame, mixed_audio);
- }
- return 0;
-}
-
AudioMixerImpl::SourceStatusList::const_iterator FindSourceInList(
AudioMixerImpl::Source const* audio_source,
AudioMixerImpl::SourceStatusList const* audio_source_list) {
@@ -139,68 +99,40 @@ AudioMixerImpl::SourceStatusList::iterator FindSourceInList(
});
}
-std::unique_ptr<AudioProcessing> CreateLimiter() {
- Config config;
- config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
- std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config));
- if (!limiter.get()) {
- return nullptr;
- }
-
- if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) !=
- limiter->kNoError) {
- return nullptr;
- }
-
- // We smoothly limit the mixed frame to -7 dbFS. -6 would correspond to the
- // divide-by-2 but -7 is used instead to give a bit of headroom since the
- // AGC is not a hard limiter.
- if (limiter->gain_control()->set_target_level_dbfs(7) != limiter->kNoError) {
- return nullptr;
- }
-
- if (limiter->gain_control()->set_compression_gain_db(0) !=
- limiter->kNoError) {
- return nullptr;
- }
-
- if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) {
- return nullptr;
- }
-
- if (limiter->gain_control()->Enable(true) != limiter->kNoError) {
- return nullptr;
- }
- return limiter;
-}
-
} // namespace
AudioMixerImpl::AudioMixerImpl(
- std::unique_ptr<AudioProcessing> limiter,
- std::unique_ptr<OutputRateCalculator> output_rate_calculator)
+ std::unique_ptr<OutputRateCalculator> output_rate_calculator,
+ bool use_limiter)
: output_rate_calculator_(std::move(output_rate_calculator)),
output_frequency_(0),
sample_size_(0),
audio_source_list_(),
- use_limiter_(true),
- time_stamp_(0),
- limiter_(std::move(limiter)) {}
+ frame_combiner_(use_limiter) {}
AudioMixerImpl::~AudioMixerImpl() {}
rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() {
- return CreateWithOutputRateCalculator(
+ return CreateWithOutputRateCalculatorAndLimiter(
std::unique_ptr<DefaultOutputRateCalculator>(
- new DefaultOutputRateCalculator()));
+ new DefaultOutputRateCalculator()),
+ true);
}
rtc::scoped_refptr<AudioMixerImpl>
AudioMixerImpl::CreateWithOutputRateCalculator(
std::unique_ptr<OutputRateCalculator> output_rate_calculator) {
+ return CreateWithOutputRateCalculatorAndLimiter(
+ std::move(output_rate_calculator), true);
+}
+
+rtc::scoped_refptr<AudioMixerImpl>
+AudioMixerImpl::CreateWithOutputRateCalculatorAndLimiter(
+ std::unique_ptr<OutputRateCalculator> output_rate_calculator,
+ bool use_limiter) {
return rtc::scoped_refptr<AudioMixerImpl>(
new rtc::RefCountedObject<AudioMixerImpl>(
- CreateLimiter(), std::move(output_rate_calculator)));
+ std::move(output_rate_calculator), use_limiter));
}
void AudioMixerImpl::Mix(size_t number_of_channels,
@@ -210,34 +142,10 @@ void AudioMixerImpl::Mix(size_t number_of_channels,
CalculateOutputFrequency();
- AudioFrameList mix_list;
{
rtc::CritScope lock(&crit_);
- mix_list = GetAudioFromSources();
-
- for (const auto& frame : mix_list) {
- RemixFrame(number_of_channels, frame);
- }
-
- audio_frame_for_mixing->UpdateFrame(
- -1, time_stamp_, NULL, 0, OutputFrequency(), AudioFrame::kNormalSpeech,
- AudioFrame::kVadPassive, number_of_channels);
-
- time_stamp_ += static_cast<uint32_t>(sample_size_);
-
- use_limiter_ = mix_list.size() > 1;
-
- // We only use the limiter if we're actually mixing multiple streams.
- MixFromList(audio_frame_for_mixing, mix_list, use_limiter_);
- }
-
- if (audio_frame_for_mixing->samples_per_channel_ == 0) {
- // Nothing was mixed, set the audio samples to silence.
- audio_frame_for_mixing->samples_per_channel_ = sample_size_;
- AudioFrameOperations::Mute(audio_frame_for_mixing);
- } else {
- // Only call the limiter if we have something to mix.
- LimitMixedAudio(audio_frame_for_mixing);
+ frame_combiner_.Combine(GetAudioFromSources(), number_of_channels,
+ OutputFrequency(), audio_frame_for_mixing);
}
return;
@@ -331,36 +239,6 @@ AudioFrameList AudioMixerImpl::GetAudioFromSources() {
return result;
}
-
-bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const {
- RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
- if (!use_limiter_) {
- return true;
- }
-
- // Smoothly limit the mixed frame.
- const int error = limiter_->ProcessStream(mixed_audio);
-
- // And now we can safely restore the level. This procedure results in
- // some loss of resolution, deemed acceptable.
- //
- // It's possible to apply the gain in the AGC (with a target level of 0 dbFS
- // and compression gain of 6 dB). However, in the transition frame when this
- // is enabled (moving from one to two audio sources) it has the potential to
- // create discontinuities in the mixed frame.
- //
- // Instead we double the frame (with addition since left-shifting a
- // negative value is undefined).
- AudioFrameOperations::Add(*mixed_audio, mixed_audio);
-
- if (error != limiter_->kNoError) {
- LOG_F(LS_ERROR) << "Error from AudioProcessing: " << error;
- RTC_NOTREACHED();
- return false;
- }
- return true;
-}
-
bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest(
AudioMixerImpl::Source* audio_source) const {
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer_impl.h ('k') | webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698