19a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org/*
29a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
39a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *
49a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
59a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
69a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
79a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
89a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org */
109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
11e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/post_decode_vad.h"
129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgnamespace webrtc {
149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
15dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.orgPostDecodeVad::~PostDecodeVad() {
16dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  if (vad_instance_)
17dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org    WebRtcVad_Free(vad_instance_);
18dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org}
19dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org
209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgvoid PostDecodeVad::Enable() {
219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (!vad_instance_) {
229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Create the instance.
239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (WebRtcVad_Create(&vad_instance_) != 0) {
249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      // Failed to create instance.
259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      Disable();
269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      return;
279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  Init();
309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  enabled_ = true;
319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgvoid PostDecodeVad::Disable() {
349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  enabled_ = false;
359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  running_ = false;
369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
379a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgvoid PostDecodeVad::Init() {
399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  running_ = false;
409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (vad_instance_) {
419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    WebRtcVad_Init(vad_instance_);
429a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    WebRtcVad_set_mode(vad_instance_, kVadMode);
439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    running_ = true;
449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
459a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
47045e45efeca8776975254550137ec65268aadb54turaj@webrtc.orgvoid PostDecodeVad::Update(int16_t* signal, int length,
489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                           AudioDecoder::SpeechType speech_type,
499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                           bool sid_frame,
509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                           int fs_hz) {
519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (!vad_instance_ || !enabled_) {
529a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    return;
539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (speech_type == AudioDecoder::kComfortNoise || sid_frame ||
569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      fs_hz > 16000) {
579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // TODO(hlundin): Remove restriction on fs_hz.
589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    running_ = false;
599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    active_speech_ = true;
609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    sid_interval_counter_ = 0;
619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  } else if (!running_) {
629a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    ++sid_interval_counter_;
639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (sid_interval_counter_ >= kVadAutoEnable) {
669a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    Init();
679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  if (length > 0 && running_) {
70045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org    int vad_sample_index = 0;
719a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    active_speech_ = false;
729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Loop through frame sizes 30, 20, and 10 ms.
73045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org    for (int vad_frame_size_ms = 30; vad_frame_size_ms >= 10;
749a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        vad_frame_size_ms -= 10) {
75045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org      int vad_frame_size_samples = vad_frame_size_ms * fs_hz / 1000;
769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      while (length - vad_sample_index >= vad_frame_size_samples) {
77045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org        int vad_return = WebRtcVad_Process(
78045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org            vad_instance_, fs_hz, &signal[vad_sample_index],
79045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org            vad_frame_size_samples);
809a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        active_speech_ |= (vad_return == 1);
819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        vad_sample_index += vad_frame_size_samples;
829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      }
839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}  // namespace webrtc
88