From 45eb9f0e7ae3cd68ea7c1f8ef986ead30f00ca9b Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Mon, 17 Oct 2011 03:14:20 -0700 Subject: [PATCH] fix some logic errors in the mic code and decrease latency a bit. emulate the buffer_overflow bit. --- Source/Core/Core/Src/HW/EXI_DeviceMic.cpp | 45 +++++++++++++---------- Source/Core/Core/Src/HW/EXI_DeviceMic.h | 9 +++-- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp index 308f03b3cb..cba3940cdf 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMic.cpp @@ -38,16 +38,18 @@ void CEXIMic::StreamLog(const char *msg) void CEXIMic::StreamInit() { // Setup the wonderful c-interfaced lib... + pa_stream = NULL; + if ((pa_error = Pa_Initialize()) != paNoError) StreamLog("Pa_Initialize"); - stream_wpos = stream_rpos = 0; - memset(stream_buffer, 0, stream_size * sample_size); + stream_buffer = NULL; + samples_avail = stream_wpos = stream_rpos = 0; } void CEXIMic::StreamTerminate() { - Pa_AbortStream(pa_stream); + StreamStop(); if ((pa_error = Pa_Terminate()) != paNoError) StreamLog("Pa_Terminate"); @@ -61,12 +63,13 @@ static int Pa_Callback(const void *inputBuffer, void *outputBuffer, { (void)outputBuffer; (void)timeInfo; + (void)statusFlags; CEXIMic *mic = (CEXIMic *)userData; std::lock_guard 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; 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->stream_size; @@ -96,6 +106,9 @@ static int Pa_Callback(const void *inputBuffer, void *outputBuffer, void CEXIMic::StreamStart() { // 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, sample_rate, buff_size_samples, Pa_Callback, this); StreamLog("Pa_OpenDefaultStream"); @@ -105,33 +118,26 @@ void CEXIMic::StreamStart() void CEXIMic::StreamStop() { - // Acts as if Pa_AbortStream was called - pa_error = Pa_CloseStream(pa_stream); - StreamLog("Pa_CloseStream"); + if (pa_stream != NULL && Pa_IsStreamActive(pa_stream) >= paNoError) + Pa_AbortStream(pa_stream); + + delete [] stream_buffer; + stream_buffer = NULL; } void CEXIMic::StreamReadOne() { std::lock_guard 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) { s16 *last_buffer = &stream_buffer[stream_rpos]; memcpy(ring_buffer, last_buffer, buff_size); + samples_avail -= buff_size_samples; + stream_rpos += buff_size_samples; 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. 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) : slot(index) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMic.h b/Source/Core/Core/Src/HW/EXI_DeviceMic.h index 1832e6b59d..b9596ba85a 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMic.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMic.h @@ -46,7 +46,6 @@ private: cmdReset = 0xFF, }; - // STATE_TO_SAVE int slot; u32 m_position; @@ -68,7 +67,6 @@ private: u16 is_active :1; // If we are sampling or not }; }; - UStatus status; // 64 is the max size, can be 16 or 32 as well int ring_pos; @@ -91,6 +89,8 @@ private: void StreamReadOne(); public: + UStatus status; + std::mutex ring_lock; // status bits converted to nice numbers @@ -100,10 +100,11 @@ public: // Arbitrarily small ringbuffer used by audio input backend in order to // keep delay tolerable - s16 stream_buffer[64 * sample_size * 500]; - static int const stream_size; + s16 *stream_buffer; + int stream_size; int stream_wpos; int stream_rpos; + int samples_avail; protected: virtual void TransferByte(u8 &byte);