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