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