Commit 6d2d5a34 authored by Jan "yenda" Trmal's avatar Jan "yenda" Trmal
Browse files

Merge pull request #18 from jtrmal/online_audio_source

Online decoder fix (thanks to Curtis Riggs)
parents 9dab5412 56eb77de
...@@ -675,6 +675,16 @@ ...@@ -675,6 +675,16 @@
/src/util/text-utils-test /src/util/text-utils-test
/src/util/parse-options-test /src/util/parse-options-test
# /src/online and /src/onlinebin
/src/online/.depend.mk
/src/online/online-feat-test
/src/onlinebin/.depend.mk
/src/onlinebin/online-audio-client
/src/onlinebin/online-audio-server-decode-faster
/src/onlinebin/online-gmm-decode-faster
/src/onlinebin/online-net-client
/src/onlinebin/online-server-gmm-decode-faster
/src/onlinebin/online-wav-gmm-decode-faster
# we should probably have more things like this in # we should probably have more things like this in
# the .gitignore: # the .gitignore:
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef KALDI_NO_PORTAUDIO #ifndef KALDI_NO_PORTAUDIO
#include "base/timer.h" #include "base/timer.h"
#endif //KALDI_NO_PORTAUDIO #endif // KALDI_NO_PORTAUDIO
#include "online-audio-source.h" #include "online-audio-source.h"
...@@ -55,8 +55,16 @@ OnlinePaSource::OnlinePaSource(const uint32 timeout, ...@@ -55,8 +55,16 @@ OnlinePaSource::OnlinePaSource(const uint32 timeout,
report_interval_(report_interval), nread_calls_(0), report_interval_(report_interval), nread_calls_(0),
noverflows_(0), samples_lost_(0) { noverflows_(0), samples_lost_(0) {
using namespace std; using namespace std;
int32 rb_bits = static_cast<int32>(ceil(Log(rb_size) / Log(2)));
if (rb_bits > 30) // ok, this limit is somewhat arbitrary // Note this will work for 32bit integers but not for 64bit.
// For 64bit integers even double wouldn't work
// You would ahve to use something like
// int64 rb_bits = 0; while (rb_size != 0) {++rb_bits; rb_size >>= 1;}
// it would be much faster than two logs of FP numbers (even floats), too,
// but I dont have the time to test it.
float f = Log(static_cast<float>(rb_size)) / Log(static_cast<float>(2));
int32 rb_bits = static_cast<int32>(ceil(f));
if (rb_bits > 30) // ok, this limit is somewhat arbitrary
throw invalid_argument("PortAudio ring buffer too large!"); throw invalid_argument("PortAudio ring buffer too large!");
rb_size_ = 1 << rb_bits; rb_size_ = 1 << rb_bits;
ring_buffer_ = new char[rb_size_]; ring_buffer_ = new char[rb_size_];
...@@ -92,7 +100,7 @@ OnlinePaSource::~OnlinePaSource() { ...@@ -92,7 +100,7 @@ OnlinePaSource::~OnlinePaSource() {
bool OnlinePaSource::Read(Vector<BaseFloat> *data) { bool OnlinePaSource::Read(Vector<BaseFloat> *data) {
if (!pa_started_) { // start stream the first time Read() is called if (!pa_started_) { // start stream the first time Read() is called
PaError paerr = Pa_StartStream(pa_stream_); PaError paerr = Pa_StartStream(pa_stream_);
if (paerr != paNoError) if (paerr != paNoError)
throw std::runtime_error("Error while trying to open PortAudio stream"); throw std::runtime_error("Error while trying to open PortAudio stream");
...@@ -102,14 +110,16 @@ bool OnlinePaSource::Read(Vector<BaseFloat> *data) { ...@@ -102,14 +110,16 @@ bool OnlinePaSource::Read(Vector<BaseFloat> *data) {
if (report_interval_ != 0 if (report_interval_ != 0
&& (++nread_calls_ % report_interval_) == 0 && (++nread_calls_ % report_interval_) == 0
&& noverflows_ > 0) { && noverflows_ > 0) {
KALDI_VLOG(1) << noverflows_ << " PortAudio ring buffer overflows detected " KALDI_VLOG(1) << noverflows_
<< " PortAudio ring buffer overflows detected "
<< "and " << samples_lost_ << " sample(s) were lost"; << "and " << samples_lost_ << " sample(s) were lost";
samples_lost_ = noverflows_ = 0; samples_lost_ = noverflows_ = 0;
} }
uint32 nsamples_req = data->Dim(); // samples to request uint32 nsamples_req = data->Dim(); // samples to request
timed_out_ = false; timed_out_ = false;
while (true) { while (true) {
ring_buffer_size_t nsamples = PaUtil_GetRingBufferReadAvailable(&pa_ringbuf_); ring_buffer_size_t nsamples;
nsamples = PaUtil_GetRingBufferReadAvailable(&pa_ringbuf_);
if (nsamples >= nsamples_req) if (nsamples >= nsamples_req)
break; break;
if (timeout_ > 0) { if (timeout_ > 0) {
...@@ -124,7 +134,8 @@ bool OnlinePaSource::Read(Vector<BaseFloat> *data) { ...@@ -124,7 +134,8 @@ bool OnlinePaSource::Read(Vector<BaseFloat> *data) {
Pa_Sleep(2); Pa_Sleep(2);
} }
std::vector<int16> buf(nsamples_req); std::vector<int16> buf(nsamples_req);
rbs_t nsamples_rcv = PaUtil_ReadRingBuffer(&pa_ringbuf_, buf.data(), nsamples_req); rbs_t nsamples_rcv;
nsamples_rcv = PaUtil_ReadRingBuffer(&pa_ringbuf_, buf.data(), nsamples_req);
if (nsamples_rcv != nsamples_req) { if (nsamples_rcv != nsamples_req) {
KALDI_WARN << "Requested: " << nsamples_req KALDI_WARN << "Requested: " << nsamples_req
<< "; Received: " << nsamples_rcv << " samples"; << "; Received: " << nsamples_rcv << " samples";
...@@ -155,7 +166,7 @@ int OnlinePaSource::Callback(const void *input, void *output, ...@@ -155,7 +166,7 @@ int OnlinePaSource::Callback(const void *input, void *output,
return paContinue; return paContinue;
} }
#endif //KALDI_NO_PORTAUDIO #endif // KALDI_NO_PORTAUDIO
bool OnlineVectorSource::Read(Vector<BaseFloat> *data) { bool OnlineVectorSource::Read(Vector<BaseFloat> *data) {
KALDI_ASSERT(data->Dim() > 0); KALDI_ASSERT(data->Dim() > 0);
...@@ -163,14 +174,15 @@ bool OnlineVectorSource::Read(Vector<BaseFloat> *data) { ...@@ -163,14 +174,15 @@ bool OnlineVectorSource::Read(Vector<BaseFloat> *data) {
static_cast<uint32>(data->Dim())); static_cast<uint32>(data->Dim()));
if (n_elem > 0) { if (n_elem > 0) {
SubVector<BaseFloat> subsrc(src_, pos_, n_elem); SubVector<BaseFloat> subsrc(src_, pos_, n_elem);
if (data->Dim() == subsrc.Dim()) if (data->Dim() == subsrc.Dim()) {
data->CopyFromVec(subsrc); data->CopyFromVec(subsrc);
else } else {
for (int32 i = 0; i < subsrc.Dim(); ++i) for (int32 i = 0; i < subsrc.Dim(); ++i)
(*data)(i) = subsrc(i); (*data)(i) = subsrc(i);
}
pos_ += n_elem; pos_ += n_elem;
} }
return (pos_ < src_.Dim()); return (pos_ < src_.Dim());
} }
} // namespace kaldi } // namespace kaldi
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment