vad_circular_buffer.cc (2937B)
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 <cstdlib> 14 15 namespace webrtc { 16 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 24 VadCircularBuffer::~VadCircularBuffer() {} 25 26 void VadCircularBuffer::Reset() { 27 is_full_ = false; 28 index_ = 0; 29 sum_ = 0; 30 } 31 32 VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) { 33 if (buffer_size <= 0) 34 return nullptr; 35 return new VadCircularBuffer(buffer_size); 36 } 37 38 double VadCircularBuffer::Oldest() const { 39 if (!is_full_) 40 return buffer_[0]; 41 else 42 return buffer_[index_]; 43 } 44 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 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 } 70 int VadCircularBuffer::BufferLevel() { 71 if (is_full_) 72 return buffer_size_; 73 return index_; 74 } 75 76 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 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 95 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 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