Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize circular buffer on overflow #422

Merged
merged 3 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 73 additions & 3 deletions sherpa-onnx/csrc/circular-buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,83 @@ CircularBuffer::CircularBuffer(int32_t capacity) {
buffer_.resize(capacity);
}

void CircularBuffer::Resize(int32_t new_capacity) {
int32_t capacity = buffer_.size();
if (new_capacity <= capacity) {
SHERPA_ONNX_LOGE("new_capacity (%d) <= original capacity (%d). Skip it.",
new_capacity, capacity);
return;
}

int32_t size = Size();
if (size == 0) {
buffer_.resize(new_capacity);
return;
}

std::vector<float> new_buffer(new_capacity);
int32_t start = head_ % capacity;
int32_t dest = head_ % new_capacity;

if (start + size <= capacity) {
if (dest + size <= new_capacity) {
std::copy(buffer_.begin() + start, buffer_.begin() + start + size,
new_buffer.begin() + dest);
} else {
int32_t part1_size = new_capacity - dest;

// copy [start, start+part1_size] to new_buffer
std::copy(buffer_.begin() + start, buffer_.begin() + start + part1_size,
new_buffer.begin() + dest);

// copy [start+part1_size, start+size] to new_buffer
std::copy(buffer_.begin() + start + part1_size,
buffer_.begin() + start + size, new_buffer.begin());
}
} else {
int32_t part1_size = capacity - start;
int32_t part2_size = size - part1_size;

// copy [start, start+part1_size] to new_buffer
if (dest + part1_size <= new_capacity) {
std::copy(buffer_.begin() + start, buffer_.begin() + start + part1_size,
new_buffer.begin() + dest);
} else {
int32_t first_part = new_capacity - dest;
int32_t second_part = part1_size - first_part;
std::copy(buffer_.begin() + start, buffer_.begin() + start + first_part,
new_buffer.begin() + dest);

std::copy(buffer_.begin() + start + first_part,
buffer_.begin() + start + part1_size, new_buffer.begin());
}

int32_t new_dest = (dest + part1_size) % new_capacity;

if (new_dest + part2_size <= new_capacity) {
std::copy(buffer_.begin(), buffer_.begin() + part2_size,
new_buffer.begin() + new_dest);
} else {
int32_t first_part = new_capacity - new_dest;
std::copy(buffer_.begin(), buffer_.begin() + first_part,
new_buffer.begin() + new_dest);
std::copy(buffer_.begin() + first_part, buffer_.begin() + part2_size,
new_buffer.begin());
}
}
buffer_.swap(new_buffer);
}

void CircularBuffer::Push(const float *p, int32_t n) {
int32_t capacity = buffer_.size();
int32_t size = Size();
if (n + size > capacity) {
SHERPA_ONNX_LOGE("Overflow! n: %d, size: %d, n+size: %d, capacity: %d", n,
size, n + size, capacity);
exit(-1);
int32_t new_capacity = std::max(capacity * 2, n + size);
SHERPA_ONNX_LOGE(
"Overflow! n: %d, size: %d, n+size: %d, capacity: %d. Increase "
"capacity to: %d",
n, size, n + size, capacity, new_capacity);
Resize(new_capacity);
}

int32_t start = tail_ % capacity;
Expand Down
2 changes: 2 additions & 0 deletions sherpa-onnx/csrc/circular-buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class CircularBuffer {
tail_ = 0;
}

void Resize(int32_t new_capacity);

private:
std::vector<float> buffer_;

Expand Down
3 changes: 2 additions & 1 deletion sherpa-onnx/csrc/lexicon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#include "android/asset_manager_jni.h"
#endif

#include <regex>
#include <memory>
#include <regex> // NOLINT

#include "sherpa-onnx/csrc/macros.h"
#include "sherpa-onnx/csrc/onnx-utils.h"
Expand Down
4 changes: 2 additions & 2 deletions sherpa-onnx/csrc/lexicon.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#define SHERPA_ONNX_CSRC_LEXICON_H_

#include <cstdint>
#include <iostream>
#include <regex>
#include <memory>
#include <regex> // NOLINT
#include <string>
#include <unordered_map>
#include <unordered_set>
Expand Down
19 changes: 15 additions & 4 deletions sherpa-onnx/csrc/voice-activity-detector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "sherpa-onnx/csrc/voice-activity-detector.h"

#include <algorithm>
#include <queue>
#include <utility>

Expand All @@ -30,7 +31,7 @@ class VoiceActivityDetector::Impl {
void AcceptWaveform(const float *samples, int32_t n) {
int32_t window_size = model_->WindowSize();

// note n is usally window_size and there is no need to use
// note n is usually window_size and there is no need to use
// an extra buffer here
last_.insert(last_.end(), samples, samples + n);
int32_t k = static_cast<int32_t>(last_.size()) / window_size;
Expand All @@ -39,7 +40,7 @@ class VoiceActivityDetector::Impl {

for (int32_t i = 0; i != k; ++i, p += window_size) {
buffer_.Push(p, window_size);
is_speech = model_->IsSpeech(p, window_size);
is_speech = is_speech || model_->IsSpeech(p, window_size);
}

last_ = std::vector<float>(
Expand All @@ -48,8 +49,9 @@ class VoiceActivityDetector::Impl {
if (is_speech) {
if (start_ == -1) {
// beginning of speech
start_ = buffer_.Tail() - 2 * model_->WindowSize() -
model_->MinSpeechDurationSamples();
start_ = std::max(buffer_.Tail() - 2 * model_->WindowSize() -
model_->MinSpeechDurationSamples(),
buffer_.Head());
}
} else {
// non-speech
Expand All @@ -68,6 +70,15 @@ class VoiceActivityDetector::Impl {
buffer_.Pop(end - buffer_.Head());
}

if (start_ == -1) {
int32_t end = buffer_.Tail() - 2 * model_->WindowSize() -
model_->MinSpeechDurationSamples();
int32_t n = std::max(0, end - buffer_.Head());
if (n > 0) {
buffer_.Pop(n);
}
}

start_ = -1;
}
}
Expand Down