• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
VadCircularBuffer(int buffer_size)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 
~VadCircularBuffer()26 VadCircularBuffer::~VadCircularBuffer() {
27 }
28 
Reset()29 void VadCircularBuffer::Reset() {
30   is_full_ = false;
31   index_ = 0;
32   sum_ = 0;
33 }
34 
Create(int buffer_size)35 VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) {
36   if (buffer_size <= 0)
37     return NULL;
38   return new VadCircularBuffer(buffer_size);
39 }
40 
Oldest() const41 double VadCircularBuffer::Oldest() const {
42   if (!is_full_)
43     return buffer_[0];
44   else
45     return buffer_[index_];
46 }
47 
Mean()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 
Insert(double value)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 }
BufferLevel()73 int VadCircularBuffer::BufferLevel() {
74   if (is_full_)
75     return buffer_size_;
76   return index_;
77 }
78 
Get(int index,double * value) const79 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 
Set(int index,double value)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 
ConvertToLinearIndex(int * index) const98 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 
RemoveTransient(int width_threshold,double val_threshold)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