noise_suppression_impl.cc revision fda2c2e810a815d98fe8b03e8c6687d14227b3ff
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 <assert.h>
14
15#include "webrtc/modules/audio_processing/audio_buffer.h"
16#if defined(WEBRTC_NS_FLOAT)
17#include "webrtc/modules/audio_processing/ns/include/noise_suppression.h"
18#elif defined(WEBRTC_NS_FIXED)
19#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h"
20#endif
21#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
22
23
24namespace webrtc {
25
26#if defined(WEBRTC_NS_FLOAT)
27typedef NsHandle Handle;
28#elif defined(WEBRTC_NS_FIXED)
29typedef NsxHandle Handle;
30#endif
31
32namespace {
33int MapSetting(NoiseSuppression::Level level) {
34  switch (level) {
35    case NoiseSuppression::kLow:
36      return 0;
37    case NoiseSuppression::kModerate:
38      return 1;
39    case NoiseSuppression::kHigh:
40      return 2;
41    case NoiseSuppression::kVeryHigh:
42      return 3;
43  }
44  assert(false);
45  return -1;
46}
47}  // namespace
48
49NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm,
50                                           CriticalSectionWrapper* crit)
51  : ProcessingComponent(),
52    apm_(apm),
53    crit_(crit),
54    level_(kModerate) {}
55
56NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
57
58int NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
59#if defined(WEBRTC_NS_FLOAT)
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
69    int err = WebRtcNs_Analyze(my_handle,
70                               audio->low_pass_split_data_f(i));
71    if (err != apm_->kNoError) {
72      return GetHandleError(my_handle);
73    }
74  }
75#endif
76  return apm_->kNoError;
77}
78
79int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
80  int err = apm_->kNoError;
81
82  if (!is_component_enabled()) {
83    return apm_->kNoError;
84  }
85  assert(audio->samples_per_split_channel() <= 160);
86  assert(audio->num_channels() == num_handles());
87
88  for (int i = 0; i < num_handles(); ++i) {
89    Handle* my_handle = static_cast<Handle*>(handle(i));
90#if defined(WEBRTC_NS_FLOAT)
91    err = WebRtcNs_Process(my_handle,
92                           audio->low_pass_split_data_f(i),
93                           audio->high_pass_split_data_f(i),
94                           audio->low_pass_split_data_f(i),
95                           audio->high_pass_split_data_f(i));
96#elif defined(WEBRTC_NS_FIXED)
97    err = WebRtcNsx_Process(my_handle,
98                            audio->low_pass_split_data(i),
99                            audio->high_pass_split_data(i),
100                            audio->low_pass_split_data(i),
101                            audio->high_pass_split_data(i));
102#endif
103
104    if (err != apm_->kNoError) {
105      return GetHandleError(my_handle);
106    }
107  }
108
109  return apm_->kNoError;
110}
111
112int NoiseSuppressionImpl::Enable(bool enable) {
113  CriticalSectionScoped crit_scoped(crit_);
114  return EnableComponent(enable);
115}
116
117bool NoiseSuppressionImpl::is_enabled() const {
118  return is_component_enabled();
119}
120
121int NoiseSuppressionImpl::set_level(Level level) {
122  CriticalSectionScoped crit_scoped(crit_);
123  if (MapSetting(level) == -1) {
124    return apm_->kBadParameterError;
125  }
126
127  level_ = level;
128  return Configure();
129}
130
131NoiseSuppression::Level NoiseSuppressionImpl::level() const {
132  return level_;
133}
134
135float NoiseSuppressionImpl::speech_probability() const {
136#if defined(WEBRTC_NS_FLOAT)
137  float probability_average = 0.0f;
138  for (int i = 0; i < num_handles(); i++) {
139    Handle* my_handle = static_cast<Handle*>(handle(i));
140    probability_average += WebRtcNs_prior_speech_probability(my_handle);
141  }
142  return probability_average / num_handles();
143#elif defined(WEBRTC_NS_FIXED)
144  // Currently not available for the fixed point implementation.
145  return apm_->kUnsupportedFunctionError;
146#endif
147}
148
149void* NoiseSuppressionImpl::CreateHandle() const {
150  Handle* handle = NULL;
151#if defined(WEBRTC_NS_FLOAT)
152  if (WebRtcNs_Create(&handle) != apm_->kNoError)
153#elif defined(WEBRTC_NS_FIXED)
154  if (WebRtcNsx_Create(&handle) != apm_->kNoError)
155#endif
156  {
157    handle = NULL;
158  } else {
159    assert(handle != NULL);
160  }
161
162  return handle;
163}
164
165void NoiseSuppressionImpl::DestroyHandle(void* handle) const {
166#if defined(WEBRTC_NS_FLOAT)
167  WebRtcNs_Free(static_cast<Handle*>(handle));
168#elif defined(WEBRTC_NS_FIXED)
169  WebRtcNsx_Free(static_cast<Handle*>(handle));
170#endif
171}
172
173int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
174#if defined(WEBRTC_NS_FLOAT)
175  return WebRtcNs_Init(static_cast<Handle*>(handle),
176                       apm_->proc_sample_rate_hz());
177#elif defined(WEBRTC_NS_FIXED)
178  return WebRtcNsx_Init(static_cast<Handle*>(handle),
179                        apm_->proc_sample_rate_hz());
180#endif
181}
182
183int NoiseSuppressionImpl::ConfigureHandle(void* handle) const {
184#if defined(WEBRTC_NS_FLOAT)
185  return WebRtcNs_set_policy(static_cast<Handle*>(handle),
186                             MapSetting(level_));
187#elif defined(WEBRTC_NS_FIXED)
188  return WebRtcNsx_set_policy(static_cast<Handle*>(handle),
189                              MapSetting(level_));
190#endif
191}
192
193int NoiseSuppressionImpl::num_handles_required() const {
194  return apm_->num_output_channels();
195}
196
197int NoiseSuppressionImpl::GetHandleError(void* handle) const {
198  // The NS has no get_error() function.
199  assert(handle != NULL);
200  return apm_->kUnspecifiedError;
201}
202}  // namespace webrtc
203