mirror of
https://github.com/libretro/RetroArch
synced 2025-02-21 09:39:56 +00:00
More fixups in DSound.
This commit is contained in:
parent
ac4219bcde
commit
9aef33aabd
@ -54,20 +54,26 @@ static inline void get_positions(dsound_t *ds, DWORD *read_ptr, DWORD *write_ptr
|
|||||||
#define CHUNK_SIZE 256
|
#define CHUNK_SIZE 256
|
||||||
#define BUFFER_ERROR ((void*)-1)
|
#define BUFFER_ERROR ((void*)-1)
|
||||||
|
|
||||||
static inline void* grab_chunk(dsound_t *ds, DWORD write_ptr)
|
struct audio_lock
|
||||||
{
|
{
|
||||||
void *chunk = NULL;
|
void *chunk1;
|
||||||
DWORD bytes = 0;
|
DWORD size1;
|
||||||
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, &chunk, &bytes, NULL, NULL, 0);
|
void *chunk2;
|
||||||
|
DWORD size2;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool grab_region(dsound_t *ds, DWORD write_ptr, struct audio_lock *region)
|
||||||
|
{
|
||||||
|
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||||
if (res == DSERR_BUFFERLOST)
|
if (res == DSERR_BUFFERLOST)
|
||||||
{
|
{
|
||||||
res = IDirectSoundBuffer_Restore(ds->dsb);
|
res = IDirectSoundBuffer_Restore(ds->dsb);
|
||||||
if (res != DS_OK)
|
if (res != DS_OK)
|
||||||
return BUFFER_ERROR;
|
return false;
|
||||||
|
|
||||||
res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, &chunk, &bytes, NULL, NULL, 0);
|
res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||||
if (res != DS_OK)
|
if (res != DS_OK)
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *err;
|
const char *err;
|
||||||
@ -91,22 +97,17 @@ static inline void* grab_chunk(dsound_t *ds, DWORD write_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
SSNES_WARN("[DirectSound error]: %s\n", err);
|
|
||||||
|
|
||||||
if (bytes != CHUNK_SIZE)
|
|
||||||
{
|
{
|
||||||
SSNES_ERR("[DirectSound]: Could not lock as much data as requested, this should not happen!\n");
|
SSNES_WARN("[DirectSound error]: %s\n", err);
|
||||||
if (chunk)
|
return false;
|
||||||
IDirectSoundBuffer_Unlock(ds->dsb, chunk, bytes, NULL, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunk;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void release_chunk(dsound_t *ds, void *ptr)
|
static inline void release_region(dsound_t *ds, const struct audio_lock *region)
|
||||||
{
|
{
|
||||||
IDirectSoundBuffer_Unlock(ds->dsb, ptr, CHUNK_SIZE, NULL, 0);
|
IDirectSoundBuffer_Unlock(ds->dsb, region->chunk1, region->size1, region->chunk2, region->size2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD CALLBACK dsound_thread(PVOID data)
|
static DWORD CALLBACK dsound_thread(PVOID data)
|
||||||
@ -139,44 +140,39 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
|||||||
}
|
}
|
||||||
else if (fifo_avail < CHUNK_SIZE) // Got space to write, but nothing in FIFO (underrun), fill block with silence.
|
else if (fifo_avail < CHUNK_SIZE) // Got space to write, but nothing in FIFO (underrun), fill block with silence.
|
||||||
{
|
{
|
||||||
void *chunk;
|
struct audio_lock region;
|
||||||
if ((chunk = grab_chunk(ds, write_ptr)) == BUFFER_ERROR)
|
if (!grab_region(ds, write_ptr, ®ion))
|
||||||
{
|
{
|
||||||
ds->thread_alive = false;
|
ds->thread_alive = false;
|
||||||
SetEvent(ds->event);
|
SetEvent(ds->event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (chunk == NULL)
|
|
||||||
{
|
|
||||||
Sleep(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(chunk, 0, CHUNK_SIZE);
|
memset(region.chunk1, 0, region.size1);
|
||||||
release_chunk(ds, chunk);
|
memset(region.chunk2, 0, region.size2);
|
||||||
write_ptr = (write_ptr + CHUNK_SIZE) & buffer_mask;
|
|
||||||
|
release_region(ds, ®ion);
|
||||||
|
write_ptr = (write_ptr + region.size1 + region.size2) & buffer_mask;
|
||||||
}
|
}
|
||||||
else // All is good. Pull from it and notify FIFO :D
|
else // All is good. Pull from it and notify FIFO :D
|
||||||
{
|
{
|
||||||
void *chunk;
|
struct audio_lock region;
|
||||||
if ((chunk = grab_chunk(ds, write_ptr)) == BUFFER_ERROR)
|
if (!grab_region(ds, write_ptr, ®ion))
|
||||||
{
|
{
|
||||||
ds->thread_alive = false;
|
ds->thread_alive = false;
|
||||||
SetEvent(ds->event);
|
SetEvent(ds->event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (chunk == NULL)
|
|
||||||
{
|
|
||||||
Sleep(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&ds->crit);
|
EnterCriticalSection(&ds->crit);
|
||||||
fifo_read(ds->buffer, chunk, CHUNK_SIZE);
|
if (region.chunk1)
|
||||||
|
fifo_read(ds->buffer, region.chunk1, region.size1);
|
||||||
|
if (region.chunk2)
|
||||||
|
fifo_read(ds->buffer, region.chunk2, region.size2);
|
||||||
LeaveCriticalSection(&ds->crit);
|
LeaveCriticalSection(&ds->crit);
|
||||||
|
|
||||||
release_chunk(ds, chunk);
|
release_region(ds, ®ion);
|
||||||
write_ptr = (write_ptr + CHUNK_SIZE) & buffer_mask;
|
write_ptr = (write_ptr + region.size1 + region.size2) & buffer_mask;
|
||||||
|
|
||||||
SetEvent(ds->event);
|
SetEvent(ds->event);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user