1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 119fb16139d917ba32720e031d3c871987d418668fpbos@webrtc.org#include "webrtc/modules/audio_processing/noise_suppression_impl.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org#include "webrtc/modules/audio_processing/audio_buffer.h" 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 179fb16139d917ba32720e031d3c871987d418668fpbos@webrtc.org#include "webrtc/modules/audio_processing/ns/include/noise_suppression.h" 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 199fb16139d917ba32720e031d3c871987d418668fpbos@webrtc.org#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 21a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef NsHandle Handle; 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef NsxHandle Handle; 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace { 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MapSetting(NoiseSuppression::Level level) { 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (level) { 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case NoiseSuppression::kLow: 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case NoiseSuppression::kModerate: 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 1; 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case NoiseSuppression::kHigh: 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 2; 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case NoiseSuppression::kVeryHigh: 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 3; 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false); 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.orgNoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm, 50a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org CriticalSectionWrapper* crit) 51a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org : ProcessingComponent(), 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org apm_(apm), 53a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org crit_(crit), 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org level_(kModerate) {} 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNoiseSuppressionImpl::~NoiseSuppressionImpl() {} 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.orgint NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { 59ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org#if defined(WEBRTC_NS_FLOAT) 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!is_component_enabled()) { 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kNoError; 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(audio->samples_per_split_channel() <= 160); 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(audio->num_channels() == num_handles()); 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 66ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org for (int i = 0; i < num_handles(); ++i) { 67ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org Handle* my_handle = static_cast<Handle*>(handle(i)); 68ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org 69ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org int err = WebRtcNs_Analyze(my_handle, 70ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org audio->low_pass_split_data_f(i)); 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err != apm_->kNoError) { 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return GetHandleError(my_handle); 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 75ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org#endif 76ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org return apm_->kNoError; 77ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org} 78ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) { 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err = apm_->kNoError; 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!is_component_enabled()) { 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kNoError; 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(audio->samples_per_split_channel() <= 160); 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(audio->num_channels() == num_handles()); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org for (int i = 0; i < num_handles(); ++i) { 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Handle* my_handle = static_cast<Handle*>(handle(i)); 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 91ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org err = WebRtcNs_Process(my_handle, 92d70e23e13703beb829651208475612026bad0af8kwiberg@webrtc.org audio->low_pass_split_data_f(i), 93d70e23e13703beb829651208475612026bad0af8kwiberg@webrtc.org audio->high_pass_split_data_f(i), 94d70e23e13703beb829651208475612026bad0af8kwiberg@webrtc.org audio->low_pass_split_data_f(i), 95d70e23e13703beb829651208475612026bad0af8kwiberg@webrtc.org audio->high_pass_split_data_f(i)); 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 97ba6a0c5315dc3af937e66cd3d3ec7f646895a04daluebs@webrtc.org err = WebRtcNsx_Process(my_handle, 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org audio->low_pass_split_data(i), 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org audio->high_pass_split_data(i), 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org audio->low_pass_split_data(i), 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org audio->high_pass_split_data(i)); 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err != apm_->kNoError) { 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return GetHandleError(my_handle); 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kNoError; 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::Enable(bool enable) { 113a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org CriticalSectionScoped crit_scoped(crit_); 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return EnableComponent(enable); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool NoiseSuppressionImpl::is_enabled() const { 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return is_component_enabled(); 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::set_level(Level level) { 122a1a60018a1f1ec863451ad0ed4eae58239882920andrew@webrtc.org CriticalSectionScoped crit_scoped(crit_); 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (MapSetting(level) == -1) { 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kBadParameterError; 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org level_ = level; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return Configure(); 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNoiseSuppression::Level NoiseSuppressionImpl::level() const { 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return level_; 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfloat NoiseSuppressionImpl::speech_probability() const { 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float probability_average = 0.0f; 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < num_handles(); i++) { 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Handle* my_handle = static_cast<Handle*>(handle(i)); 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org probability_average += WebRtcNs_prior_speech_probability(my_handle); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return probability_average / num_handles(); 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Currently not available for the fixed point implementation. 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kUnsupportedFunctionError; 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid* NoiseSuppressionImpl::CreateHandle() const { 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Handle* handle = NULL; 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcNs_Create(&handle) != apm_->kNoError) 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcNsx_Create(&handle) != apm_->kNoError) 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org handle = NULL; 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(handle != NULL); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return handle; 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 165ffc2de0133683fb103eef61f21134f469bc099dbbjornv@webrtc.orgvoid NoiseSuppressionImpl::DestroyHandle(void* handle) const { 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 167ffc2de0133683fb103eef61f21134f469bc099dbbjornv@webrtc.org WebRtcNs_Free(static_cast<Handle*>(handle)); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 169ffc2de0133683fb103eef61f21134f469bc099dbbjornv@webrtc.org WebRtcNsx_Free(static_cast<Handle*>(handle)); 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::InitializeHandle(void* handle) const { 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 175467f7567c8befea153861e09f048f69932d6e3bdandrew@webrtc.org return WebRtcNs_Init(static_cast<Handle*>(handle), 176467f7567c8befea153861e09f048f69932d6e3bdandrew@webrtc.org apm_->proc_sample_rate_hz()); 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 178467f7567c8befea153861e09f048f69932d6e3bdandrew@webrtc.org return WebRtcNsx_Init(static_cast<Handle*>(handle), 179467f7567c8befea153861e09f048f69932d6e3bdandrew@webrtc.org apm_->proc_sample_rate_hz()); 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::ConfigureHandle(void* handle) const { 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_NS_FLOAT) 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcNs_set_policy(static_cast<Handle*>(handle), 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MapSetting(level_)); 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#elif defined(WEBRTC_NS_FIXED) 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcNsx_set_policy(static_cast<Handle*>(handle), 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MapSetting(level_)); 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::num_handles_required() const { 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->num_output_channels(); 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint NoiseSuppressionImpl::GetHandleError(void* handle) const { 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The NS has no get_error() function. 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(handle != NULL); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return apm_->kUnspecifiedError; 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 203