blob: eea0a04a2a624a4469687ddd9b5d9c97d90b00ee [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
bjornv@webrtc.org0c6f9312012-01-30 09:39:08 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000011#include "webrtc/modules/audio_processing/noise_suppression_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000015#include "webrtc/modules/audio_processing/audio_buffer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000016#if defined(WEBRTC_NS_FLOAT)
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000017#include "webrtc/modules/audio_processing/ns/include/noise_suppression.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000018#elif defined(WEBRTC_NS_FIXED)
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000019#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020#endif
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000021#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000022
niklase@google.com470e71d2011-07-07 08:21:25 +000023
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;
niklase@google.com470e71d2011-07-07 08:21:25 +000043 }
andrew@webrtc.org648af742012-02-08 01:57:29 +000044 assert(false);
mflodman@webrtc.orgec31bc12012-02-06 12:42:45 +000045 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000046}
47} // namespace
48
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000049NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm,
50 CriticalSectionWrapper* crit)
51 : ProcessingComponent(),
niklase@google.com470e71d2011-07-07 08:21:25 +000052 apm_(apm),
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000053 crit_(crit),
niklase@google.com470e71d2011-07-07 08:21:25 +000054 level_(kModerate) {}
55
56NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
57
58int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
59 int err = apm_->kNoError;
60
61 if (!is_component_enabled()) {
62 return apm_->kNoError;
63 }
64 assert(audio->samples_per_split_channel() <= 160);
65 assert(audio->num_channels() == num_handles());
66
67 for (int i = 0; i < num_handles(); i++) {
68 Handle* my_handle = static_cast<Handle*>(handle(i));
69#if defined(WEBRTC_NS_FLOAT)
70 err = WebRtcNs_Process(static_cast<Handle*>(handle(i)),
kwiberg@webrtc.org12cd4432014-06-10 11:13:09 +000071 audio->low_pass_split_data_f(i),
72 audio->high_pass_split_data_f(i),
73 audio->low_pass_split_data_f(i),
74 audio->high_pass_split_data_f(i));
niklase@google.com470e71d2011-07-07 08:21:25 +000075#elif defined(WEBRTC_NS_FIXED)
76 err = WebRtcNsx_Process(static_cast<Handle*>(handle(i)),
77 audio->low_pass_split_data(i),
78 audio->high_pass_split_data(i),
79 audio->low_pass_split_data(i),
80 audio->high_pass_split_data(i));
81#endif
82
83 if (err != apm_->kNoError) {
84 return GetHandleError(my_handle);
85 }
86 }
87
88 return apm_->kNoError;
89}
90
91int NoiseSuppressionImpl::Enable(bool enable) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000092 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +000093 return EnableComponent(enable);
94}
95
96bool NoiseSuppressionImpl::is_enabled() const {
97 return is_component_enabled();
98}
99
100int NoiseSuppressionImpl::set_level(Level level) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +0000101 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 if (MapSetting(level) == -1) {
103 return apm_->kBadParameterError;
104 }
105
106 level_ = level;
107 return Configure();
108}
109
110NoiseSuppression::Level NoiseSuppressionImpl::level() const {
111 return level_;
112}
113
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000114float NoiseSuppressionImpl::speech_probability() const {
115#if defined(WEBRTC_NS_FLOAT)
116 float probability_average = 0.0f;
117 for (int i = 0; i < num_handles(); i++) {
118 Handle* my_handle = static_cast<Handle*>(handle(i));
119 probability_average += WebRtcNs_prior_speech_probability(my_handle);
120 }
121 return probability_average / num_handles();
122#elif defined(WEBRTC_NS_FIXED)
123 // Currently not available for the fixed point implementation.
124 return apm_->kUnsupportedFunctionError;
125#endif
126}
127
niklase@google.com470e71d2011-07-07 08:21:25 +0000128void* NoiseSuppressionImpl::CreateHandle() const {
129 Handle* handle = NULL;
130#if defined(WEBRTC_NS_FLOAT)
131 if (WebRtcNs_Create(&handle) != apm_->kNoError)
132#elif defined(WEBRTC_NS_FIXED)
133 if (WebRtcNsx_Create(&handle) != apm_->kNoError)
134#endif
135 {
136 handle = NULL;
137 } else {
138 assert(handle != NULL);
139 }
140
141 return handle;
142}
143
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000144void NoiseSuppressionImpl::DestroyHandle(void* handle) const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000145#if defined(WEBRTC_NS_FLOAT)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000146 WebRtcNs_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000147#elif defined(WEBRTC_NS_FIXED)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000148 WebRtcNsx_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000149#endif
150}
151
152int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
153#if defined(WEBRTC_NS_FLOAT)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000154 return WebRtcNs_Init(static_cast<Handle*>(handle),
155 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000156#elif defined(WEBRTC_NS_FIXED)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000157 return WebRtcNsx_Init(static_cast<Handle*>(handle),
158 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000159#endif
160}
161
162int NoiseSuppressionImpl::ConfigureHandle(void* handle) const {
163#if defined(WEBRTC_NS_FLOAT)
164 return WebRtcNs_set_policy(static_cast<Handle*>(handle),
165 MapSetting(level_));
166#elif defined(WEBRTC_NS_FIXED)
167 return WebRtcNsx_set_policy(static_cast<Handle*>(handle),
168 MapSetting(level_));
169#endif
170}
171
172int NoiseSuppressionImpl::num_handles_required() const {
173 return apm_->num_output_channels();
174}
175
176int NoiseSuppressionImpl::GetHandleError(void* handle) const {
177 // The NS has no get_error() function.
178 assert(handle != NULL);
179 return apm_->kUnspecifiedError;
180}
181} // namespace webrtc