blob: 0314ceb9090972f1f3feb12eaad2a7e5ddb61605 [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
13#include <cassert>
14
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000015#include "webrtc/system_wrappers/interface/critical_section_wrapper.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
21
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000022#include "webrtc/modules/audio_processing/audio_buffer.h"
23#include "webrtc/modules/audio_processing/audio_processing_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
25namespace webrtc {
26
27#if defined(WEBRTC_NS_FLOAT)
28typedef NsHandle Handle;
29#elif defined(WEBRTC_NS_FIXED)
30typedef NsxHandle Handle;
31#endif
32
33namespace {
34int 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;
niklase@google.com470e71d2011-07-07 08:21:25 +000044 }
andrew@webrtc.org648af742012-02-08 01:57:29 +000045 assert(false);
mflodman@webrtc.orgec31bc12012-02-06 12:42:45 +000046 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000047}
48} // namespace
49
50NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessingImpl* apm)
51 : ProcessingComponent(apm),
52 apm_(apm),
53 level_(kModerate) {}
54
55NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
56
57int 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
90int NoiseSuppressionImpl::Enable(bool enable) {
andrew@webrtc.org40654032012-01-30 20:51:15 +000091 CriticalSectionScoped crit_scoped(apm_->crit());
niklase@google.com470e71d2011-07-07 08:21:25 +000092 return EnableComponent(enable);
93}
94
95bool NoiseSuppressionImpl::is_enabled() const {
96 return is_component_enabled();
97}
98
99int NoiseSuppressionImpl::set_level(Level level) {
andrew@webrtc.org40654032012-01-30 20:51:15 +0000100 CriticalSectionScoped crit_scoped(apm_->crit());
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 if (MapSetting(level) == -1) {
102 return apm_->kBadParameterError;
103 }
104
105 level_ = level;
106 return Configure();
107}
108
109NoiseSuppression::Level NoiseSuppressionImpl::level() const {
110 return level_;
111}
112
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000113float NoiseSuppressionImpl::speech_probability() const {
114#if defined(WEBRTC_NS_FLOAT)
115 float probability_average = 0.0f;
116 for (int i = 0; i < num_handles(); i++) {
117 Handle* my_handle = static_cast<Handle*>(handle(i));
118 probability_average += WebRtcNs_prior_speech_probability(my_handle);
119 }
120 return probability_average / num_handles();
121#elif defined(WEBRTC_NS_FIXED)
122 // Currently not available for the fixed point implementation.
123 return apm_->kUnsupportedFunctionError;
124#endif
125}
126
niklase@google.com470e71d2011-07-07 08:21:25 +0000127void* 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
143int 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
151int 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
159int 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
169int NoiseSuppressionImpl::num_handles_required() const {
170 return apm_->num_output_channels();
171}
172
173int 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