Rewrote SDL sound synchronization, using a very old patch as a base for some of the changes

This commit is contained in:
kode54 2013-11-14 07:51:57 +00:00
parent 9e8671042b
commit 885172ea9c
2 changed files with 31 additions and 13 deletions

View File

@ -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;

View File

@ -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;