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)
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);
_rbuf.read(stream, std::min(static_cast<std::size_t>(length) / 2, _rbuf.used()));
SDL_CondSignal(_cond);
SDL_mutexV(_mutex);
if (lock)
SDL_SemPost (_semBufferEmpty);
}
void SoundSDL::write(u16 * finalWave, int length)
@ -63,23 +74,25 @@ void SoundSDL::write(u16 * finalWave, int length)
std::size_t avail;
while ((avail = _rbuf.avail() / 2) < samples)
{
bool lock = (emulating && !speedup) ? true : false;
_rbuf.write(finalWave, avail * 2);
finalWave += avail * 2;
samples -= avail;
// If emulating and not in speed up mode, synchronize to audio
// by waiting till there is enough room in the buffer
if (emulating && !speedup)
SDL_mutexV(_mutex);
if (lock)
{
SDL_CondWait(_cond, _mutex);
SDL_SemPost(_semBufferFull);
SDL_SemWait(_semBufferEmpty);
}
else
{
// Drop the remaining of the audio data
SDL_mutexV(_mutex);
return;
}
SDL_mutexP(_mutex);
}
_rbuf.write(finalWave, samples * 2);
@ -106,9 +119,10 @@ bool SoundSDL::init(long sampleRate)
_rbuf.reset(_delay * sampleRate * 2);
_cond = SDL_CreateCond();
_mutex = SDL_CreateMutex();
_initialized = true;
_mutex = SDL_CreateMutex();
_semBufferFull = SDL_CreateSemaphore (0);
_semBufferEmpty = SDL_CreateSemaphore (1);
_initialized = true;
return true;
}
@ -121,11 +135,14 @@ SoundSDL::~SoundSDL()
SDL_mutexP(_mutex);
int iSave = emulating;
emulating = 0;
SDL_CondSignal(_cond);
SDL_SemPost(_semBufferFull);
SDL_SemPost(_semBufferEmpty);
SDL_mutexV(_mutex);
SDL_DestroyCond(_cond);
_cond = NULL;
SDL_DestroySemaphore(_semBufferFull);
SDL_DestroySemaphore(_semBufferEmpty);
_semBufferFull = NULL;
_semBufferEmpty = NULL;
SDL_DestroyMutex(_mutex);
_mutex = NULL;

View File

@ -38,8 +38,9 @@ public:
private:
RingBuffer<u16> _rbuf;
SDL_cond * _cond;
SDL_mutex * _mutex;
SDL_sem *_semBufferFull;
SDL_sem *_semBufferEmpty;
bool _initialized;