noise_suppression_impl.cc revision fda2c2e810a815d98fe8b03e8c6687d14227b3ff
1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 11#include "webrtc/modules/audio_processing/noise_suppression_impl.h" 12 13#include <assert.h> 14 15#include "webrtc/modules/audio_processing/audio_buffer.h" 16#if defined(WEBRTC_NS_FLOAT) 17#include "webrtc/modules/audio_processing/ns/include/noise_suppression.h" 18#elif defined(WEBRTC_NS_FIXED) 19#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h" 20#endif 21#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 22 23 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; 43 } 44 assert(false); 45 return -1; 46} 47} // namespace 48 49NoiseSuppressionImpl::NoiseSuppressionImpl(const AudioProcessing* apm, 50 CriticalSectionWrapper* crit) 51 : ProcessingComponent(), 52 apm_(apm), 53 crit_(crit), 54 level_(kModerate) {} 55 56NoiseSuppressionImpl::~NoiseSuppressionImpl() {} 57 58int NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { 59#if defined(WEBRTC_NS_FLOAT) 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 69 int err = WebRtcNs_Analyze(my_handle, 70 audio->low_pass_split_data_f(i)); 71 if (err != apm_->kNoError) { 72 return GetHandleError(my_handle); 73 } 74 } 75#endif 76 return apm_->kNoError; 77} 78 79int NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) { 80 int err = apm_->kNoError; 81 82 if (!is_component_enabled()) { 83 return apm_->kNoError; 84 } 85 assert(audio->samples_per_split_channel() <= 160); 86 assert(audio->num_channels() == num_handles()); 87 88 for (int i = 0; i < num_handles(); ++i) { 89 Handle* my_handle = static_cast<Handle*>(handle(i)); 90#if defined(WEBRTC_NS_FLOAT) 91 err = WebRtcNs_Process(my_handle, 92 audio->low_pass_split_data_f(i), 93 audio->high_pass_split_data_f(i), 94 audio->low_pass_split_data_f(i), 95 audio->high_pass_split_data_f(i)); 96#elif defined(WEBRTC_NS_FIXED) 97 err = WebRtcNsx_Process(my_handle, 98 audio->low_pass_split_data(i), 99 audio->high_pass_split_data(i), 100 audio->low_pass_split_data(i), 101 audio->high_pass_split_data(i)); 102#endif 103 104 if (err != apm_->kNoError) { 105 return GetHandleError(my_handle); 106 } 107 } 108 109 return apm_->kNoError; 110} 111 112int NoiseSuppressionImpl::Enable(bool enable) { 113 CriticalSectionScoped crit_scoped(crit_); 114 return EnableComponent(enable); 115} 116 117bool NoiseSuppressionImpl::is_enabled() const { 118 return is_component_enabled(); 119} 120 121int NoiseSuppressionImpl::set_level(Level level) { 122 CriticalSectionScoped crit_scoped(crit_); 123 if (MapSetting(level) == -1) { 124 return apm_->kBadParameterError; 125 } 126 127 level_ = level; 128 return Configure(); 129} 130 131NoiseSuppression::Level NoiseSuppressionImpl::level() const { 132 return level_; 133} 134 135float NoiseSuppressionImpl::speech_probability() const { 136#if defined(WEBRTC_NS_FLOAT) 137 float probability_average = 0.0f; 138 for (int i = 0; i < num_handles(); i++) { 139 Handle* my_handle = static_cast<Handle*>(handle(i)); 140 probability_average += WebRtcNs_prior_speech_probability(my_handle); 141 } 142 return probability_average / num_handles(); 143#elif defined(WEBRTC_NS_FIXED) 144 // Currently not available for the fixed point implementation. 145 return apm_->kUnsupportedFunctionError; 146#endif 147} 148 149void* NoiseSuppressionImpl::CreateHandle() const { 150 Handle* handle = NULL; 151#if defined(WEBRTC_NS_FLOAT) 152 if (WebRtcNs_Create(&handle) != apm_->kNoError) 153#elif defined(WEBRTC_NS_FIXED) 154 if (WebRtcNsx_Create(&handle) != apm_->kNoError) 155#endif 156 { 157 handle = NULL; 158 } else { 159 assert(handle != NULL); 160 } 161 162 return handle; 163} 164 165void NoiseSuppressionImpl::DestroyHandle(void* handle) const { 166#if defined(WEBRTC_NS_FLOAT) 167 WebRtcNs_Free(static_cast<Handle*>(handle)); 168#elif defined(WEBRTC_NS_FIXED) 169 WebRtcNsx_Free(static_cast<Handle*>(handle)); 170#endif 171} 172 173int NoiseSuppressionImpl::InitializeHandle(void* handle) const { 174#if defined(WEBRTC_NS_FLOAT) 175 return WebRtcNs_Init(static_cast<Handle*>(handle), 176 apm_->proc_sample_rate_hz()); 177#elif defined(WEBRTC_NS_FIXED) 178 return WebRtcNsx_Init(static_cast<Handle*>(handle), 179 apm_->proc_sample_rate_hz()); 180#endif 181} 182 183int NoiseSuppressionImpl::ConfigureHandle(void* handle) const { 184#if defined(WEBRTC_NS_FLOAT) 185 return WebRtcNs_set_policy(static_cast<Handle*>(handle), 186 MapSetting(level_)); 187#elif defined(WEBRTC_NS_FIXED) 188 return WebRtcNsx_set_policy(static_cast<Handle*>(handle), 189 MapSetting(level_)); 190#endif 191} 192 193int NoiseSuppressionImpl::num_handles_required() const { 194 return apm_->num_output_channels(); 195} 196 197int NoiseSuppressionImpl::GetHandleError(void* handle) const { 198 // The NS has no get_error() function. 199 assert(handle != NULL); 200 return apm_->kUnspecifiedError; 201} 202} // namespace webrtc 203