fix some logic errors in the mic code and decrease latency a bit. emulate the buffer_overflow bit.

This commit is contained in:
Shawn Hoffman
2011-10-17 03:14:20 -07:00
parent c528978608
commit 45eb9f0e7a
2 changed files with 30 additions and 24 deletions

View File

@ -38,16 +38,18 @@ void CEXIMic::StreamLog(const char *msg)
void CEXIMic::StreamInit() void CEXIMic::StreamInit()
{ {
// Setup the wonderful c-interfaced lib... // Setup the wonderful c-interfaced lib...
pa_stream = NULL;
if ((pa_error = Pa_Initialize()) != paNoError) if ((pa_error = Pa_Initialize()) != paNoError)
StreamLog("Pa_Initialize"); StreamLog("Pa_Initialize");
stream_wpos = stream_rpos = 0; stream_buffer = NULL;
memset(stream_buffer, 0, stream_size * sample_size); samples_avail = stream_wpos = stream_rpos = 0;
} }
void CEXIMic::StreamTerminate() void CEXIMic::StreamTerminate()
{ {
Pa_AbortStream(pa_stream); StreamStop();
if ((pa_error = Pa_Terminate()) != paNoError) if ((pa_error = Pa_Terminate()) != paNoError)
StreamLog("Pa_Terminate"); StreamLog("Pa_Terminate");
@ -61,12 +63,13 @@ static int Pa_Callback(const void *inputBuffer, void *outputBuffer,
{ {
(void)outputBuffer; (void)outputBuffer;
(void)timeInfo; (void)timeInfo;
(void)statusFlags;
CEXIMic *mic = (CEXIMic *)userData; CEXIMic *mic = (CEXIMic *)userData;
std::lock_guard<std::mutex> lk(mic->ring_lock); std::lock_guard<std::mutex> lk(mic->ring_lock);
if (mic->stream_wpos + mic->buff_size_samples >= mic->stream_size) if (mic->stream_wpos + mic->buff_size_samples > mic->stream_size)
mic->stream_wpos = 0; mic->stream_wpos = 0;
s16 *buff_in = (s16 *)inputBuffer; s16 *buff_in = (s16 *)inputBuffer;
@ -87,6 +90,13 @@ static int Pa_Callback(const void *inputBuffer, void *outputBuffer,
} }
} }
mic->samples_avail += mic->buff_size_samples;
if (mic->samples_avail > mic->stream_size)
{
mic->samples_avail = 0;
mic->status.buff_ovrflw = 1;
}
mic->stream_wpos += mic->buff_size_samples; mic->stream_wpos += mic->buff_size_samples;
mic->stream_wpos %= mic->stream_size; mic->stream_wpos %= mic->stream_size;
@ -96,6 +106,9 @@ static int Pa_Callback(const void *inputBuffer, void *outputBuffer,
void CEXIMic::StreamStart() void CEXIMic::StreamStart()
{ {
// Open stream with current parameters // Open stream with current parameters
stream_size = buff_size_samples * 500;
stream_buffer = new s16[stream_size];
pa_error = Pa_OpenDefaultStream(&pa_stream, 1, 0, paInt16, pa_error = Pa_OpenDefaultStream(&pa_stream, 1, 0, paInt16,
sample_rate, buff_size_samples, Pa_Callback, this); sample_rate, buff_size_samples, Pa_Callback, this);
StreamLog("Pa_OpenDefaultStream"); StreamLog("Pa_OpenDefaultStream");
@ -105,33 +118,26 @@ void CEXIMic::StreamStart()
void CEXIMic::StreamStop() void CEXIMic::StreamStop()
{ {
// Acts as if Pa_AbortStream was called if (pa_stream != NULL && Pa_IsStreamActive(pa_stream) >= paNoError)
pa_error = Pa_CloseStream(pa_stream); Pa_AbortStream(pa_stream);
StreamLog("Pa_CloseStream");
delete [] stream_buffer;
stream_buffer = NULL;
} }
void CEXIMic::StreamReadOne() void CEXIMic::StreamReadOne()
{ {
std::lock_guard<std::mutex> lk(ring_lock); std::lock_guard<std::mutex> lk(ring_lock);
int samples_avail = (stream_wpos > stream_rpos) ?
stream_wpos - stream_rpos :
stream_size - stream_rpos + stream_wpos;
if (samples_avail >= buff_size_samples) if (samples_avail >= buff_size_samples)
{ {
s16 *last_buffer = &stream_buffer[stream_rpos]; s16 *last_buffer = &stream_buffer[stream_rpos];
memcpy(ring_buffer, last_buffer, buff_size); memcpy(ring_buffer, last_buffer, buff_size);
samples_avail -= buff_size_samples;
stream_rpos += buff_size_samples; stream_rpos += buff_size_samples;
stream_rpos %= stream_size; stream_rpos %= stream_size;
// TODO: if overflow bit matters, find a nice way
//if (samples_avail >= buff_size_samples * 2)
//{
// status.buff_ovrflw = 1;
// stream_rpos = stream_wpos = 0;
//}
} }
} }
@ -143,7 +149,6 @@ void CEXIMic::StreamReadOne()
// in the background by Pa_Callback. // in the background by Pa_Callback.
u8 const CEXIMic::exi_id[] = { 0, 0x0a, 0, 0, 0 }; u8 const CEXIMic::exi_id[] = { 0, 0x0a, 0, 0, 0 };
int const CEXIMic::stream_size = sizeof(stream_buffer) / sizeof(*stream_buffer);
CEXIMic::CEXIMic(int index) CEXIMic::CEXIMic(int index)
: slot(index) : slot(index)

View File

@ -46,7 +46,6 @@ private:
cmdReset = 0xFF, cmdReset = 0xFF,
}; };
// STATE_TO_SAVE
int slot; int slot;
u32 m_position; u32 m_position;
@ -68,7 +67,6 @@ private:
u16 is_active :1; // If we are sampling or not u16 is_active :1; // If we are sampling or not
}; };
}; };
UStatus status;
// 64 is the max size, can be 16 or 32 as well // 64 is the max size, can be 16 or 32 as well
int ring_pos; int ring_pos;
@ -91,6 +89,8 @@ private:
void StreamReadOne(); void StreamReadOne();
public: public:
UStatus status;
std::mutex ring_lock; std::mutex ring_lock;
// status bits converted to nice numbers // status bits converted to nice numbers
@ -100,10 +100,11 @@ public:
// Arbitrarily small ringbuffer used by audio input backend in order to // Arbitrarily small ringbuffer used by audio input backend in order to
// keep delay tolerable // keep delay tolerable
s16 stream_buffer[64 * sample_size * 500]; s16 *stream_buffer;
static int const stream_size; int stream_size;
int stream_wpos; int stream_wpos;
int stream_rpos; int stream_rpos;
int samples_avail;
protected: protected:
virtual void TransferByte(u8 &byte); virtual void TransferByte(u8 &byte);