1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/* 2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * 4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Use of this source code is governed by a BSD-style license 5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * that can be found in the LICENSE file in the root of the source 6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * tree. An additional intellectual property rights grant can be found 7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * in the file PATENTS. All contributing project authors may 8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * be found in the AUTHORS file in the root of the source tree. 9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */ 10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "noise_suppression_impl.h" 12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <cassert> 14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "critical_section_wrapper.h" 16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "noise_suppression.h" 18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "noise_suppression_x.h" 20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "audio_processing_impl.h" 23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "audio_buffer.h" 24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace webrtc { 26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenttypedef NsHandle Handle; 29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenttypedef NsxHandle Handle; 31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace { 34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint MapSetting(NoiseSuppression::Level level) { 35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent switch (level) { 36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent case NoiseSuppression::kLow: 37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent case NoiseSuppression::kModerate: 39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 1; 40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent case NoiseSuppression::kHigh: 41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 2; 42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent case NoiseSuppression::kVeryHigh: 43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 3; 44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent default: 45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace 49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentNoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessingImpl* apm) 51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent : ProcessingComponent(apm), 52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent apm_(apm), 53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent level_(kModerate) {} 54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentNoiseSuppressionImpl::~NoiseSuppressionImpl() {} 56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) { 58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int err = apm_->kNoError; 59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (!is_component_enabled()) { 61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kNoError; 62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(audio->samples_per_split_channel() <= 160); 64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(audio->num_channels() == num_handles()); 65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (int i = 0; i < num_handles(); i++) { 67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent Handle* my_handle = static_cast<Handle*>(handle(i)); 68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = WebRtcNs_Process(static_cast<Handle*>(handle(i)), 70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->low_pass_split_data(i), 71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->high_pass_split_data(i), 72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->low_pass_split_data(i), 73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->high_pass_split_data(i)); 74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = WebRtcNsx_Process(static_cast<Handle*>(handle(i)), 76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->low_pass_split_data(i), 77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->high_pass_split_data(i), 78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->low_pass_split_data(i), 79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent audio->high_pass_split_data(i)); 80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != apm_->kNoError) { 83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return GetHandleError(my_handle); 84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kNoError; 88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::Enable(bool enable) { 91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*apm_->crit()); 92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return EnableComponent(enable); 93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbool NoiseSuppressionImpl::is_enabled() const { 96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return is_component_enabled(); 97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::set_level(Level level) { 100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*apm_->crit()); 101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (MapSetting(level) == -1) { 102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kBadParameterError; 103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent level_ = level; 106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return Configure(); 107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentNoiseSuppression::Level NoiseSuppressionImpl::level() const { 110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return level_; 111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::get_version(char* version, 114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int version_len_bytes) const { 115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WebRtcNs_get_version(version, version_len_bytes) != 0) 117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WebRtcNsx_get_version(version, version_len_bytes) != 0) 119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kBadParameterError; 122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kNoError; 125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid* NoiseSuppressionImpl::CreateHandle() const { 128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent Handle* handle = NULL; 129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WebRtcNs_Create(&handle) != apm_->kNoError) 131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WebRtcNsx_Create(&handle) != apm_->kNoError) 133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent handle = NULL; 136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else { 137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(handle != NULL); 138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return handle; 141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::DestroyHandle(void* handle) const { 144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNs_Free(static_cast<Handle*>(handle)); 146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNsx_Free(static_cast<Handle*>(handle)); 148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::InitializeHandle(void* handle) const { 152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNs_Init(static_cast<Handle*>(handle), apm_->sample_rate_hz()); 154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNsx_Init(static_cast<Handle*>(handle), apm_->sample_rate_hz()); 156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::ConfigureHandle(void* handle) const { 160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#if defined(WEBRTC_NS_FLOAT) 161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNs_set_policy(static_cast<Handle*>(handle), 162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent MapSetting(level_)); 163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#elif defined(WEBRTC_NS_FIXED) 164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return WebRtcNsx_set_policy(static_cast<Handle*>(handle), 165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent MapSetting(level_)); 166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::num_handles_required() const { 170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->num_output_channels(); 171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint NoiseSuppressionImpl::GetHandleError(void* handle) const { 174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // The NS has no get_error() function. 175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(handle != NULL); 176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm_->kUnspecifiedError; 177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc 179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 180