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 |