Rewrote SDL sound synchronization, using a very old patch as a base for some of the changes
This commit is contained in:
parent
9e8671042b
commit
885172ea9c
|
@ -40,12 +40,23 @@ void SoundSDL::read(u16 * stream, int length)
|
||||||
if (!_initialized || length <= 0 || !emulating)
|
if (!_initialized || length <= 0 || !emulating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
/* since this is running in a different thread, speedup and
|
||||||
|
* throttle can change at any time; save the value so locks
|
||||||
|
* stay in sync */
|
||||||
|
bool lock = (emulating && !speedup) ? true : false;
|
||||||
|
|
||||||
|
if (lock)
|
||||||
|
SDL_SemWait (_semBufferFull);
|
||||||
|
|
||||||
SDL_mutexP(_mutex);
|
SDL_mutexP(_mutex);
|
||||||
|
|
||||||
_rbuf.read(stream, std::min(static_cast<std::size_t>(length) / 2, _rbuf.used()));
|
_rbuf.read(stream, std::min(static_cast<std::size_t>(length) / 2, _rbuf.used()));
|
||||||
|
|
||||||
SDL_CondSignal(_cond);
|
|
||||||
SDL_mutexV(_mutex);
|
SDL_mutexV(_mutex);
|
||||||
|
|
||||||
|
if (lock)
|
||||||
|
SDL_SemPost (_semBufferEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSDL::write(u16 * finalWave, int length)
|
void SoundSDL::write(u16 * finalWave, int length)
|
||||||
|
@ -63,23 +74,25 @@ void SoundSDL::write(u16 * finalWave, int length)
|
||||||
std::size_t avail;
|
std::size_t avail;
|
||||||
while ((avail = _rbuf.avail() / 2) < samples)
|
while ((avail = _rbuf.avail() / 2) < samples)
|
||||||
{
|
{
|
||||||
|
bool lock = (emulating && !speedup) ? true : false;
|
||||||
|
|
||||||
_rbuf.write(finalWave, avail * 2);
|
_rbuf.write(finalWave, avail * 2);
|
||||||
|
|
||||||
finalWave += avail * 2;
|
finalWave += avail * 2;
|
||||||
samples -= avail;
|
samples -= avail;
|
||||||
|
|
||||||
// If emulating and not in speed up mode, synchronize to audio
|
SDL_mutexV(_mutex);
|
||||||
// by waiting till there is enough room in the buffer
|
if (lock)
|
||||||
if (emulating && !speedup)
|
|
||||||
{
|
{
|
||||||
SDL_CondWait(_cond, _mutex);
|
SDL_SemPost(_semBufferFull);
|
||||||
|
SDL_SemWait(_semBufferEmpty);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Drop the remaining of the audio data
|
// Drop the remaining of the audio data
|
||||||
SDL_mutexV(_mutex);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SDL_mutexP(_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
_rbuf.write(finalWave, samples * 2);
|
_rbuf.write(finalWave, samples * 2);
|
||||||
|
@ -106,9 +119,10 @@ bool SoundSDL::init(long sampleRate)
|
||||||
|
|
||||||
_rbuf.reset(_delay * sampleRate * 2);
|
_rbuf.reset(_delay * sampleRate * 2);
|
||||||
|
|
||||||
_cond = SDL_CreateCond();
|
_mutex = SDL_CreateMutex();
|
||||||
_mutex = SDL_CreateMutex();
|
_semBufferFull = SDL_CreateSemaphore (0);
|
||||||
_initialized = true;
|
_semBufferEmpty = SDL_CreateSemaphore (1);
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -121,11 +135,14 @@ SoundSDL::~SoundSDL()
|
||||||
SDL_mutexP(_mutex);
|
SDL_mutexP(_mutex);
|
||||||
int iSave = emulating;
|
int iSave = emulating;
|
||||||
emulating = 0;
|
emulating = 0;
|
||||||
SDL_CondSignal(_cond);
|
SDL_SemPost(_semBufferFull);
|
||||||
|
SDL_SemPost(_semBufferEmpty);
|
||||||
SDL_mutexV(_mutex);
|
SDL_mutexV(_mutex);
|
||||||
|
|
||||||
SDL_DestroyCond(_cond);
|
SDL_DestroySemaphore(_semBufferFull);
|
||||||
_cond = NULL;
|
SDL_DestroySemaphore(_semBufferEmpty);
|
||||||
|
_semBufferFull = NULL;
|
||||||
|
_semBufferEmpty = NULL;
|
||||||
|
|
||||||
SDL_DestroyMutex(_mutex);
|
SDL_DestroyMutex(_mutex);
|
||||||
_mutex = NULL;
|
_mutex = NULL;
|
||||||
|
|
|
@ -38,8 +38,9 @@ public:
|
||||||
private:
|
private:
|
||||||
RingBuffer<u16> _rbuf;
|
RingBuffer<u16> _rbuf;
|
||||||
|
|
||||||
SDL_cond * _cond;
|
|
||||||
SDL_mutex * _mutex;
|
SDL_mutex * _mutex;
|
||||||
|
SDL_sem *_semBufferFull;
|
||||||
|
SDL_sem *_semBufferEmpty;
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue