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:
parent
eb9bf411f3
commit
ca362855e1
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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_);
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user