• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
20 typedef 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
27 typedef NsxHandle NsState;
28 #endif
29 
30 namespace webrtc {
31 class NoiseSuppressionImpl::Suppressor {
32  public:
Suppressor(int sample_rate_hz)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   }
~Suppressor()39   ~Suppressor() {
40     NS_FREE(state_);
41   }
state()42   NsState* state() { return state_; }
43  private:
44   NsState* state_ = nullptr;
45   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Suppressor);
46 };
47 
NoiseSuppressionImpl(rtc::CriticalSection * crit)48 NoiseSuppressionImpl::NoiseSuppressionImpl(rtc::CriticalSection* crit)
49     : crit_(crit) {
50   RTC_DCHECK(crit);
51 }
52 
~NoiseSuppressionImpl()53 NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
54 
Initialize(size_t channels,int sample_rate_hz)55 void NoiseSuppressionImpl::Initialize(size_t channels, int sample_rate_hz) {
56   rtc::CritScope cs(crit_);
57   channels_ = channels;
58   sample_rate_hz_ = sample_rate_hz;
59   std::vector<rtc::scoped_ptr<Suppressor>> new_suppressors;
60   if (enabled_) {
61     new_suppressors.resize(channels);
62     for (size_t i = 0; i < channels; i++) {
63       new_suppressors[i].reset(new Suppressor(sample_rate_hz));
64     }
65   }
66   suppressors_.swap(new_suppressors);
67   set_level(level_);
68 }
69 
AnalyzeCaptureAudio(AudioBuffer * audio)70 void NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
71   RTC_DCHECK(audio);
72 #if defined(WEBRTC_NS_FLOAT)
73   rtc::CritScope cs(crit_);
74   if (!enabled_) {
75     return;
76   }
77 
78   RTC_DCHECK_GE(160u, audio->num_frames_per_band());
79   RTC_DCHECK_EQ(suppressors_.size(), audio->num_channels());
80   for (size_t i = 0; i < suppressors_.size(); i++) {
81     WebRtcNs_Analyze(suppressors_[i]->state(),
82                      audio->split_bands_const_f(i)[kBand0To8kHz]);
83   }
84 #endif
85 }
86 
ProcessCaptureAudio(AudioBuffer * audio)87 void NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
88   RTC_DCHECK(audio);
89   rtc::CritScope cs(crit_);
90   if (!enabled_) {
91     return;
92   }
93 
94   RTC_DCHECK_GE(160u, audio->num_frames_per_band());
95   RTC_DCHECK_EQ(suppressors_.size(), audio->num_channels());
96   for (size_t i = 0; i < suppressors_.size(); i++) {
97 #if defined(WEBRTC_NS_FLOAT)
98     WebRtcNs_Process(suppressors_[i]->state(),
99                      audio->split_bands_const_f(i),
100                      audio->num_bands(),
101                      audio->split_bands_f(i));
102 #elif defined(WEBRTC_NS_FIXED)
103     WebRtcNsx_Process(suppressors_[i]->state(),
104                       audio->split_bands_const(i),
105                       audio->num_bands(),
106                       audio->split_bands(i));
107 #endif
108   }
109 }
110 
Enable(bool enable)111 int NoiseSuppressionImpl::Enable(bool enable) {
112   rtc::CritScope cs(crit_);
113   if (enabled_ != enable) {
114     enabled_ = enable;
115     Initialize(channels_, sample_rate_hz_);
116   }
117   return AudioProcessing::kNoError;
118 }
119 
is_enabled() const120 bool NoiseSuppressionImpl::is_enabled() const {
121   rtc::CritScope cs(crit_);
122   return enabled_;
123 }
124 
set_level(Level level)125 int NoiseSuppressionImpl::set_level(Level level) {
126   int policy = 1;
127   switch (level) {
128     case NoiseSuppression::kLow:
129       policy = 0;
130       break;
131     case NoiseSuppression::kModerate:
132       policy = 1;
133       break;
134     case NoiseSuppression::kHigh:
135       policy = 2;
136       break;
137     case NoiseSuppression::kVeryHigh:
138       policy = 3;
139       break;
140     default:
141       RTC_NOTREACHED();
142   }
143   rtc::CritScope cs(crit_);
144   level_ = level;
145   for (auto& suppressor : suppressors_) {
146     int error = NS_SET_POLICY(suppressor->state(), policy);
147     RTC_DCHECK_EQ(0, error);
148   }
149   return AudioProcessing::kNoError;
150 }
151 
level() const152 NoiseSuppression::Level NoiseSuppressionImpl::level() const {
153   rtc::CritScope cs(crit_);
154   return level_;
155 }
156 
speech_probability() const157 float NoiseSuppressionImpl::speech_probability() const {
158   rtc::CritScope cs(crit_);
159 #if defined(WEBRTC_NS_FLOAT)
160   float probability_average = 0.0f;
161   for (auto& suppressor : suppressors_) {
162     probability_average +=
163         WebRtcNs_prior_speech_probability(suppressor->state());
164   }
165   if (!suppressors_.empty()) {
166     probability_average /= suppressors_.size();
167   }
168   return probability_average;
169 #elif defined(WEBRTC_NS_FIXED)
170   // TODO(peah): Returning error code as a float! Remove this.
171   // Currently not available for the fixed point implementation.
172   return AudioProcessing::kUnsupportedFunctionError;
173 #endif
174 }
175 }  // namespace webrtc
176