| /* |
| * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/modules/audio_processing/vad/vad_circular_buffer.h" |
| |
| #include <stdlib.h> |
| |
| namespace webrtc { |
| |
| VadCircularBuffer::VadCircularBuffer(int buffer_size) |
| : buffer_(new double[buffer_size]), |
| is_full_(false), |
| index_(0), |
| buffer_size_(buffer_size), |
| sum_(0) { |
| } |
| |
| VadCircularBuffer::~VadCircularBuffer() { |
| } |
| |
| void VadCircularBuffer::Reset() { |
| is_full_ = false; |
| index_ = 0; |
| sum_ = 0; |
| } |
| |
| VadCircularBuffer* VadCircularBuffer::Create(int buffer_size) { |
| if (buffer_size <= 0) |
| return NULL; |
| return new VadCircularBuffer(buffer_size); |
| } |
| |
| double VadCircularBuffer::Oldest() const { |
| if (!is_full_) |
| return buffer_[0]; |
| else |
| return buffer_[index_]; |
| } |
| |
| double VadCircularBuffer::Mean() { |
| double m; |
| if (is_full_) { |
| m = sum_ / buffer_size_; |
| } else { |
| if (index_ > 0) |
| m = sum_ / index_; |
| else |
| m = 0; |
| } |
| return m; |
| } |
| |
| void VadCircularBuffer::Insert(double value) { |
| if (is_full_) { |
| sum_ -= buffer_[index_]; |
| } |
| sum_ += value; |
| buffer_[index_] = value; |
| index_++; |
| if (index_ >= buffer_size_) { |
| is_full_ = true; |
| index_ = 0; |
| } |
| } |
| int VadCircularBuffer::BufferLevel() { |
| if (is_full_) |
| return buffer_size_; |
| return index_; |
| } |
| |
| int VadCircularBuffer::Get(int index, double* value) const { |
| int err = ConvertToLinearIndex(&index); |
| if (err < 0) |
| return -1; |
| *value = buffer_[index]; |
| return 0; |
| } |
| |
| int VadCircularBuffer::Set(int index, double value) { |
| int err = ConvertToLinearIndex(&index); |
| if (err < 0) |
| return -1; |
| |
| sum_ -= buffer_[index]; |
| buffer_[index] = value; |
| sum_ += value; |
| return 0; |
| } |
| |
| int VadCircularBuffer::ConvertToLinearIndex(int* index) const { |
| if (*index < 0 || *index >= buffer_size_) |
| return -1; |
| |
| if (!is_full_ && *index >= index_) |
| return -1; |
| |
| *index = index_ - 1 - *index; |
| if (*index < 0) |
| *index += buffer_size_; |
| return 0; |
| } |
| |
| int VadCircularBuffer::RemoveTransient(int width_threshold, |
| double val_threshold) { |
| if (!is_full_ && index_ < width_threshold + 2) |
| return 0; |
| |
| int index_1 = 0; |
| int index_2 = width_threshold + 1; |
| double v = 0; |
| if (Get(index_1, &v) < 0) |
| return -1; |
| if (v < val_threshold) { |
| Set(index_1, 0); |
| int index; |
| for (index = index_2; index > index_1; index--) { |
| if (Get(index, &v) < 0) |
| return -1; |
| if (v < val_threshold) |
| break; |
| } |
| for (; index > index_1; index--) { |
| if (Set(index, 0.0) < 0) |
| return -1; |
| } |
| } |
| return 0; |
| } |
| |
| } // namespace webrtc |