136 lines
2.9 KiB
C++
136 lines
2.9 KiB
C++
|
/*
|
||
|
* 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 "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
|