Removed the dependency in GainControlImpl on the ProcessingComponent class
BUG=webrtc:5353 Review URL: https://codereview.webrtc.org/1768943002 Cr-Commit-Position: refs/heads/master@{#11949}
This commit is contained in:
@ -80,11 +80,11 @@ static bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) {
|
||||
static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero");
|
||||
|
||||
struct AudioProcessingImpl::ApmPublicSubmodules {
|
||||
ApmPublicSubmodules() : gain_control(nullptr) {}
|
||||
ApmPublicSubmodules() {}
|
||||
// Accessed externally of APM without any lock acquired.
|
||||
std::unique_ptr<EchoCancellationImpl> echo_cancellation;
|
||||
std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
|
||||
GainControlImpl* gain_control;
|
||||
std::unique_ptr<GainControlImpl> gain_control;
|
||||
std::unique_ptr<HighPassFilterImpl> high_pass_filter;
|
||||
std::unique_ptr<LevelEstimatorImpl> level_estimator;
|
||||
std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
|
||||
@ -173,8 +173,8 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config,
|
||||
new EchoCancellationImpl(this, &crit_render_, &crit_capture_));
|
||||
public_submodules_->echo_control_mobile.reset(
|
||||
new EchoControlMobileImpl(this, &crit_render_, &crit_capture_));
|
||||
public_submodules_->gain_control =
|
||||
new GainControlImpl(this, &crit_capture_, &crit_capture_);
|
||||
public_submodules_->gain_control.reset(
|
||||
new GainControlImpl(this, &crit_capture_, &crit_capture_));
|
||||
public_submodules_->high_pass_filter.reset(
|
||||
new HighPassFilterImpl(&crit_capture_));
|
||||
public_submodules_->level_estimator.reset(
|
||||
@ -184,10 +184,8 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config,
|
||||
public_submodules_->voice_detection.reset(
|
||||
new VoiceDetectionImpl(&crit_capture_));
|
||||
public_submodules_->gain_control_for_experimental_agc.reset(
|
||||
new GainControlForExperimentalAgc(public_submodules_->gain_control,
|
||||
&crit_capture_));
|
||||
private_submodules_->component_list.push_back(
|
||||
public_submodules_->gain_control);
|
||||
new GainControlForExperimentalAgc(
|
||||
public_submodules_->gain_control.get(), &crit_capture_));
|
||||
}
|
||||
|
||||
SetExtraOptions(config);
|
||||
@ -318,6 +316,7 @@ int AudioProcessingImpl::InitializeLocked() {
|
||||
}
|
||||
}
|
||||
|
||||
InitializeGainController();
|
||||
InitializeEchoCanceller();
|
||||
InitializeEchoControlMobile();
|
||||
InitializeExperimentalAgc();
|
||||
@ -1093,7 +1092,7 @@ GainControl* AudioProcessingImpl::gain_control() const {
|
||||
if (constants_.use_experimental_agc) {
|
||||
return public_submodules_->gain_control_for_experimental_agc.get();
|
||||
}
|
||||
return public_submodules_->gain_control;
|
||||
return public_submodules_->gain_control.get();
|
||||
}
|
||||
|
||||
HighPassFilter* AudioProcessingImpl::high_pass_filter() const {
|
||||
@ -1127,7 +1126,8 @@ bool AudioProcessingImpl::is_data_processed() const {
|
||||
public_submodules_->high_pass_filter->is_enabled() ||
|
||||
public_submodules_->noise_suppression->is_enabled() ||
|
||||
public_submodules_->echo_cancellation->is_enabled() ||
|
||||
public_submodules_->echo_control_mobile->is_enabled()) {
|
||||
public_submodules_->echo_control_mobile->is_enabled() ||
|
||||
public_submodules_->gain_control->is_enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1191,7 +1191,7 @@ void AudioProcessingImpl::InitializeExperimentalAgc() {
|
||||
if (constants_.use_experimental_agc) {
|
||||
if (!private_submodules_->agc_manager.get()) {
|
||||
private_submodules_->agc_manager.reset(new AgcManagerDirect(
|
||||
public_submodules_->gain_control,
|
||||
public_submodules_->gain_control.get(),
|
||||
public_submodules_->gain_control_for_experimental_agc.get(),
|
||||
constants_.agc_startup_min_volume));
|
||||
}
|
||||
@ -1247,6 +1247,10 @@ void AudioProcessingImpl::InitializeEchoCanceller() {
|
||||
public_submodules_->echo_cancellation->Initialize();
|
||||
}
|
||||
|
||||
void AudioProcessingImpl::InitializeGainController() {
|
||||
public_submodules_->gain_control->Initialize();
|
||||
}
|
||||
|
||||
void AudioProcessingImpl::InitializeEchoControlMobile() {
|
||||
public_submodules_->echo_control_mobile->Initialize();
|
||||
}
|
||||
|
||||
@ -198,6 +198,8 @@ class AudioProcessingImpl : public AudioProcessing {
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||
void InitializeEchoCanceller()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
|
||||
void InitializeGainController()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
|
||||
void InitializeEchoControlMobile()
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
|
||||
int InitializeLocked(const ProcessingConfig& config)
|
||||
|
||||
@ -10,8 +10,7 @@
|
||||
|
||||
#include "webrtc/modules/audio_processing/gain_control_impl.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "webrtc/base/optional.h"
|
||||
#include "webrtc/modules/audio_processing/audio_buffer.h"
|
||||
#include "webrtc/modules/audio_processing/agc/legacy/gain_control.h"
|
||||
|
||||
@ -29,7 +28,7 @@ int16_t MapSetting(GainControl::Mode mode) {
|
||||
case GainControl::kFixedDigital:
|
||||
return kAgcModeFixedDigital;
|
||||
}
|
||||
assert(false);
|
||||
RTC_DCHECK(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -42,11 +41,59 @@ static const size_t kMaxNumFramesToBuffer = 100;
|
||||
|
||||
} // namespace
|
||||
|
||||
class GainControlImpl::GainController {
|
||||
public:
|
||||
explicit GainController() {
|
||||
state_ = WebRtcAgc_Create();
|
||||
RTC_CHECK(state_);
|
||||
}
|
||||
|
||||
~GainController() {
|
||||
RTC_DCHECK(state_);
|
||||
WebRtcAgc_Free(state_);
|
||||
}
|
||||
|
||||
Handle* state() {
|
||||
RTC_DCHECK(state_);
|
||||
return state_;
|
||||
}
|
||||
|
||||
void Initialize(int minimum_capture_level,
|
||||
int maximum_capture_level,
|
||||
Mode mode,
|
||||
int sample_rate_hz,
|
||||
int capture_level) {
|
||||
RTC_DCHECK(state_);
|
||||
int error =
|
||||
WebRtcAgc_Init(state_, minimum_capture_level, maximum_capture_level,
|
||||
MapSetting(mode), sample_rate_hz);
|
||||
RTC_DCHECK_EQ(0, error);
|
||||
|
||||
set_capture_level(capture_level);
|
||||
}
|
||||
|
||||
void set_capture_level(int capture_level) {
|
||||
capture_level_ = rtc::Optional<int>(capture_level);
|
||||
}
|
||||
|
||||
int get_capture_level() {
|
||||
RTC_DCHECK(capture_level_);
|
||||
return *capture_level_;
|
||||
}
|
||||
|
||||
private:
|
||||
Handle* state_;
|
||||
// TODO(peah): Remove the optional once the initialization is moved into the
|
||||
// ctor.
|
||||
rtc::Optional<int> capture_level_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(GainController);
|
||||
};
|
||||
|
||||
GainControlImpl::GainControlImpl(const AudioProcessing* apm,
|
||||
rtc::CriticalSection* crit_render,
|
||||
rtc::CriticalSection* crit_capture)
|
||||
: ProcessingComponent(),
|
||||
apm_(apm),
|
||||
: apm_(apm),
|
||||
crit_render_(crit_render),
|
||||
crit_capture_(crit_capture),
|
||||
mode_(kAdaptiveAnalog),
|
||||
@ -68,20 +115,20 @@ GainControlImpl::~GainControlImpl() {}
|
||||
|
||||
int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) {
|
||||
rtc::CritScope cs(crit_render_);
|
||||
if (!is_component_enabled()) {
|
||||
if (!enabled_) {
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
assert(audio->num_frames_per_band() <= 160);
|
||||
RTC_DCHECK_GE(160u, audio->num_frames_per_band());
|
||||
|
||||
render_queue_buffer_.resize(0);
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
Handle* my_handle = static_cast<Handle*>(handle(i));
|
||||
int err =
|
||||
WebRtcAgc_GetAddFarendError(my_handle, audio->num_frames_per_band());
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
int err = WebRtcAgc_GetAddFarendError(gain_controller->state(),
|
||||
audio->num_frames_per_band());
|
||||
|
||||
if (err != AudioProcessing::kNoError)
|
||||
return GetHandleError(my_handle);
|
||||
if (err != AudioProcessing::kNoError) {
|
||||
return AudioProcessing::kUnspecifiedError;
|
||||
}
|
||||
|
||||
// Buffer the samples in the render queue.
|
||||
render_queue_buffer_.insert(
|
||||
@ -106,17 +153,17 @@ int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) {
|
||||
void GainControlImpl::ReadQueuedRenderData() {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
|
||||
if (!is_component_enabled()) {
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
|
||||
size_t buffer_index = 0;
|
||||
const size_t num_frames_per_band =
|
||||
capture_queue_buffer_.size() / num_handles();
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
Handle* my_handle = static_cast<Handle*>(handle(i));
|
||||
WebRtcAgc_AddFarend(my_handle, &capture_queue_buffer_[buffer_index],
|
||||
capture_queue_buffer_.size() / num_handles_required();
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
WebRtcAgc_AddFarend(gain_controller->state(),
|
||||
&capture_queue_buffer_[buffer_index],
|
||||
num_frames_per_band);
|
||||
|
||||
buffer_index += num_frames_per_band;
|
||||
@ -127,49 +174,42 @@ void GainControlImpl::ReadQueuedRenderData() {
|
||||
int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
|
||||
if (!is_component_enabled()) {
|
||||
if (!enabled_) {
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
assert(audio->num_frames_per_band() <= 160);
|
||||
assert(audio->num_channels() == num_handles());
|
||||
|
||||
int err = AudioProcessing::kNoError;
|
||||
RTC_DCHECK_GE(160u, audio->num_frames_per_band());
|
||||
RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
|
||||
RTC_DCHECK_LE(num_handles_required(), gain_controllers_.size());
|
||||
|
||||
if (mode_ == kAdaptiveAnalog) {
|
||||
capture_levels_.assign(num_handles(), analog_capture_level_);
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
Handle* my_handle = static_cast<Handle*>(handle(i));
|
||||
err = WebRtcAgc_AddMic(
|
||||
my_handle,
|
||||
audio->split_bands(i),
|
||||
audio->num_bands(),
|
||||
audio->num_frames_per_band());
|
||||
int capture_channel = 0;
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
gain_controller->set_capture_level(analog_capture_level_);
|
||||
int err = WebRtcAgc_AddMic(
|
||||
gain_controller->state(), audio->split_bands(capture_channel),
|
||||
audio->num_bands(), audio->num_frames_per_band());
|
||||
|
||||
if (err != AudioProcessing::kNoError) {
|
||||
return GetHandleError(my_handle);
|
||||
return AudioProcessing::kUnspecifiedError;
|
||||
}
|
||||
++capture_channel;
|
||||
}
|
||||
} else if (mode_ == kAdaptiveDigital) {
|
||||
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
Handle* my_handle = static_cast<Handle*>(handle(i));
|
||||
int capture_channel = 0;
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
int32_t capture_level_out = 0;
|
||||
int err = WebRtcAgc_VirtualMic(
|
||||
gain_controller->state(), audio->split_bands(capture_channel),
|
||||
audio->num_bands(), audio->num_frames_per_band(),
|
||||
analog_capture_level_, &capture_level_out);
|
||||
|
||||
err = WebRtcAgc_VirtualMic(
|
||||
my_handle,
|
||||
audio->split_bands(i),
|
||||
audio->num_bands(),
|
||||
audio->num_frames_per_band(),
|
||||
analog_capture_level_,
|
||||
&capture_level_out);
|
||||
|
||||
capture_levels_[i] = capture_level_out;
|
||||
gain_controller->set_capture_level(capture_level_out);
|
||||
|
||||
if (err != AudioProcessing::kNoError) {
|
||||
return GetHandleError(my_handle);
|
||||
return AudioProcessing::kUnspecifiedError;
|
||||
}
|
||||
|
||||
++capture_channel;
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +219,7 @@ int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
|
||||
int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
|
||||
if (!is_component_enabled()) {
|
||||
if (!enabled_) {
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
@ -187,46 +227,44 @@ int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) {
|
||||
return AudioProcessing::kStreamParameterNotSetError;
|
||||
}
|
||||
|
||||
assert(audio->num_frames_per_band() <= 160);
|
||||
assert(audio->num_channels() == num_handles());
|
||||
RTC_DCHECK_GE(160u, audio->num_frames_per_band());
|
||||
RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
|
||||
|
||||
stream_is_saturated_ = false;
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
Handle* my_handle = static_cast<Handle*>(handle(i));
|
||||
int capture_channel = 0;
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
int32_t capture_level_out = 0;
|
||||
uint8_t saturation_warning = 0;
|
||||
|
||||
// The call to stream_has_echo() is ok from a deadlock perspective
|
||||
// as the capture lock is allready held.
|
||||
int err = WebRtcAgc_Process(
|
||||
my_handle,
|
||||
audio->split_bands_const(i),
|
||||
audio->num_bands(),
|
||||
audio->num_frames_per_band(),
|
||||
audio->split_bands(i),
|
||||
capture_levels_[i],
|
||||
&capture_level_out,
|
||||
apm_->echo_cancellation()->stream_has_echo(),
|
||||
&saturation_warning);
|
||||
gain_controller->state(), audio->split_bands_const(capture_channel),
|
||||
audio->num_bands(), audio->num_frames_per_band(),
|
||||
audio->split_bands(capture_channel),
|
||||
gain_controller->get_capture_level(), &capture_level_out,
|
||||
apm_->echo_cancellation()->stream_has_echo(), &saturation_warning);
|
||||
|
||||
if (err != AudioProcessing::kNoError) {
|
||||
return GetHandleError(my_handle);
|
||||
return AudioProcessing::kUnspecifiedError;
|
||||
}
|
||||
|
||||
capture_levels_[i] = capture_level_out;
|
||||
gain_controller->set_capture_level(capture_level_out);
|
||||
if (saturation_warning == 1) {
|
||||
stream_is_saturated_ = true;
|
||||
}
|
||||
|
||||
++capture_channel;
|
||||
}
|
||||
|
||||
if (mode_ == kAdaptiveAnalog) {
|
||||
// Take the analog level to be the average across the handles.
|
||||
analog_capture_level_ = 0;
|
||||
for (size_t i = 0; i < num_handles(); i++) {
|
||||
analog_capture_level_ += capture_levels_[i];
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
analog_capture_level_ += gain_controller->get_capture_level();
|
||||
}
|
||||
|
||||
analog_capture_level_ /= num_handles();
|
||||
analog_capture_level_ /= num_handles_required();
|
||||
}
|
||||
|
||||
was_analog_level_set_ = false;
|
||||
@ -257,12 +295,18 @@ int GainControlImpl::stream_analog_level() {
|
||||
int GainControlImpl::Enable(bool enable) {
|
||||
rtc::CritScope cs_render(crit_render_);
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
return EnableComponent(enable);
|
||||
if (enable && !enabled_) {
|
||||
enabled_ = enable; // Must be set before Initialize() is called.
|
||||
Initialize();
|
||||
} else {
|
||||
enabled_ = enable;
|
||||
}
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
bool GainControlImpl::is_enabled() const {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
return is_component_enabled();
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
int GainControlImpl::set_mode(Mode mode) {
|
||||
@ -273,7 +317,8 @@ int GainControlImpl::set_mode(Mode mode) {
|
||||
}
|
||||
|
||||
mode_ = mode;
|
||||
return Initialize();
|
||||
Initialize();
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
GainControl::Mode GainControlImpl::mode() const {
|
||||
@ -299,7 +344,8 @@ int GainControlImpl::set_analog_level_limits(int minimum,
|
||||
minimum_capture_level_ = minimum;
|
||||
maximum_capture_level_ = maximum;
|
||||
|
||||
return Initialize();
|
||||
Initialize();
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
int GainControlImpl::analog_level_minimum() const {
|
||||
@ -318,12 +364,13 @@ bool GainControlImpl::stream_is_saturated() const {
|
||||
}
|
||||
|
||||
int GainControlImpl::set_target_level_dbfs(int level) {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
if (level > 31 || level < 0) {
|
||||
return AudioProcessing::kBadParameterError;
|
||||
}
|
||||
|
||||
target_level_dbfs_ = level;
|
||||
{
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
target_level_dbfs_ = level;
|
||||
}
|
||||
return Configure();
|
||||
}
|
||||
|
||||
@ -333,12 +380,13 @@ int GainControlImpl::target_level_dbfs() const {
|
||||
}
|
||||
|
||||
int GainControlImpl::set_compression_gain_db(int gain) {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
if (gain < 0 || gain > 90) {
|
||||
return AudioProcessing::kBadParameterError;
|
||||
}
|
||||
|
||||
compression_gain_db_ = gain;
|
||||
{
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
compression_gain_db_ = gain;
|
||||
}
|
||||
return Configure();
|
||||
}
|
||||
|
||||
@ -348,8 +396,10 @@ int GainControlImpl::compression_gain_db() const {
|
||||
}
|
||||
|
||||
int GainControlImpl::enable_limiter(bool enable) {
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
limiter_enabled_ = enable;
|
||||
{
|
||||
rtc::CritScope cs(crit_capture_);
|
||||
limiter_enabled_ = enable;
|
||||
}
|
||||
return Configure();
|
||||
}
|
||||
|
||||
@ -358,26 +408,32 @@ bool GainControlImpl::is_limiter_enabled() const {
|
||||
return limiter_enabled_;
|
||||
}
|
||||
|
||||
int GainControlImpl::Initialize() {
|
||||
int err = ProcessingComponent::Initialize();
|
||||
if (err != AudioProcessing::kNoError || !is_component_enabled()) {
|
||||
return err;
|
||||
void GainControlImpl::Initialize() {
|
||||
rtc::CritScope cs_render(crit_render_);
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
int sample_rate_hz = apm_->proc_sample_rate_hz();
|
||||
gain_controllers_.resize(num_handles_required());
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
if (!gain_controller) {
|
||||
gain_controller.reset(new GainController());
|
||||
}
|
||||
gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_,
|
||||
mode_, sample_rate_hz, analog_capture_level_);
|
||||
}
|
||||
|
||||
Configure();
|
||||
|
||||
AllocateRenderQueue();
|
||||
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
const int n = num_handles();
|
||||
RTC_CHECK_GE(n, 0) << "Bad number of handles: " << n;
|
||||
|
||||
capture_levels_.assign(n, analog_capture_level_);
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
void GainControlImpl::AllocateRenderQueue() {
|
||||
const size_t new_render_queue_element_max_size =
|
||||
std::max<size_t>(static_cast<size_t>(1),
|
||||
kMaxAllowedValuesOfSamplesPerFrame * num_handles());
|
||||
const size_t new_render_queue_element_max_size = std::max<size_t>(
|
||||
static_cast<size_t>(1),
|
||||
kMaxAllowedValuesOfSamplesPerFrame * num_handles_required());
|
||||
|
||||
rtc::CritScope cs_render(crit_render_);
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
@ -398,26 +454,7 @@ void GainControlImpl::AllocateRenderQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
void* GainControlImpl::CreateHandle() const {
|
||||
return WebRtcAgc_Create();
|
||||
}
|
||||
|
||||
void GainControlImpl::DestroyHandle(void* handle) const {
|
||||
WebRtcAgc_Free(static_cast<Handle*>(handle));
|
||||
}
|
||||
|
||||
int GainControlImpl::InitializeHandle(void* handle) const {
|
||||
rtc::CritScope cs_render(crit_render_);
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
|
||||
return WebRtcAgc_Init(static_cast<Handle*>(handle),
|
||||
minimum_capture_level_,
|
||||
maximum_capture_level_,
|
||||
MapSetting(mode_),
|
||||
apm_->proc_sample_rate_hz());
|
||||
}
|
||||
|
||||
int GainControlImpl::ConfigureHandle(void* handle) const {
|
||||
int GainControlImpl::Configure() {
|
||||
rtc::CritScope cs_render(crit_render_);
|
||||
rtc::CritScope cs_capture(crit_capture_);
|
||||
WebRtcAgcConfig config;
|
||||
@ -430,18 +467,19 @@ int GainControlImpl::ConfigureHandle(void* handle) const {
|
||||
static_cast<int16_t>(compression_gain_db_);
|
||||
config.limiterEnable = limiter_enabled_;
|
||||
|
||||
return WebRtcAgc_set_config(static_cast<Handle*>(handle), config);
|
||||
int error = AudioProcessing::kNoError;
|
||||
for (auto& gain_controller : gain_controllers_) {
|
||||
const int handle_error =
|
||||
WebRtcAgc_set_config(gain_controller->state(), config);
|
||||
if (handle_error != AudioProcessing::kNoError) {
|
||||
error = handle_error;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
size_t GainControlImpl::num_handles_required() const {
|
||||
// Not locked as it only relies on APM public API which is threadsafe.
|
||||
return apm_->num_proc_channels();
|
||||
}
|
||||
|
||||
int GainControlImpl::GetHandleError(void* handle) const {
|
||||
// The AGC has no get_error() function.
|
||||
// (Despite listing errors in its interface...)
|
||||
assert(handle != NULL);
|
||||
return AudioProcessing::kUnspecifiedError;
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/common_audio/swap_queue.h"
|
||||
@ -24,20 +25,18 @@ namespace webrtc {
|
||||
|
||||
class AudioBuffer;
|
||||
|
||||
class GainControlImpl : public GainControl,
|
||||
public ProcessingComponent {
|
||||
class GainControlImpl : public GainControl {
|
||||
public:
|
||||
GainControlImpl(const AudioProcessing* apm,
|
||||
rtc::CriticalSection* crit_render,
|
||||
rtc::CriticalSection* crit_capture);
|
||||
virtual ~GainControlImpl();
|
||||
~GainControlImpl() override;
|
||||
|
||||
int ProcessRenderAudio(AudioBuffer* audio);
|
||||
int AnalyzeCaptureAudio(AudioBuffer* audio);
|
||||
int ProcessCaptureAudio(AudioBuffer* audio);
|
||||
|
||||
// ProcessingComponent implementation.
|
||||
int Initialize() override;
|
||||
void Initialize();
|
||||
|
||||
// GainControl implementation.
|
||||
bool is_enabled() const override;
|
||||
@ -49,6 +48,8 @@ class GainControlImpl : public GainControl,
|
||||
void ReadQueuedRenderData();
|
||||
|
||||
private:
|
||||
class GainController;
|
||||
|
||||
// GainControl implementation.
|
||||
int Enable(bool enable) override;
|
||||
int set_stream_analog_level(int level) override;
|
||||
@ -63,15 +64,10 @@ class GainControlImpl : public GainControl,
|
||||
int analog_level_maximum() const override;
|
||||
bool stream_is_saturated() const override;
|
||||
|
||||
// ProcessingComponent implementation.
|
||||
void* CreateHandle() const override;
|
||||
int InitializeHandle(void* handle) const override;
|
||||
int ConfigureHandle(void* handle) const override;
|
||||
void DestroyHandle(void* handle) const override;
|
||||
size_t num_handles_required() const override;
|
||||
int GetHandleError(void* handle) const override;
|
||||
size_t num_handles_required() const;
|
||||
|
||||
void AllocateRenderQueue();
|
||||
int Configure();
|
||||
|
||||
// Not guarded as its public API is thread safe.
|
||||
const AudioProcessing* apm_;
|
||||
@ -79,13 +75,14 @@ class GainControlImpl : public GainControl,
|
||||
rtc::CriticalSection* const crit_render_ ACQUIRED_BEFORE(crit_capture_);
|
||||
rtc::CriticalSection* const crit_capture_;
|
||||
|
||||
bool enabled_ = false;
|
||||
|
||||
Mode mode_ GUARDED_BY(crit_capture_);
|
||||
int minimum_capture_level_ GUARDED_BY(crit_capture_);
|
||||
int maximum_capture_level_ GUARDED_BY(crit_capture_);
|
||||
bool limiter_enabled_ GUARDED_BY(crit_capture_);
|
||||
int target_level_dbfs_ GUARDED_BY(crit_capture_);
|
||||
int compression_gain_db_ GUARDED_BY(crit_capture_);
|
||||
std::vector<int> capture_levels_ GUARDED_BY(crit_capture_);
|
||||
int analog_capture_level_ GUARDED_BY(crit_capture_);
|
||||
bool was_analog_level_set_ GUARDED_BY(crit_capture_);
|
||||
bool stream_is_saturated_ GUARDED_BY(crit_capture_);
|
||||
@ -99,6 +96,10 @@ class GainControlImpl : public GainControl,
|
||||
std::unique_ptr<
|
||||
SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>>
|
||||
render_signal_queue_;
|
||||
|
||||
std::vector<std::unique_ptr<GainController>> gain_controllers_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GainControlImpl);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user