blob: 15019112647efa1b02a15d65401b5499f21e670d [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 }
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000063 assert(audio->num_frames_per_band() <= 160);
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000064 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
aluebs@webrtc.orgc5ebbd92014-12-10 19:30:57 +000069 WebRtcNs_Analyze(my_handle, audio->split_bands_const_f(i)[kBand0To8kHz]);
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000070 }
71#endif
72 return apm_->kNoError;
73}
74
niklase@google.com470e71d2011-07-07 08:21:25 +000075int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
niklase@google.com470e71d2011-07-07 08:21:25 +000076 if (!is_component_enabled()) {
77 return apm_->kNoError;
78 }
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000079 assert(audio->num_frames_per_band() <= 160);
niklase@google.com470e71d2011-07-07 08:21:25 +000080 assert(audio->num_channels() == num_handles());
81
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000082 for (int i = 0; i < num_handles(); ++i) {
niklase@google.com470e71d2011-07-07 08:21:25 +000083 Handle* my_handle = static_cast<Handle*>(handle(i));
84#if defined(WEBRTC_NS_FLOAT)
aluebs@webrtc.orgc5ebbd92014-12-10 19:30:57 +000085 WebRtcNs_Process(my_handle,
86 audio->split_bands_const_f(i),
87 audio->num_bands(),
88 audio->split_bands_f(i));
niklase@google.com470e71d2011-07-07 08:21:25 +000089#elif defined(WEBRTC_NS_FIXED)
aluebs@webrtc.orgc5ebbd92014-12-10 19:30:57 +000090 WebRtcNsx_Process(my_handle,
91 audio->split_bands_const(i),
92 audio->num_bands(),
93 audio->split_bands(i));
niklase@google.com470e71d2011-07-07 08:21:25 +000094#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000095 }
niklase@google.com470e71d2011-07-07 08:21:25 +000096 return apm_->kNoError;
97}
98
99int NoiseSuppressionImpl::Enable(bool enable) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +0000100 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 return EnableComponent(enable);
102}
103
104bool NoiseSuppressionImpl::is_enabled() const {
105 return is_component_enabled();
106}
107
108int NoiseSuppressionImpl::set_level(Level level) {
andrew@webrtc.org56e4a052014-02-27 22:23:17 +0000109 CriticalSectionScoped crit_scoped(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 if (MapSetting(level) == -1) {
111 return apm_->kBadParameterError;
112 }
113
114 level_ = level;
115 return Configure();
116}
117
118NoiseSuppression::Level NoiseSuppressionImpl::level() const {
119 return level_;
120}
121
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000122float NoiseSuppressionImpl::speech_probability() const {
123#if defined(WEBRTC_NS_FLOAT)
124 float probability_average = 0.0f;
125 for (int i = 0; i < num_handles(); i++) {
126 Handle* my_handle = static_cast<Handle*>(handle(i));
127 probability_average += WebRtcNs_prior_speech_probability(my_handle);
128 }
129 return probability_average / num_handles();
130#elif defined(WEBRTC_NS_FIXED)
131 // Currently not available for the fixed point implementation.
132 return apm_->kUnsupportedFunctionError;
133#endif
134}
135
niklase@google.com470e71d2011-07-07 08:21:25 +0000136void* NoiseSuppressionImpl::CreateHandle() const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000137#if defined(WEBRTC_NS_FLOAT)
Bjorn Volcker9345e862015-06-10 21:43:36 +0200138 return WebRtcNs_Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000139#elif defined(WEBRTC_NS_FIXED)
Bjorn Volcker9345e862015-06-10 21:43:36 +0200140 return WebRtcNsx_Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000141#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000142}
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),
aluebs@webrtc.org50883772014-09-26 14:33:08 +0000155 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