Home | History | Annotate | Download | only in vad
      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/vad/vad_circular_buffer.h"
     12 
     13 #include <assert.h>
     14 #include <stdlib.h>
     15 
     16 namespace webrtc {
     17 
     18 VadCircularBuffer::VadCircularBuffer(int buffer_size)
     19     : buffer_(new double[buffer_size]),
     20       is_full_(false),
     21       index_(0),
     22       buffer_size_(buffer_size),
     23       sum_(0) {
     24 }
     25 
     26 VadCircularBuffer::~VadCircularBuffer() {
     27 }
     28 
     29 void VadCircularBuffer::Reset() {
     30   is_full_ = false;
     31   index_ = 0;
     32   sum_ = 0;
     33 }
     34 
     35 VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) {
     36   if (buffer_size <= 0)
     37     return NULL;
     38   return new VadCircularBuffer(buffer_size);
     39 }
     40 
     41 double VadCircularBuffer::Oldest() const {
     42   if (!is_full_)
     43     return buffer_[0];
     44   else
     45     return buffer_[index_];
     46 }
     47 
     48 double VadCircularBuffer::Mean() {
     49   double m;
     50   if (is_full_) {
     51     m = sum_ / buffer_size_;
     52   } else {
     53     if (index_ > 0)
     54       m = sum_ / index_;
     55     else
     56       m = 0;
     57   }
     58   return m;
     59 }
     60 
     61 void VadCircularBuffer::Insert(double value) {
     62   if (is_full_) {
     63     sum_ -= buffer_[index_];
     64   }
     65   sum_ += value;
     66   buffer_[index_] = value;
     67   index_++;
     68   if (index_ >= buffer_size_) {
     69     is_full_ = true;
     70     index_ = 0;
     71   }
     72 }
     73 int VadCircularBuffer::BufferLevel() {
     74   if (is_full_)
     75     return buffer_size_;
     76   return index_;
     77 }
     78 
     79 int VadCircularBuffer::Get(int index, double* value) const {
     80   int err = ConvertToLinearIndex(&index);
     81   if (err < 0)
     82     return -1;
     83   *value = buffer_[index];
     84   return 0;
     85 }
     86 
     87 int VadCircularBuffer::Set(int index, double value) {
     88   int err = ConvertToLinearIndex(&index);
     89   if (err < 0)
     90     return -1;
     91 
     92   sum_ -= buffer_[index];
     93   buffer_[index] = value;
     94   sum_ += value;
     95   return 0;
     96 }
     97 
     98 int VadCircularBuffer::ConvertToLinearIndex(int* index) const {
     99   if (*index < 0 || *index >= buffer_size_)
    100     return -1;
    101 
    102   if (!is_full_ && *index >= index_)
    103     return -1;
    104 
    105   *index = index_ - 1 - *index;
    106   if (*index < 0)
    107     *index += buffer_size_;
    108   return 0;
    109 }
    110 
    111 int VadCircularBuffer::RemoveTransient(int width_threshold,
    112                                        double val_threshold) {
    113   if (!is_full_ && index_ < width_threshold + 2)
    114     return 0;
    115 
    116   int index_1 = 0;
    117   int index_2 = width_threshold + 1;
    118   double v = 0;
    119   if (Get(index_1, &v) < 0)
    120     return -1;
    121   if (v < val_threshold) {
    122     Set(index_1, 0);
    123     int index;
    124     for (index = index_2; index > index_1; index--) {
    125       if (Get(index, &v) < 0)
    126         return -1;
    127       if (v < val_threshold)
    128         break;
    129     }
    130     for (; index > index_1; index--) {
    131       if (Set(index, 0.0) < 0)
    132         return -1;
    133     }
    134   }
    135   return 0;
    136 }
    137 
    138 }  // namespace webrtc
    139