mirror of
https://github.com/libretro/libretro-tyrquake.git
synced 2025-02-21 16:30:44 +00:00
[PATCH] Abstract DMA sound buffer locking
Add SNDDMA_LockBuffer() and SNDDMA_UnlockBuffer() functions to the generic sound interface, to allow drivers to implement appropriate locking on their DMA buffers if required. Move the #ifdef'd Windows specific code to do this from the shared snd_mix.c and snd_dma.c files to the windows sound driver. Thanks to O.Sezer <sezero@users.sourceforge.net> for the idea and for providing the orginal patch which was the basis for this one. Signed-off-by: Tyrann <tyrann@disenchant.net>
This commit is contained in:
parent
e56a126544
commit
33b5b4fcbe
@ -547,50 +547,21 @@ S_StopAllSoundsC(void)
|
||||
void
|
||||
S_ClearBuffer(void)
|
||||
{
|
||||
int err;
|
||||
int clear;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!sound_started || !shm || (!shm->buffer && !pDSBuf))
|
||||
#else
|
||||
if (!sound_started || !shm || !shm->buffer)
|
||||
#endif
|
||||
if (!sound_started || !shm)
|
||||
return;
|
||||
|
||||
if (shm->samplebits == 8)
|
||||
clear = 0x80;
|
||||
else
|
||||
clear = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (pDSBuf) {
|
||||
int reps;
|
||||
void *pData;
|
||||
DWORD dwSize;
|
||||
HRESULT hresult;
|
||||
|
||||
reps = 0;
|
||||
|
||||
while ((hresult =
|
||||
pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize,
|
||||
NULL, NULL, 0)) != DS_OK) {
|
||||
if (hresult != DSERR_BUFFERLOST) {
|
||||
Con_Printf("%s: DS::Lock Sound Buffer Failed\n", __func__);
|
||||
S_Shutdown();
|
||||
return;
|
||||
}
|
||||
if (++reps > 10000) {
|
||||
Con_Printf("%s: DS: couldn't restore buffer\n", __func__);
|
||||
S_Shutdown();
|
||||
return;
|
||||
}
|
||||
}
|
||||
memset(pData, clear, shm->samples * shm->samplebits / 8);
|
||||
pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
memset(shm->buffer, clear, shm->samples * shm->samplebits / 8);
|
||||
err = SNDDMA_LockBuffer();
|
||||
if (err) {
|
||||
S_Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
clear = (shm->samplebits == 8) ? 0x80 : 0;
|
||||
memset(shm->buffer, clear, shm->samples * shm->samplebits / 8);
|
||||
SNDDMA_UnlockBuffer();
|
||||
}
|
||||
|
||||
|
||||
|
@ -235,6 +235,17 @@ SNDDMA_Init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
SNDDMA_LockBuffer(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SNDDMA_UnlockBuffer(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
SNDDMA_GetDMAPos(void)
|
||||
{
|
||||
|
@ -68,69 +68,34 @@ S_TransferStereo16(int endtime)
|
||||
{
|
||||
int lpos;
|
||||
int lpaintedtime;
|
||||
void *pbuf;
|
||||
|
||||
#ifdef _WIN32
|
||||
int reps;
|
||||
DWORD dwSize;
|
||||
HRESULT hresult;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
snd_vol = volume.value * 256;
|
||||
|
||||
snd_p = (int *)paintbuffer;
|
||||
lpaintedtime = paintedtime;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (pDSBuf) {
|
||||
reps = 0;
|
||||
|
||||
while ((hresult =
|
||||
pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize,
|
||||
NULL, NULL, 0)) != DS_OK) {
|
||||
if (hresult != DSERR_BUFFERLOST) {
|
||||
Con_Printf("%s: DS::Lock Sound Buffer Failed\n", __func__);
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (++reps > 10000) {
|
||||
Con_Printf("%s: DS: couldn't restore buffer\n", __func__);
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pbuf = shm->buffer;
|
||||
err = SNDDMA_LockBuffer();
|
||||
if (err) {
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
|
||||
while (lpaintedtime < endtime) {
|
||||
// handle recirculating buffer issues
|
||||
lpos = lpaintedtime & ((shm->samples >> 1) - 1);
|
||||
|
||||
snd_out = (short *)pbuf + (lpos << 1);
|
||||
|
||||
snd_out = (short *)shm->buffer + (lpos << 1);
|
||||
snd_linear_count = (shm->samples >> 1) - lpos;
|
||||
if (lpaintedtime + snd_linear_count > endtime)
|
||||
snd_linear_count = endtime - lpaintedtime;
|
||||
|
||||
snd_linear_count <<= 1;
|
||||
|
||||
// write a linear blast of samples
|
||||
Snd_WriteLinearBlastStereo16();
|
||||
|
||||
snd_p += snd_linear_count;
|
||||
lpaintedtime += (snd_linear_count >> 1);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (pDSBuf)
|
||||
pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0);
|
||||
#endif
|
||||
SNDDMA_UnlockBuffer();
|
||||
}
|
||||
|
||||
void
|
||||
@ -143,13 +108,7 @@ S_TransferPaintBuffer(int endtime)
|
||||
int step;
|
||||
int val;
|
||||
int snd_vol;
|
||||
void *pbuf;
|
||||
|
||||
#ifdef _WIN32
|
||||
int reps;
|
||||
DWORD dwSize;
|
||||
HRESULT hresult;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
if (shm->samplebits == 16 && shm->channels == 2) {
|
||||
S_TransferStereo16(endtime);
|
||||
@ -163,36 +122,15 @@ S_TransferPaintBuffer(int endtime)
|
||||
step = 3 - shm->channels;
|
||||
snd_vol = volume.value * 256;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (pDSBuf) {
|
||||
reps = 0;
|
||||
|
||||
while ((hresult =
|
||||
pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize,
|
||||
NULL, NULL, 0)) != DS_OK) {
|
||||
if (hresult != DSERR_BUFFERLOST) {
|
||||
Con_Printf("%s: DS::Lock Sound Buffer Failed\n", __func__);
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (++reps > 10000) {
|
||||
Con_Printf("%s: DS: couldn't restore buffer\n", __func__);
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pbuf = shm->buffer;
|
||||
err = SNDDMA_LockBuffer();
|
||||
if (err) {
|
||||
S_Shutdown();
|
||||
S_Startup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (shm->samplebits == 16) {
|
||||
short *out = (short *)pbuf;
|
||||
|
||||
short *out = (short *)shm->buffer;
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
@ -204,8 +142,7 @@ S_TransferPaintBuffer(int endtime)
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
} else if (shm->samplebits == 8) {
|
||||
unsigned char *out = (unsigned char *)pbuf;
|
||||
|
||||
unsigned char *out = (unsigned char *)shm->buffer;
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
@ -217,6 +154,7 @@ S_TransferPaintBuffer(int endtime)
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
}
|
||||
SNDDMA_UnlockBuffer();
|
||||
#ifdef _WIN32
|
||||
if (pDSBuf) {
|
||||
DWORD dwNewpos, dwWrite;
|
||||
@ -224,7 +162,6 @@ S_TransferPaintBuffer(int endtime)
|
||||
int ir = endtime - paintedtime;
|
||||
|
||||
ir += il;
|
||||
pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0);
|
||||
pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &dwNewpos, &dwWrite);
|
||||
}
|
||||
#endif
|
||||
|
@ -169,6 +169,52 @@ FreeSound(void)
|
||||
wav_init = false;
|
||||
}
|
||||
|
||||
static DWORD dsLockSize;
|
||||
static qboolean dsIsLocked = false;
|
||||
|
||||
int
|
||||
SNDDMA_LockBuffer(void)
|
||||
{
|
||||
int reps;
|
||||
void *pData;
|
||||
HRESULT hresult;
|
||||
|
||||
if (dsIsLocked)
|
||||
Sys_Error("%s: Recursive locking detected!", __func__);
|
||||
|
||||
if (pDSBuf) {
|
||||
reps = 0;
|
||||
|
||||
while ((hresult =
|
||||
pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData,
|
||||
&dsLockSize, NULL, NULL, 0)) != DS_OK) {
|
||||
if (hresult != DSERR_BUFFERLOST) {
|
||||
Con_Printf("%s: DS::Lock Sound Buffer Failed\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
if (++reps > 10000) {
|
||||
Con_Printf("%s: DS: couldn't restore buffer\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
shm->buffer = pData;
|
||||
}
|
||||
dsIsLocked = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SNDDMA_UnlockBuffer()
|
||||
{
|
||||
if (!dsIsLocked)
|
||||
Sys_Error("%s: Detected unlock without lock", __func__);
|
||||
if (pDSBuf) {
|
||||
pDSBuf->lpVtbl->Unlock(pDSBuf, shm->buffer, dsLockSize, NULL, 0);
|
||||
shm->buffer = NULL;
|
||||
}
|
||||
dsIsLocked = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -121,6 +121,10 @@ qboolean SNDDMA_Init(void);
|
||||
// gets the current DMA position
|
||||
int SNDDMA_GetDMAPos(void);
|
||||
|
||||
/* Lock and unlock the DMA sound buffer */
|
||||
int SNDDMA_LockBuffer(void);
|
||||
void SNDDMA_UnlockBuffer(void);
|
||||
|
||||
// shutdown the DMA xfer.
|
||||
void SNDDMA_Shutdown(void);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user