blob: 3c4d5ad0e07894f150c6a19c19b0782374595bfe [file] [log] [blame]
pbos@webrtc.org788acd12014-12-15 09:41:24 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/vad/vad_circular_buffer.h"
pbos@webrtc.org788acd12014-12-15 09:41:24 +000012
pbos@webrtc.org788acd12014-12-15 09:41:24 +000013#include <stdlib.h>
14
15namespace webrtc {
16
aluebsecf6b812015-06-25 12:28:48 -070017VadCircularBuffer::VadCircularBuffer(int buffer_size)
pbos@webrtc.org788acd12014-12-15 09:41:24 +000018 : buffer_(new double[buffer_size]),
19 is_full_(false),
20 index_(0),
21 buffer_size_(buffer_size),
aluebsecf6b812015-06-25 12:28:48 -070022 sum_(0) {
23}
pbos@webrtc.org788acd12014-12-15 09:41:24 +000024
aluebsecf6b812015-06-25 12:28:48 -070025VadCircularBuffer::~VadCircularBuffer() {
26}
pbos@webrtc.org788acd12014-12-15 09:41:24 +000027
aluebsecf6b812015-06-25 12:28:48 -070028void VadCircularBuffer::Reset() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000029 is_full_ = false;
30 index_ = 0;
31 sum_ = 0;
32}
33
aluebsecf6b812015-06-25 12:28:48 -070034VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000035 if (buffer_size <= 0)
36 return NULL;
aluebsecf6b812015-06-25 12:28:48 -070037 return new VadCircularBuffer(buffer_size);
pbos@webrtc.org788acd12014-12-15 09:41:24 +000038}
39
aluebsecf6b812015-06-25 12:28:48 -070040double VadCircularBuffer::Oldest() const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000041 if (!is_full_)
42 return buffer_[0];
43 else
44 return buffer_[index_];
45}
46
aluebsecf6b812015-06-25 12:28:48 -070047double VadCircularBuffer::Mean() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000048 double m;
49 if (is_full_) {
50 m = sum_ / buffer_size_;
51 } else {
52 if (index_ > 0)
53 m = sum_ / index_;
54 else
55 m = 0;
56 }
57 return m;
58}
59
aluebsecf6b812015-06-25 12:28:48 -070060void VadCircularBuffer::Insert(double value) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000061 if (is_full_) {
62 sum_ -= buffer_[index_];
63 }
64 sum_ += value;
65 buffer_[index_] = value;
66 index_++;
67 if (index_ >= buffer_size_) {
68 is_full_ = true;
69 index_ = 0;
70 }
71}
aluebsecf6b812015-06-25 12:28:48 -070072int VadCircularBuffer::BufferLevel() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000073 if (is_full_)
74 return buffer_size_;
75 return index_;
76}
77
aluebsecf6b812015-06-25 12:28:48 -070078int VadCircularBuffer::Get(int index, double* value) const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000079 int err = ConvertToLinearIndex(&index);
80 if (err < 0)
81 return -1;
82 *value = buffer_[index];
83 return 0;
84}
85
aluebsecf6b812015-06-25 12:28:48 -070086int VadCircularBuffer::Set(int index, double value) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000087 int err = ConvertToLinearIndex(&index);
88 if (err < 0)
89 return -1;
90
91 sum_ -= buffer_[index];
92 buffer_[index] = value;
93 sum_ += value;
94 return 0;
95}
96
aluebsecf6b812015-06-25 12:28:48 -070097int VadCircularBuffer::ConvertToLinearIndex(int* index) const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000098 if (*index < 0 || *index >= buffer_size_)
99 return -1;
100
101 if (!is_full_ && *index >= index_)
102 return -1;
103
104 *index = index_ - 1 - *index;
105 if (*index < 0)
106 *index += buffer_size_;
107 return 0;
108}
109
aluebsecf6b812015-06-25 12:28:48 -0700110int VadCircularBuffer::RemoveTransient(int width_threshold,
pbos@webrtc.org788acd12014-12-15 09:41:24 +0000111 double val_threshold) {
112 if (!is_full_ && index_ < width_threshold + 2)
113 return 0;
114
115 int index_1 = 0;
116 int index_2 = width_threshold + 1;
117 double v = 0;
118 if (Get(index_1, &v) < 0)
119 return -1;
120 if (v < val_threshold) {
121 Set(index_1, 0);
122 int index;
123 for (index = index_2; index > index_1; index--) {
124 if (Get(index, &v) < 0)
125 return -1;
126 if (v < val_threshold)
127 break;
128 }
129 for (; index > index_1; index--) {
130 if (Set(index, 0.0) < 0)
131 return -1;
132 }
133 }
134 return 0;
135}
136
137} // namespace webrtc