mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
fix some logic errors in the mic code and decrease latency a bit. emulate the buffer_overflow bit.
This commit is contained in:
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user