blob: 4e056dde6c375dc3057d665f6cd1e00a6970f816 [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
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000058int 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,
aluebs@webrtc.orga7384a12014-12-03 01:06:35 +000070 audio->split_data_f(i, kBand0To8kHz));
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000071 if (err != apm_->kNoError) {
72 return GetHandleError(my_handle);
73 }
74 }
75#endif
76 return apm_->kNoError;
77}
78
niklase@google.com470e71d2011-07-07 08:21:25 +000079int 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
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000088 for (int i = 0; i < num_handles(); ++i) {
niklase@google.com470e71d2011-07-07 08:21:25 +000089 Handle* my_handle = static_cast<Handle*>(handle(i));
90#if defined(WEBRTC_NS_FLOAT)
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000091 err = WebRtcNs_Process(my_handle,
aluebs@webrtc.orga7384a12014-12-03 01:06:35 +000092 audio->split_data_f(i, kBand0To8kHz),
93 audio->split_data_f(i, kBand8To16kHz),
94 audio->split_data_f(i, kBand0To8kHz),
95 audio->split_data_f(i, kBand8To16kHz));
niklase@google.com470e71d2011-07-07 08:21:25 +000096#elif defined(WEBRTC_NS_FIXED)
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000097 err = WebRtcNsx_Process(my_handle,
aluebs@webrtc.orga7384a12014-12-03 01:06:35 +000098 audio->split_data(i, kBand0To8kHz),
99 audio->split_data(i, kBand8To16kHz),
100 audio->split_data(i, kBand0To8kHz),
101 audio->split_data(i, kBand8To16kHz));
niklase@google.com470e71d2011-07-07 08:21:25 +0000102#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) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +0000113 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000114 return EnableComponent(enable);
115}
116
117bool NoiseSuppressionImpl::is_enabled() const {
118 return is_component_enabled();
119}
120
121int NoiseSuppressionImpl::set_level(Level level) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +0000122 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000123 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
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000135float 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
niklase@google.com470e71d2011-07-07 08:21:25 +0000149void* 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
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000165void NoiseSuppressionImpl::DestroyHandle(void* handle) const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000166#if defined(WEBRTC_NS_FLOAT)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000167 WebRtcNs_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000168#elif defined(WEBRTC_NS_FIXED)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000169 WebRtcNsx_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000170#endif
171}
172
173int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
174#if defined(WEBRTC_NS_FLOAT)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000175 return WebRtcNs_Init(static_cast<Handle*>(handle),
aluebs@webrtc.org50883772014-09-26 14:33:08 +0000176 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000177#elif defined(WEBRTC_NS_FIXED)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000178 return WebRtcNsx_Init(static_cast<Handle*>(handle),
179 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000180#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