blob: 31f14d7f64ff5be2ed85147f676e4a84cf3a92a4 [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),
Yves Gerey665174f2018-06-19 15:03:05 +020022 sum_(0) {}
pbos@webrtc.org788acd12014-12-15 09:41:24 +000023
Yves Gerey665174f2018-06-19 15:03:05 +020024VadCircularBuffer::~VadCircularBuffer() {}
pbos@webrtc.org788acd12014-12-15 09:41:24 +000025
aluebsecf6b812015-06-25 12:28:48 -070026void VadCircularBuffer::Reset() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000027 is_full_ = false;
28 index_ = 0;
29 sum_ = 0;
30}
31
aluebsecf6b812015-06-25 12:28:48 -070032VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000033 if (buffer_size <= 0)
34 return NULL;
aluebsecf6b812015-06-25 12:28:48 -070035 return new VadCircularBuffer(buffer_size);
pbos@webrtc.org788acd12014-12-15 09:41:24 +000036}
37
aluebsecf6b812015-06-25 12:28:48 -070038double VadCircularBuffer::Oldest() const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000039 if (!is_full_)
40 return buffer_[0];
41 else
42 return buffer_[index_];
43}
44
aluebsecf6b812015-06-25 12:28:48 -070045double VadCircularBuffer::Mean() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000046 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
aluebsecf6b812015-06-25 12:28:48 -070058void VadCircularBuffer::Insert(double value) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000059 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}
aluebsecf6b812015-06-25 12:28:48 -070070int VadCircularBuffer::BufferLevel() {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000071 if (is_full_)
72 return buffer_size_;
73 return index_;
74}
75
aluebsecf6b812015-06-25 12:28:48 -070076int VadCircularBuffer::Get(int index, double* value) const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000077 int err = ConvertToLinearIndex(&index);
78 if (err < 0)
79 return -1;
80 *value = buffer_[index];
81 return 0;
82}
83
aluebsecf6b812015-06-25 12:28:48 -070084int VadCircularBuffer::Set(int index, double value) {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000085 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
aluebsecf6b812015-06-25 12:28:48 -070095int VadCircularBuffer::ConvertToLinearIndex(int* index) const {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000096 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
aluebsecf6b812015-06-25 12:28:48 -0700108int VadCircularBuffer::RemoveTransient(int width_threshold,
pbos@webrtc.org788acd12014-12-15 09:41:24 +0000109 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