noise_suppression_impl.cc revision 5e465c33cac54ed5265f18413f7afc44aae2dfca
1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/modules/audio_processing/noise_suppression_impl.h" 12 13#include "webrtc/modules/audio_processing/audio_buffer.h" 14#if defined(WEBRTC_NS_FLOAT) 15#include "webrtc/modules/audio_processing/ns/noise_suppression.h" 16#define NS_CREATE WebRtcNs_Create 17#define NS_FREE WebRtcNs_Free 18#define NS_INIT WebRtcNs_Init 19#define NS_SET_POLICY WebRtcNs_set_policy 20typedef NsHandle NsState; 21#elif defined(WEBRTC_NS_FIXED) 22#include "webrtc/modules/audio_processing/ns/noise_suppression_x.h" 23#define NS_CREATE WebRtcNsx_Create 24#define NS_FREE WebRtcNsx_Free 25#define NS_INIT WebRtcNsx_Init 26#define NS_SET_POLICY WebRtcNsx_set_policy 27typedef NsxHandle NsState; 28#endif 29 30namespace webrtc { 31class NoiseSuppressionImpl::Suppressor { 32 public: 33 explicit Suppressor(int sample_rate_hz) { 34 state_ = NS_CREATE(); 35 RTC_CHECK(state_); 36 int error = NS_INIT(state_, sample_rate_hz); 37 RTC_DCHECK_EQ(0, error); 38 } 39 ~Suppressor() { 40 NS_FREE(state_); 41 } 42 NsState* state() { return state_; } 43 private: 44 NsState* state_ = nullptr; 45 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Suppressor); 46}; 47 48NoiseSuppressionImpl::NoiseSuppressionImpl(rtc::CriticalSection* crit) 49 : crit_(crit) { 50 RTC_DCHECK(crit); 51} 52 53NoiseSuppressionImpl::~NoiseSuppressionImpl() {} 54 55void NoiseSuppressionImpl::Initialize(int channels, int sample_rate_hz) { 56 RTC_DCHECK_LE(0, channels); 57 std::vector<rtc::scoped_ptr<Suppressor>> new_suppressors(channels); 58 for (int i = 0; i < channels; i++) { 59 new_suppressors[i].reset(new Suppressor(sample_rate_hz)); 60 } 61 rtc::CritScope cs(crit_); 62 suppressors_.swap(new_suppressors); 63 set_level(level_); 64} 65 66int NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { 67 RTC_DCHECK(audio); 68#if defined(WEBRTC_NS_FLOAT) 69 rtc::CritScope cs(crit_); 70 if (!enabled_) { 71 return AudioProcessing::kNoError; 72 } 73 74 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 75 RTC_DCHECK_EQ(suppressors_.size(), 76 static_cast<size_t>(audio->num_channels())); 77 for (size_t i = 0; i < suppressors_.size(); i++) { 78 WebRtcNs_Analyze(suppressors_[i]->state(), 79 audio->split_bands_const_f(i)[kBand0To8kHz]); 80 } 81#endif 82 return AudioProcessing::kNoError; 83} 84 85int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) { 86 RTC_DCHECK(audio); 87 rtc::CritScope cs(crit_); 88 if (!enabled_) { 89 return AudioProcessing::kNoError; 90 } 91 92 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 93 RTC_DCHECK_EQ(suppressors_.size(), 94 static_cast<size_t>(audio->num_channels())); 95 for (size_t i = 0; i < suppressors_.size(); i++) { 96#if defined(WEBRTC_NS_FLOAT) 97 WebRtcNs_Process(suppressors_[i]->state(), 98 audio->split_bands_const_f(i), 99 audio->num_bands(), 100 audio->split_bands_f(i)); 101#elif defined(WEBRTC_NS_FIXED) 102 WebRtcNsx_Process(suppressors_[i]->state(), 103 audio->split_bands_const(i), 104 audio->num_bands(), 105 audio->split_bands(i)); 106#endif 107 } 108 return AudioProcessing::kNoError; 109} 110 111int NoiseSuppressionImpl::Enable(bool enable) { 112 rtc::CritScope cs(crit_); 113 enabled_ = enable; 114 return AudioProcessing::kNoError; 115} 116 117bool NoiseSuppressionImpl::is_enabled() const { 118 rtc::CritScope cs(crit_); 119 return enabled_; 120} 121 122int NoiseSuppressionImpl::set_level(Level level) { 123 rtc::CritScope cs(crit_); 124 int policy = 1; 125 switch (level) { 126 case NoiseSuppression::kLow: 127 policy = 0; 128 break; 129 case NoiseSuppression::kModerate: 130 policy = 1; 131 break; 132 case NoiseSuppression::kHigh: 133 policy = 2; 134 break; 135 case NoiseSuppression::kVeryHigh: 136 policy = 3; 137 break; 138 default: 139 RTC_NOTREACHED(); 140 } 141 level_ = level; 142 for (auto& suppressor : suppressors_) { 143 int error = NS_SET_POLICY(suppressor->state(), policy); 144 RTC_DCHECK_EQ(0, error); 145 } 146 return AudioProcessing::kNoError; 147} 148 149NoiseSuppression::Level NoiseSuppressionImpl::level() const { 150 rtc::CritScope cs(crit_); 151 return level_; 152} 153 154float NoiseSuppressionImpl::speech_probability() const { 155 rtc::CritScope cs(crit_); 156#if defined(WEBRTC_NS_FLOAT) 157 float probability_average = 0.0f; 158 for (auto& suppressor : suppressors_) { 159 probability_average += 160 WebRtcNs_prior_speech_probability(suppressor->state()); 161 } 162 if (suppressors_.size() > 0) { 163 probability_average /= suppressors_.size(); 164 } 165 return probability_average; 166#elif defined(WEBRTC_NS_FIXED) 167 // TODO(peah): Returning error code as a float! Remove this. 168 // Currently not available for the fixed point implementation. 169 return AudioProcessing::kUnsupportedFunctionError; 170#endif 171} 172} // namespace webrtc 173