blob: 837585fbd70c9d78fa6cef476b16579d52a25ec7 [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)
Henrik Kjellander9b72af92015-11-11 20:16:11 +010017#include "webrtc/modules/audio_processing/ns/noise_suppression.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000018#elif defined(WEBRTC_NS_FIXED)
Henrik Kjellander9b72af92015-11-11 20:16:11 +010019#include "webrtc/modules/audio_processing/ns/noise_suppression_x.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020#endif
21
niklase@google.com470e71d2011-07-07 08:21:25 +000022
23namespace webrtc {
24
25#if defined(WEBRTC_NS_FLOAT)
26typedef NsHandle Handle;
27#elif defined(WEBRTC_NS_FIXED)
28typedef NsxHandle Handle;
29#endif
30
31namespace {
32int MapSetting(NoiseSuppression::Level level) {
33 switch (level) {
34 case NoiseSuppression::kLow:
35 return 0;
36 case NoiseSuppression::kModerate:
37 return 1;
38 case NoiseSuppression::kHigh:
39 return 2;
40 case NoiseSuppression::kVeryHigh:
41 return 3;
niklase@google.com470e71d2011-07-07 08:21:25 +000042 }
andrew@webrtc.org648af742012-02-08 01:57:29 +000043 assert(false);
mflodman@webrtc.orgec31bc12012-02-06 12:42:45 +000044 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46} // namespace
47
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000048NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm,
peahdf3efa82015-11-28 12:35:15 -080049 rtc::CriticalSection* crit)
50 : ProcessingComponent(), apm_(apm), crit_(crit), level_(kModerate) {
51 RTC_DCHECK(apm);
52 RTC_DCHECK(crit);
53}
niklase@google.com470e71d2011-07-07 08:21:25 +000054
55NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
56
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000057int NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
58#if defined(WEBRTC_NS_FLOAT)
59 if (!is_component_enabled()) {
peahdf3efa82015-11-28 12:35:15 -080060 return AudioProcessing::kNoError;
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000061 }
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000062 assert(audio->num_frames_per_band() <= 160);
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000063 assert(audio->num_channels() == num_handles());
64
65 for (int i = 0; i < num_handles(); ++i) {
66 Handle* my_handle = static_cast<Handle*>(handle(i));
67
aluebs@webrtc.orgc5ebbd92014-12-10 19:30:57 +000068 WebRtcNs_Analyze(my_handle, audio->split_bands_const_f(i)[kBand0To8kHz]);
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000069 }
70#endif
peahdf3efa82015-11-28 12:35:15 -080071 return AudioProcessing::kNoError;
aluebs@webrtc.orgfda2c2e2014-09-18 09:54:06 +000072}
73
niklase@google.com470e71d2011-07-07 08:21:25 +000074int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
peahdf3efa82015-11-28 12:35:15 -080075 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +000076 if (!is_component_enabled()) {
peahdf3efa82015-11-28 12:35:15 -080077 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +000078 }
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 }
peahdf3efa82015-11-28 12:35:15 -080096 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +000097}
98
99int NoiseSuppressionImpl::Enable(bool enable) {
peahdf3efa82015-11-28 12:35:15 -0800100 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 return EnableComponent(enable);
102}
103
104bool NoiseSuppressionImpl::is_enabled() const {
peahdf3efa82015-11-28 12:35:15 -0800105 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000106 return is_component_enabled();
107}
108
109int NoiseSuppressionImpl::set_level(Level level) {
peahdf3efa82015-11-28 12:35:15 -0800110 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 if (MapSetting(level) == -1) {
peahdf3efa82015-11-28 12:35:15 -0800112 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000113 }
114
115 level_ = level;
116 return Configure();
117}
118
119NoiseSuppression::Level NoiseSuppressionImpl::level() const {
peahdf3efa82015-11-28 12:35:15 -0800120 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000121 return level_;
122}
123
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000124float NoiseSuppressionImpl::speech_probability() const {
peahdf3efa82015-11-28 12:35:15 -0800125 rtc::CritScope cs(crit_);
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000126#if defined(WEBRTC_NS_FLOAT)
127 float probability_average = 0.0f;
128 for (int i = 0; i < num_handles(); i++) {
129 Handle* my_handle = static_cast<Handle*>(handle(i));
130 probability_average += WebRtcNs_prior_speech_probability(my_handle);
131 }
132 return probability_average / num_handles();
133#elif defined(WEBRTC_NS_FIXED)
134 // Currently not available for the fixed point implementation.
peahdf3efa82015-11-28 12:35:15 -0800135 return AudioProcessing::kUnsupportedFunctionError;
bjornv@webrtc.org08329f42012-07-12 21:00:43 +0000136#endif
137}
138
niklase@google.com470e71d2011-07-07 08:21:25 +0000139void* NoiseSuppressionImpl::CreateHandle() const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000140#if defined(WEBRTC_NS_FLOAT)
Bjorn Volcker9345e862015-06-10 21:43:36 +0200141 return WebRtcNs_Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000142#elif defined(WEBRTC_NS_FIXED)
Bjorn Volcker9345e862015-06-10 21:43:36 +0200143 return WebRtcNsx_Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000144#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000145}
146
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000147void NoiseSuppressionImpl::DestroyHandle(void* handle) const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000148#if defined(WEBRTC_NS_FLOAT)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000149 WebRtcNs_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000150#elif defined(WEBRTC_NS_FIXED)
bjornv@webrtc.org5964fe02014-04-22 06:52:28 +0000151 WebRtcNsx_Free(static_cast<Handle*>(handle));
niklase@google.com470e71d2011-07-07 08:21:25 +0000152#endif
153}
154
155int NoiseSuppressionImpl::InitializeHandle(void* handle) const {
156#if defined(WEBRTC_NS_FLOAT)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000157 return WebRtcNs_Init(static_cast<Handle*>(handle),
aluebs@webrtc.org50883772014-09-26 14:33:08 +0000158 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000159#elif defined(WEBRTC_NS_FIXED)
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000160 return WebRtcNsx_Init(static_cast<Handle*>(handle),
161 apm_->proc_sample_rate_hz());
niklase@google.com470e71d2011-07-07 08:21:25 +0000162#endif
163}
164
165int NoiseSuppressionImpl::ConfigureHandle(void* handle) const {
peahdf3efa82015-11-28 12:35:15 -0800166 rtc::CritScope cs(crit_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000167#if defined(WEBRTC_NS_FLOAT)
168 return WebRtcNs_set_policy(static_cast<Handle*>(handle),
169 MapSetting(level_));
170#elif defined(WEBRTC_NS_FIXED)
171 return WebRtcNsx_set_policy(static_cast<Handle*>(handle),
172 MapSetting(level_));
173#endif
174}
175
176int NoiseSuppressionImpl::num_handles_required() const {
177 return apm_->num_output_channels();
178}
179
180int NoiseSuppressionImpl::GetHandleError(void* handle) const {
181 // The NS has no get_error() function.
182 assert(handle != NULL);
peahdf3efa82015-11-28 12:35:15 -0800183 return AudioProcessing::kUnspecifiedError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000184}
185} // namespace webrtc