1 /*
2  *  Copyright (c) 2011 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 "noise_suppression_impl.h"
12 
13 #include <cassert>
14 
15 #include "critical_section_wrapper.h"
16 #if defined(WEBRTC_NS_FLOAT)
17 #include "noise_suppression.h"
18 #elif defined(WEBRTC_NS_FIXED)
19 #include "noise_suppression_x.h"
20 #endif
21 
22 #include "audio_processing_impl.h"
23 #include "audio_buffer.h"
24 
25 namespace webrtc {
26 
27 #if defined(WEBRTC_NS_FLOAT)
28 typedef NsHandle Handle;
29 #elif defined(WEBRTC_NS_FIXED)
30 typedef NsxHandle Handle;
31 #endif
32 
33 namespace {
MapSetting(NoiseSuppression::Level level)34 int MapSetting(NoiseSuppression::Level level) {
35   switch (level) {
36     case NoiseSuppression::kLow:
37       return 0;
38     case NoiseSuppression::kModerate:
39       return 1;
40     case NoiseSuppression::kHigh:
41       return 2;
42     case NoiseSuppression::kVeryHigh:
43       return 3;
44     default:
45       return -1;
46   }
47 }
48 }  // namespace
49 
NoiseSuppressionImpl(const AudioProcessingImpl * apm)50 NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessingImpl* apm)
51   : ProcessingComponent(apm),
52     apm_(apm),
53     level_(kModerate) {}
54 
~NoiseSuppressionImpl()55 NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
56 
ProcessCaptureAudio(AudioBuffer * audio)57 int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
58   int err = apm_->kNoError;
59 
60   if (!is_component_enabled()) {
61     return apm_->kNoError;
62   }
63   assert(audio->samples_per_split_channel() <= 160);
64   assert(audio->num_channels() == num_handles());
65 
66   for (int i = 0; i < num_handles(); i++) {
67     Handle* my_handle = static_cast<Handle*>(handle(i));
68 #if defined(WEBRTC_NS_FLOAT)
69     err = WebRtcNs_Process(static_cast<Handle*>(handle(i)),
70                            audio->low_pass_split_data(i),
71                            audio->high_pass_split_data(i),
72                            audio->low_pass_split_data(i),
73                            audio->high_pass_split_data(i));
74 #elif defined(WEBRTC_NS_FIXED)
75     err = WebRtcNsx_Process(static_cast<Handle*>(handle(i)),
76                             audio->low_pass_split_data(i),
77                             audio->high_pass_split_data(i),
78                             audio->low_pass_split_data(i),
79                             audio->high_pass_split_data(i));
80 #endif
81 
82     if (err != apm_->kNoError) {
83       return GetHandleError(my_handle);
84     }
85   }
86 
87   return apm_->kNoError;
88 }
89 
Enable(bool enable)90 int NoiseSuppressionImpl::Enable(bool enable) {
91   CriticalSectionScoped crit_scoped(*apm_->crit());
92   return EnableComponent(enable);
93 }
94 
is_enabled() const95 bool NoiseSuppressionImpl::is_enabled() const {
96   return is_component_enabled();
97 }
98 
set_level(Level level)99 int NoiseSuppressionImpl::set_level(Level level) {
100   CriticalSectionScoped crit_scoped(*apm_->crit());
101   if (MapSetting(level) == -1) {
102     return apm_->kBadParameterError;
103   }
104 
105   level_ = level;
106   return Configure();
107 }
108 
level() const109 NoiseSuppression::Level NoiseSuppressionImpl::level() const {
110   return level_;
111 }
112 
get_version(char * version,int version_len_bytes) const113 int NoiseSuppressionImpl::get_version(char* version,
114                                       int version_len_bytes) const {
115 #if defined(WEBRTC_NS_FLOAT)
116   if (WebRtcNs_get_version(version, version_len_bytes) != 0)
117 #elif defined(WEBRTC_NS_FIXED)
118   if (WebRtcNsx_get_version(version, version_len_bytes) != 0)
119 #endif
120   {
121       return apm_->kBadParameterError;
122   }
123 
124   return apm_->kNoError;
125 }
126 
CreateHandle() const127 void* NoiseSuppressionImpl::CreateHandle() const {
128   Handle* handle = NULL;
129 #if defined(WEBRTC_NS_FLOAT)
130   if (WebRtcNs_Create(&handle) != apm_->kNoError)
131 #elif defined(WEBRTC_NS_FIXED)
132   if (WebRtcNsx_Create(&handle) != apm_->kNoError)
133 #endif
134   {
135     handle = NULL;
136   } else {
137     assert(handle != NULL);
138   }
139 
140   return handle;
141 }
142 
DestroyHandle(void * handle) const143 int NoiseSuppressionImpl::DestroyHandle(void* handle) const {
144 #if defined(WEBRTC_NS_FLOAT)
145   return WebRtcNs_Free(static_cast<Handle*>(handle));
146 #elif defined(WEBRTC_NS_FIXED)
147   return WebRtcNsx_Free(static_cast<Handle*>(handle));
148 #endif
149 }
150 
InitializeHandle(void * handle) const151 int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
152 #if defined(WEBRTC_NS_FLOAT)
153   return WebRtcNs_Init(static_cast<Handle*>(handle), apm_->sample_rate_hz());
154 #elif defined(WEBRTC_NS_FIXED)
155   return WebRtcNsx_Init(static_cast<Handle*>(handle), apm_->sample_rate_hz());
156 #endif
157 }
158 
ConfigureHandle(void * handle) const159 int NoiseSuppressionImpl::ConfigureHandle(void* handle) const {
160 #if defined(WEBRTC_NS_FLOAT)
161   return WebRtcNs_set_policy(static_cast<Handle*>(handle),
162                              MapSetting(level_));
163 #elif defined(WEBRTC_NS_FIXED)
164   return WebRtcNsx_set_policy(static_cast<Handle*>(handle),
165                               MapSetting(level_));
166 #endif
167 }
168 
num_handles_required() const169 int NoiseSuppressionImpl::num_handles_required() const {
170   return apm_->num_output_channels();
171 }
172 
GetHandleError(void * handle) const173 int NoiseSuppressionImpl::GetHandleError(void* handle) const {
174   // The NS has no get_error() function.
175   assert(handle != NULL);
176   return apm_->kUnspecifiedError;
177 }
178 }  // namespace webrtc
179 
180