Add multi-mic support for the noise suppression pre-processing effect
Change-Id: I7cf8d5657a25206e0a07e7e343635f7cf23e6f89
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index f3c038b..0a3298e 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -89,6 +89,7 @@
preproc_session_t *session; // session the effect is on
const preproc_ops_t *ops; // effect ops table
preproc_fx_handle_t engine; // handle on webRTC engine
+ uint32_t type; // subtype of effect
#ifdef DUAL_MIC_TEST
bool aux_channels_on; // support auxiliary channels
size_t cur_channel_config; // current auciliary channel configuration
@@ -559,6 +560,21 @@
ALOGV("NsInit");
webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
ns->set_level(kNsDefaultLevel);
+ webrtc::Config config;
+ std::vector<webrtc::Point> geometry;
+ // TODO(aluebs): Make the geometry settable.
+ geometry.push_back(webrtc::Point(-0.03f, 0.f, 0.f));
+ geometry.push_back(webrtc::Point(-0.01f, 0.f, 0.f));
+ geometry.push_back(webrtc::Point(0.01f, 0.f, 0.f));
+ geometry.push_back(webrtc::Point(0.03f, 0.f, 0.f));
+ // The geometry needs to be set with Beamforming enabled.
+ config.Set<webrtc::Beamforming>(
+ new webrtc::Beamforming(true, geometry));
+ effect->session->apm->SetExtraOptions(config);
+ config.Set<webrtc::Beamforming>(
+ new webrtc::Beamforming(false, geometry));
+ effect->session->apm->SetExtraOptions(config);
+ effect->type = NS_TYPE_SINGLE_CHANNEL;
return 0;
}
@@ -584,11 +600,35 @@
return status;
}
-int NsSetParameter (preproc_effect_t *effect __unused,
- void *pParam __unused,
- void *pValue __unused)
+int NsSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
{
int status = 0;
+ webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
+ uint32_t param = *(uint32_t *)pParam;
+ uint32_t value = *(uint32_t *)pValue;
+ switch(param) {
+ case NS_PARAM_LEVEL:
+ ns->set_level((webrtc::NoiseSuppression::Level)value);
+ ALOGV("NsSetParameter() level %d", value);
+ break;
+ case NS_PARAM_TYPE:
+ {
+ webrtc::Config config;
+ std::vector<webrtc::Point> geometry;
+ bool is_beamforming_enabled =
+ value == NS_TYPE_MULTI_CHANNEL && ns->is_enabled();
+ config.Set<webrtc::Beamforming>(
+ new webrtc::Beamforming(is_beamforming_enabled, geometry));
+ effect->session->apm->SetExtraOptions(config);
+ effect->type = value;
+ ALOGV("NsSetParameter() type %d", value);
+ break;
+ }
+ default:
+ ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
+ status = -EINVAL;
+ }
+
return status;
}
@@ -597,6 +637,12 @@
webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
ALOGV("NsEnable ns %p", ns);
ns->Enable(true);
+ if (effect->type == NS_TYPE_MULTI_CHANNEL) {
+ webrtc::Config config;
+ std::vector<webrtc::Point> geometry;
+ config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
+ effect->session->apm->SetExtraOptions(config);
+ }
}
void NsDisable(preproc_effect_t *effect)
@@ -604,6 +650,10 @@
ALOGV("NsDisable");
webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
ns->Enable(false);
+ webrtc::Config config;
+ std::vector<webrtc::Point> geometry;
+ config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry));
+ effect->session->apm->SetExtraOptions(config);
}
static const preproc_ops_t sNsOps = {
@@ -897,17 +947,6 @@
config->inputCfg.samplingRate, config->inputCfg.channels);
int status;
- // if at least one process is enabled, do not accept configuration changes
- if (session->enabledMsk) {
- if (session->samplingRate != config->inputCfg.samplingRate ||
- session->inChannelCount != inCnl ||
- session->outChannelCount != outCnl) {
- return -ENOSYS;
- } else {
- return 0;
- }
- }
-
// AEC implementation is limited to 16kHz
if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
session->apmSamplingRate = 32000;
@@ -1290,8 +1329,7 @@
}
session->framesIn = 0;
}
- session->procFrame->samples_per_channel_ =
- session->apmFrameCount * session->inChannelCount;
+ session->procFrame->samples_per_channel_ = session->apmFrameCount;
effect->session->apm->ProcessStream(session->procFrame);
@@ -1802,8 +1840,7 @@
}
session->framesRev = 0;
}
- session->revFrame->samples_per_channel_ =
- session->apmFrameCount * session->inChannelCount;
+ session->revFrame->samples_per_channel_ = session->apmFrameCount;
effect->session->apm->AnalyzeReverseStream(session->revFrame);
return 0;
} else {