2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_processing/voice_detection_impl.h"
15 #include "webrtc/common_audio/vad/include/webrtc_vad.h"
16 #include "webrtc/modules/audio_processing/audio_buffer.h"
17 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
21 typedef VadInst Handle;
24 int MapSetting(VoiceDetection::Likelihood likelihood) {
26 case VoiceDetection::kVeryLowLikelihood:
28 case VoiceDetection::kLowLikelihood:
30 case VoiceDetection::kModerateLikelihood:
32 case VoiceDetection::kHighLikelihood:
40 VoiceDetectionImpl::VoiceDetectionImpl(const AudioProcessing* apm,
41 CriticalSectionWrapper* crit)
42 : ProcessingComponent(),
45 stream_has_voice_(false),
46 using_external_vad_(false),
47 likelihood_(kLowLikelihood),
49 frame_size_samples_(0) {}
51 VoiceDetectionImpl::~VoiceDetectionImpl() {}
53 int VoiceDetectionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
54 if (!is_component_enabled()) {
55 return apm_->kNoError;
58 if (using_external_vad_) {
59 using_external_vad_ = false;
60 return apm_->kNoError;
62 assert(audio->samples_per_split_channel() <= 160);
64 // TODO(ajm): concatenate data in frame buffer here.
66 int vad_ret = WebRtcVad_Process(static_cast<Handle*>(handle(0)),
67 apm_->proc_split_sample_rate_hz(),
68 audio->mixed_low_pass_data(),
71 stream_has_voice_ = false;
72 audio->set_activity(AudioFrame::kVadPassive);
73 } else if (vad_ret == 1) {
74 stream_has_voice_ = true;
75 audio->set_activity(AudioFrame::kVadActive);
77 return apm_->kUnspecifiedError;
80 return apm_->kNoError;
83 int VoiceDetectionImpl::Enable(bool enable) {
84 CriticalSectionScoped crit_scoped(crit_);
85 return EnableComponent(enable);
88 bool VoiceDetectionImpl::is_enabled() const {
89 return is_component_enabled();
92 int VoiceDetectionImpl::set_stream_has_voice(bool has_voice) {
93 using_external_vad_ = true;
94 stream_has_voice_ = has_voice;
95 return apm_->kNoError;
98 bool VoiceDetectionImpl::stream_has_voice() const {
99 // TODO(ajm): enable this assertion?
100 //assert(using_external_vad_ || is_component_enabled());
101 return stream_has_voice_;
104 int VoiceDetectionImpl::set_likelihood(VoiceDetection::Likelihood likelihood) {
105 CriticalSectionScoped crit_scoped(crit_);
106 if (MapSetting(likelihood) == -1) {
107 return apm_->kBadParameterError;
110 likelihood_ = likelihood;
114 VoiceDetection::Likelihood VoiceDetectionImpl::likelihood() const {
118 int VoiceDetectionImpl::set_frame_size_ms(int size) {
119 CriticalSectionScoped crit_scoped(crit_);
120 assert(size == 10); // TODO(ajm): remove when supported.
124 return apm_->kBadParameterError;
127 frame_size_ms_ = size;
132 int VoiceDetectionImpl::frame_size_ms() const {
133 return frame_size_ms_;
136 int VoiceDetectionImpl::Initialize() {
137 int err = ProcessingComponent::Initialize();
138 if (err != apm_->kNoError || !is_component_enabled()) {
142 using_external_vad_ = false;
143 frame_size_samples_ = frame_size_ms_ *
144 apm_->proc_split_sample_rate_hz() / 1000;
145 // TODO(ajm): intialize frame buffer here.
147 return apm_->kNoError;
150 void* VoiceDetectionImpl::CreateHandle() const {
151 Handle* handle = NULL;
152 if (WebRtcVad_Create(&handle) != apm_->kNoError) {
155 assert(handle != NULL);
161 void VoiceDetectionImpl::DestroyHandle(void* handle) const {
162 WebRtcVad_Free(static_cast<Handle*>(handle));
165 int VoiceDetectionImpl::InitializeHandle(void* handle) const {
166 return WebRtcVad_Init(static_cast<Handle*>(handle));
169 int VoiceDetectionImpl::ConfigureHandle(void* handle) const {
170 return WebRtcVad_set_mode(static_cast<Handle*>(handle),
171 MapSetting(likelihood_));
174 int VoiceDetectionImpl::num_handles_required() const {
178 int VoiceDetectionImpl::GetHandleError(void* handle) const {
179 // The VAD has no get_error() function.
180 assert(handle != NULL);
181 return apm_->kUnspecifiedError;
183 } // namespace webrtc