Add PlayoutVolumeChange RuntimeSetting.

Add a PlayoutVolumeChange RuntimeSetting. Trigger an echo path change when the playout volume is changed.

Bug: webrtc:10608
Change-Id: I1e736b93c1865d08c7d2582f6fe00216c1e1f72e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135746
Reviewed-by: Per Åhgren <peah@webrtc.org>
Reviewed-by: Fredrik Hernqvist <fhernqvist@webrtc.org>
Commit-Queue: Fredrik Hernqvist <fhernqvist@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27913}
This commit is contained in:
Fredrik Hernqvist 2019-05-10 15:50:02 +02:00 committed by Commit Bot
parent eb9bf411f3
commit ca362855e1
8 changed files with 113 additions and 7 deletions

View File

@ -192,11 +192,18 @@ void AecDumpImpl::WriteRuntimeSetting(
// Runtime AGC1 compression gain is ignored.
// TODO(http://bugs.webrtc.org/10432): Store compression gain in aecdumps.
break;
case AudioProcessing::RuntimeSetting::Type::kCaptureFixedPostGain:
case AudioProcessing::RuntimeSetting::Type::kCaptureFixedPostGain: {
float x;
runtime_setting.GetFloat(&x);
setting->set_capture_fixed_post_gain(x);
break;
}
case AudioProcessing::RuntimeSetting::Type::kPlayoutVolumeChange: {
int x;
runtime_setting.GetInt(&x);
setting->set_playout_volume_change(x);
break;
}
case AudioProcessing::RuntimeSetting::Type::kNotSpecified:
RTC_NOTREACHED();
break;

View File

@ -853,6 +853,7 @@ void AudioProcessingImpl::SetRuntimeSetting(RuntimeSetting setting) {
case RuntimeSetting::Type::kCapturePreGain:
case RuntimeSetting::Type::kCaptureCompressionGain:
case RuntimeSetting::Type::kCaptureFixedPostGain:
case RuntimeSetting::Type::kPlayoutVolumeChange:
capture_runtime_settings_enqueuer_.Enqueue(setting);
return;
}
@ -998,6 +999,12 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
}
break;
}
case RuntimeSetting::Type::kPlayoutVolumeChange: {
int value;
setting.GetInt(&value);
capture_.playout_volume = value;
break;
}
case RuntimeSetting::Type::kCustomRenderProcessingRuntimeSetting:
RTC_NOTREACHED();
break;
@ -1023,6 +1030,7 @@ void AudioProcessingImpl::HandleRenderRuntimeSettings() {
case RuntimeSetting::Type::kCapturePreGain: // fall-through
case RuntimeSetting::Type::kCaptureCompressionGain: // fall-through
case RuntimeSetting::Type::kCaptureFixedPostGain: // fall-through
case RuntimeSetting::Type::kPlayoutVolumeChange: // fall-through
case RuntimeSetting::Type::kNotSpecified:
RTC_NOTREACHED();
break;
@ -1291,6 +1299,14 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
capture_.prev_pre_amp_gain >= 0.f);
capture_.prev_pre_amp_gain = pre_amp_gain;
}
// Detect volume change.
capture_.echo_path_gain_change =
capture_.echo_path_gain_change ||
(capture_.prev_playout_volume != capture_.playout_volume &&
capture_.prev_playout_volume >= 0);
capture_.prev_playout_volume = capture_.playout_volume;
private_submodules_->echo_controller->AnalyzeCapture(capture_buffer);
}
@ -2087,7 +2103,9 @@ AudioProcessingImpl::ApmCaptureState::ApmCaptureState(
split_rate(kSampleRate16kHz),
echo_path_gain_change(false),
prev_analog_mic_level(-1),
prev_pre_amp_gain(-1.f) {}
prev_pre_amp_gain(-1.f),
playout_volume(-1),
prev_playout_volume(-1) {}
AudioProcessingImpl::ApmCaptureState::~ApmCaptureState() = default;

View File

@ -398,6 +398,8 @@ class AudioProcessingImpl : public AudioProcessing {
bool echo_path_gain_change;
int prev_analog_mic_level;
float prev_pre_amp_gain;
int playout_volume;
int prev_playout_volume;
AudioProcessingStats stats;
} capture_ RTC_GUARDED_BY(crit_capture_);

View File

@ -296,6 +296,59 @@ TEST(AudioProcessingImplTest,
apm->ProcessStream(&frame);
}
TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) {
// Tests that the echo controller observes an echo path gain change when a
// playout volume change is reported.
auto echo_control_factory = absl::make_unique<MockEchoControlFactory>();
const auto* echo_control_factory_ptr = echo_control_factory.get();
std::unique_ptr<AudioProcessing> apm(
AudioProcessingBuilder()
.SetEchoControlFactory(std::move(echo_control_factory))
.Create());
apm->gain_control()->Enable(false); // Disable AGC.
apm->gain_control()->set_mode(GainControl::Mode::kFixedDigital);
AudioFrame frame;
constexpr int16_t kAudioLevel = 10000;
constexpr size_t kSampleRateHz = 48000;
constexpr size_t kNumChannels = 2;
InitializeAudioFrame(kSampleRateHz, kNumChannels, &frame);
FillFixedFrame(kAudioLevel, &frame);
MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1);
EXPECT_CALL(*echo_control_mock,
ProcessCapture(NotNull(), /*echo_path_change=*/false))
.Times(1);
apm->ProcessStream(&frame);
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1);
EXPECT_CALL(*echo_control_mock,
ProcessCapture(NotNull(), /*echo_path_change=*/false))
.Times(1);
apm->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
apm->ProcessStream(&frame);
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1);
EXPECT_CALL(*echo_control_mock,
ProcessCapture(NotNull(), /*echo_path_change=*/false))
.Times(1);
apm->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
apm->ProcessStream(&frame);
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1);
EXPECT_CALL(*echo_control_mock,
ProcessCapture(NotNull(), /*echo_path_change=*/true))
.Times(1);
apm->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(100));
apm->ProcessStream(&frame);
}
TEST(AudioProcessingImplTest, RenderPreProcessorBeforeEchoDetector) {
// Make sure that signal changes caused by a render pre-processing sub-module
// take place before any echo detector analysis.

View File

@ -84,6 +84,7 @@ message RuntimeSetting {
optional float capture_pre_gain = 1;
optional float custom_render_processing_setting = 2;
optional float capture_fixed_post_gain = 3;
optional int32 playout_volume_change = 4;
}
message Event {

View File

@ -392,6 +392,7 @@ class AudioProcessing : public rtc::RefCountInterface {
kCapturePreGain,
kCaptureCompressionGain,
kCaptureFixedPostGain,
kPlayoutVolumeChange,
kCustomRenderProcessingRuntimeSetting
};
@ -419,6 +420,10 @@ class AudioProcessing : public rtc::RefCountInterface {
return {Type::kCaptureFixedPostGain, gain_db};
}
static RuntimeSetting CreatePlayoutVolumeChange(int volume) {
return {Type::kPlayoutVolumeChange, volume};
}
static RuntimeSetting CreateCustomRenderSetting(float payload) {
return {Type::kCustomRenderProcessingRuntimeSetting, payload};
}
@ -426,13 +431,24 @@ class AudioProcessing : public rtc::RefCountInterface {
Type type() const { return type_; }
void GetFloat(float* value) const {
RTC_DCHECK(value);
*value = value_;
*value = value_.float_value;
}
void GetInt(int* value) const {
RTC_DCHECK(value);
*value = value_.int_value;
}
private:
RuntimeSetting(Type id, float value) : type_(id), value_(value) {}
RuntimeSetting(Type id, int value) : type_(id), value_(value) {}
Type type_;
float value_;
union U {
U() {}
U(int value) : int_value(value) {}
U(float value) : float_value(value) {}
float float_value;
int int_value;
} value_;
};
~AudioProcessing() override {}

View File

@ -584,6 +584,10 @@ void AecDumpBasedSimulator::HandleMessage(
AudioProcessing::RuntimeSetting::CreateCaptureFixedPostGain(
msg.capture_fixed_post_gain()));
}
} else if (msg.has_playout_volume_change()) {
ap_->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(
msg.playout_volume_change()));
}
}

View File

@ -18,10 +18,11 @@ void ReplayRuntimeSetting(AudioProcessing* apm,
const webrtc::audioproc::RuntimeSetting& setting) {
RTC_CHECK(apm);
// TODO(bugs.webrtc.org/9138): Add ability to handle different types
// of settings. Currently only CapturePreGain and CaptureFixedPostGain are
// supported.
// of settings. Currently CapturePreGain, CaptureFixedPostGain and
// PlayoutVolumeChange are supported.
RTC_CHECK(setting.has_capture_pre_gain() ||
setting.has_capture_fixed_post_gain());
setting.has_capture_fixed_post_gain() ||
setting.has_playout_volume_change());
if (setting.has_capture_pre_gain()) {
apm->SetRuntimeSetting(
@ -31,6 +32,10 @@ void ReplayRuntimeSetting(AudioProcessing* apm,
apm->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreateCaptureFixedPostGain(
setting.capture_fixed_post_gain()));
} else if (setting.has_playout_volume_change()) {
apm->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(
setting.playout_volume_change()));
}
}
} // namespace webrtc