| Index: webrtc/modules/audio_processing/noise_suppression_impl.cc
|
| diff --git a/webrtc/modules/audio_processing/noise_suppression_impl.cc b/webrtc/modules/audio_processing/noise_suppression_impl.cc
|
| index 837585fbd70c9d78fa6cef476b16579d52a25ec7..d4f8bbb60c234360df42c54dc188a058c2227fb9 100644
|
| --- a/webrtc/modules/audio_processing/noise_suppression_impl.cc
|
| +++ b/webrtc/modules/audio_processing/noise_suppression_impl.cc
|
| @@ -10,84 +10,96 @@
|
|
|
| #include "webrtc/modules/audio_processing/noise_suppression_impl.h"
|
|
|
| -#include <assert.h>
|
| -
|
| #include "webrtc/modules/audio_processing/audio_buffer.h"
|
| #if defined(WEBRTC_NS_FLOAT)
|
| #include "webrtc/modules/audio_processing/ns/noise_suppression.h"
|
| +#define NS_CREATE WebRtcNs_Create
|
| +#define NS_FREE WebRtcNs_Free
|
| +#define NS_INIT WebRtcNs_Init
|
| +#define NS_SET_POLICY WebRtcNs_set_policy
|
| +typedef NsHandle NsState;
|
| #elif defined(WEBRTC_NS_FIXED)
|
| #include "webrtc/modules/audio_processing/ns/noise_suppression_x.h"
|
| +#define NS_CREATE WebRtcNsx_Create
|
| +#define NS_FREE WebRtcNsx_Free
|
| +#define NS_INIT WebRtcNsx_Init
|
| +#define NS_SET_POLICY WebRtcNsx_set_policy
|
| +typedef NsxHandle NsState;
|
| #endif
|
|
|
| -
|
| namespace webrtc {
|
| -
|
| -#if defined(WEBRTC_NS_FLOAT)
|
| -typedef NsHandle Handle;
|
| -#elif defined(WEBRTC_NS_FIXED)
|
| -typedef NsxHandle Handle;
|
| -#endif
|
| -
|
| -namespace {
|
| -int MapSetting(NoiseSuppression::Level level) {
|
| - switch (level) {
|
| - case NoiseSuppression::kLow:
|
| - return 0;
|
| - case NoiseSuppression::kModerate:
|
| - return 1;
|
| - case NoiseSuppression::kHigh:
|
| - return 2;
|
| - case NoiseSuppression::kVeryHigh:
|
| - return 3;
|
| +class NoiseSuppressionImpl::Suppressor {
|
| + public:
|
| + explicit Suppressor(int sample_rate_hz) {
|
| + state_ = NS_CREATE();
|
| + RTC_CHECK(state_);
|
| + int error = NS_INIT(state_, sample_rate_hz);
|
| + RTC_DCHECK_EQ(0, error);
|
| }
|
| - assert(false);
|
| - return -1;
|
| -}
|
| -} // namespace
|
| -
|
| -NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm,
|
| - rtc::CriticalSection* crit)
|
| - : ProcessingComponent(), apm_(apm), crit_(crit), level_(kModerate) {
|
| - RTC_DCHECK(apm);
|
| + ~Suppressor() {
|
| + NS_FREE(state_);
|
| + }
|
| + NsState* state() { return state_; }
|
| + private:
|
| + NsState* state_ = nullptr;
|
| + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Suppressor);
|
| +};
|
| +
|
| +NoiseSuppressionImpl::NoiseSuppressionImpl(rtc::CriticalSection* crit)
|
| + : crit_(crit) {
|
| RTC_DCHECK(crit);
|
| }
|
|
|
| NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
|
|
|
| +void NoiseSuppressionImpl::Initialize(int channels, int sample_rate_hz) {
|
| + RTC_DCHECK_LE(0, channels);
|
| + std::vector<rtc::scoped_ptr<Suppressor>> new_suppressors(channels);
|
| + for (int i = 0; i < channels; i++) {
|
| + new_suppressors[i].reset(new Suppressor(sample_rate_hz));
|
| + }
|
| + rtc::CritScope cs(crit_);
|
| + suppressors_.swap(new_suppressors);
|
| + set_level(level_);
|
| +}
|
| +
|
| int NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
|
| + RTC_DCHECK(audio);
|
| #if defined(WEBRTC_NS_FLOAT)
|
| - if (!is_component_enabled()) {
|
| + rtc::CritScope cs(crit_);
|
| + if (!enabled_) {
|
| return AudioProcessing::kNoError;
|
| }
|
| - assert(audio->num_frames_per_band() <= 160);
|
| - assert(audio->num_channels() == num_handles());
|
| -
|
| - for (int i = 0; i < num_handles(); ++i) {
|
| - Handle* my_handle = static_cast<Handle*>(handle(i));
|
|
|
| - WebRtcNs_Analyze(my_handle, audio->split_bands_const_f(i)[kBand0To8kHz]);
|
| + RTC_DCHECK_GE(160u, audio->num_frames_per_band());
|
| + RTC_DCHECK_EQ(suppressors_.size(),
|
| + static_cast<size_t>(audio->num_channels()));
|
| + for (size_t i = 0; i < suppressors_.size(); i++) {
|
| + WebRtcNs_Analyze(suppressors_[i]->state(),
|
| + audio->split_bands_const_f(i)[kBand0To8kHz]);
|
| }
|
| #endif
|
| return AudioProcessing::kNoError;
|
| }
|
|
|
| int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
|
| + RTC_DCHECK(audio);
|
| rtc::CritScope cs(crit_);
|
| - if (!is_component_enabled()) {
|
| + if (!enabled_) {
|
| return AudioProcessing::kNoError;
|
| }
|
| - assert(audio->num_frames_per_band() <= 160);
|
| - assert(audio->num_channels() == num_handles());
|
|
|
| - for (int i = 0; i < num_handles(); ++i) {
|
| - Handle* my_handle = static_cast<Handle*>(handle(i));
|
| + RTC_DCHECK_GE(160u, audio->num_frames_per_band());
|
| + RTC_DCHECK_EQ(suppressors_.size(),
|
| + static_cast<size_t>(audio->num_channels()));
|
| + for (size_t i = 0; i < suppressors_.size(); i++) {
|
| #if defined(WEBRTC_NS_FLOAT)
|
| - WebRtcNs_Process(my_handle,
|
| + WebRtcNs_Process(suppressors_[i]->state(),
|
| audio->split_bands_const_f(i),
|
| audio->num_bands(),
|
| audio->split_bands_f(i));
|
| #elif defined(WEBRTC_NS_FIXED)
|
| - WebRtcNsx_Process(my_handle,
|
| + WebRtcNsx_Process(suppressors_[i]->state(),
|
| audio->split_bands_const(i),
|
| audio->num_bands(),
|
| audio->split_bands(i));
|
| @@ -98,22 +110,40 @@ int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
|
|
|
| int NoiseSuppressionImpl::Enable(bool enable) {
|
| rtc::CritScope cs(crit_);
|
| - return EnableComponent(enable);
|
| + enabled_ = enable;
|
| + return AudioProcessing::kNoError;
|
| }
|
|
|
| bool NoiseSuppressionImpl::is_enabled() const {
|
| rtc::CritScope cs(crit_);
|
| - return is_component_enabled();
|
| + return enabled_;
|
| }
|
|
|
| int NoiseSuppressionImpl::set_level(Level level) {
|
| rtc::CritScope cs(crit_);
|
| - if (MapSetting(level) == -1) {
|
| - return AudioProcessing::kBadParameterError;
|
| + int policy = 1;
|
| + switch (level) {
|
| + case NoiseSuppression::kLow:
|
| + policy = 0;
|
| + break;
|
| + case NoiseSuppression::kModerate:
|
| + policy = 1;
|
| + break;
|
| + case NoiseSuppression::kHigh:
|
| + policy = 2;
|
| + break;
|
| + case NoiseSuppression::kVeryHigh:
|
| + policy = 3;
|
| + break;
|
| + default:
|
| + RTC_NOTREACHED();
|
| }
|
| -
|
| level_ = level;
|
| - return Configure();
|
| + for (auto& suppressor : suppressors_) {
|
| + int error = NS_SET_POLICY(suppressor->state(), policy);
|
| + RTC_DCHECK_EQ(0, error);
|
| + }
|
| + return AudioProcessing::kNoError;
|
| }
|
|
|
| NoiseSuppression::Level NoiseSuppressionImpl::level() const {
|
| @@ -125,61 +155,18 @@ float NoiseSuppressionImpl::speech_probability() const {
|
| rtc::CritScope cs(crit_);
|
| #if defined(WEBRTC_NS_FLOAT)
|
| float probability_average = 0.0f;
|
| - for (int i = 0; i < num_handles(); i++) {
|
| - Handle* my_handle = static_cast<Handle*>(handle(i));
|
| - probability_average += WebRtcNs_prior_speech_probability(my_handle);
|
| + for (auto& suppressor : suppressors_) {
|
| + probability_average +=
|
| + WebRtcNs_prior_speech_probability(suppressor->state());
|
| }
|
| - return probability_average / num_handles();
|
| + if (suppressors_.size() > 0) {
|
| + probability_average /= suppressors_.size();
|
| + }
|
| + return probability_average;
|
| #elif defined(WEBRTC_NS_FIXED)
|
| + // TODO(peah): Returning error code as a float! Remove this.
|
| // Currently not available for the fixed point implementation.
|
| return AudioProcessing::kUnsupportedFunctionError;
|
| #endif
|
| }
|
| -
|
| -void* NoiseSuppressionImpl::CreateHandle() const {
|
| -#if defined(WEBRTC_NS_FLOAT)
|
| - return WebRtcNs_Create();
|
| -#elif defined(WEBRTC_NS_FIXED)
|
| - return WebRtcNsx_Create();
|
| -#endif
|
| -}
|
| -
|
| -void NoiseSuppressionImpl::DestroyHandle(void* handle) const {
|
| -#if defined(WEBRTC_NS_FLOAT)
|
| - WebRtcNs_Free(static_cast<Handle*>(handle));
|
| -#elif defined(WEBRTC_NS_FIXED)
|
| - WebRtcNsx_Free(static_cast<Handle*>(handle));
|
| -#endif
|
| -}
|
| -
|
| -int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
|
| -#if defined(WEBRTC_NS_FLOAT)
|
| - return WebRtcNs_Init(static_cast<Handle*>(handle),
|
| - apm_->proc_sample_rate_hz());
|
| -#elif defined(WEBRTC_NS_FIXED)
|
| - return WebRtcNsx_Init(static_cast<Handle*>(handle),
|
| - apm_->proc_sample_rate_hz());
|
| -#endif
|
| -}
|
| -
|
| -int NoiseSuppressionImpl::ConfigureHandle(void* handle) const {
|
| - rtc::CritScope cs(crit_);
|
| -#if defined(WEBRTC_NS_FLOAT)
|
| - return WebRtcNs_set_policy(static_cast<Handle*>(handle),
|
| - MapSetting(level_));
|
| -#elif defined(WEBRTC_NS_FIXED)
|
| - return WebRtcNsx_set_policy(static_cast<Handle*>(handle),
|
| - MapSetting(level_));
|
| -#endif
|
| -}
|
| -
|
| -int NoiseSuppressionImpl::num_handles_required() const {
|
| - return apm_->num_output_channels();
|
| -}
|
| -
|
| -int NoiseSuppressionImpl::GetHandleError(void* handle) const {
|
| - // The NS has no get_error() function.
|
| - assert(handle != NULL);
|
| - return AudioProcessing::kUnspecifiedError;
|
| -}
|
| } // namespace webrtc
|
|
|