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