dsound: Express buffer positions in terms of bytes, not fragments.
This commit is contained in:
parent
2c6087457b
commit
1053bfb48d
@ -83,7 +83,7 @@ struct DirectSoundDevice
|
|||||||
DSCAPS drvcaps;
|
DSCAPS drvcaps;
|
||||||
DWORD priolevel;
|
DWORD priolevel;
|
||||||
PWAVEFORMATEX pwfx;
|
PWAVEFORMATEX pwfx;
|
||||||
UINT timerID, pwplay, pwqueue, prebuf, helfrags;
|
UINT timerID, playing_offs_bytes, in_mmdev_bytes, prebuf, helfrags;
|
||||||
UINT64 last_pos_bytes;
|
UINT64 last_pos_bytes;
|
||||||
DWORD fraglen;
|
DWORD fraglen;
|
||||||
LPBYTE buffer;
|
LPBYTE buffer;
|
||||||
|
@ -663,53 +663,47 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos,
|
|||||||
|
|
||||||
static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
|
static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
|
||||||
{
|
{
|
||||||
DWORD prebuf_frames, buf_offs_bytes, wave_fragpos;
|
DWORD prebuf_frames, prebuf_bytes, read_offs_bytes;
|
||||||
int prebuf_frags;
|
|
||||||
BYTE *buffer;
|
BYTE *buffer;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p)\n", device);
|
TRACE("(%p)\n", device);
|
||||||
|
|
||||||
/* calculate the current wave frag position */
|
read_offs_bytes = (device->playing_offs_bytes + device->in_mmdev_bytes) % device->buflen;
|
||||||
wave_fragpos = (device->pwplay + device->pwqueue) % device->helfrags;
|
|
||||||
|
|
||||||
/* calculate the current wave write position */
|
TRACE("read_offs_bytes = %u, playing_offs_bytes = %u, in_mmdev_bytes: %u, prebuf = %u\n",
|
||||||
buf_offs_bytes = wave_fragpos * device->fraglen;
|
read_offs_bytes, device->playing_offs_bytes, device->in_mmdev_bytes, device->prebuf);
|
||||||
|
|
||||||
TRACE("wave_fragpos = %i, buf_offs_bytes = %i, pwqueue = %i, prebuf = %i\n",
|
|
||||||
wave_fragpos, buf_offs_bytes, device->pwqueue, device->prebuf);
|
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
/* check remaining prebuffered frags */
|
if(device->mixpos < device->playing_offs_bytes)
|
||||||
prebuf_frags = device->mixpos / device->fraglen;
|
prebuf_bytes = device->mixpos + device->buflen - device->playing_offs_bytes;
|
||||||
if (prebuf_frags == device->helfrags)
|
else
|
||||||
--prebuf_frags;
|
prebuf_bytes = device->mixpos - device->playing_offs_bytes;
|
||||||
TRACE("wave_fragpos = %d, mixpos_frags = %d\n", wave_fragpos, prebuf_frags);
|
|
||||||
if (prebuf_frags < wave_fragpos)
|
|
||||||
prebuf_frags += device->helfrags;
|
|
||||||
prebuf_frags -= wave_fragpos;
|
|
||||||
TRACE("wanted prebuf_frags = %d\n", prebuf_frags);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* buffer the maximum amount of frags */
|
/* buffer the maximum amount of frags */
|
||||||
prebuf_frags = device->prebuf;
|
prebuf_bytes = device->prebuf * device->fraglen;
|
||||||
|
|
||||||
/* limit to the queue we have left */
|
/* limit to the queue we have left */
|
||||||
if ((prebuf_frags + device->pwqueue) > device->prebuf)
|
if(device->in_mmdev_bytes + prebuf_bytes > device->prebuf * device->fraglen)
|
||||||
prebuf_frags = device->prebuf - device->pwqueue;
|
prebuf_bytes = device->prebuf * device->fraglen - device->in_mmdev_bytes;
|
||||||
|
|
||||||
TRACE("prebuf_frags = %i\n", prebuf_frags);
|
TRACE("prebuf_bytes = %u\n", prebuf_bytes);
|
||||||
|
|
||||||
if(!prebuf_frags)
|
if(!prebuf_bytes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* adjust queue */
|
device->in_mmdev_bytes += prebuf_bytes;
|
||||||
device->pwqueue += prebuf_frags;
|
|
||||||
|
|
||||||
prebuf_frames = ((prebuf_frags + wave_fragpos > device->helfrags) ?
|
if(prebuf_bytes + read_offs_bytes > device->buflen){
|
||||||
(device->helfrags - wave_fragpos) :
|
DWORD chunk_bytes = device->buflen - read_offs_bytes;
|
||||||
(prebuf_frags)) * device->fraglen / device->pwfx->nBlockAlign;
|
prebuf_frames = chunk_bytes / device->pwfx->nBlockAlign;
|
||||||
|
prebuf_bytes -= chunk_bytes;
|
||||||
|
}else{
|
||||||
|
prebuf_frames = prebuf_bytes / device->pwfx->nBlockAlign;
|
||||||
|
prebuf_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
|
hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
|
||||||
if(FAILED(hr)){
|
if(FAILED(hr)){
|
||||||
@ -717,7 +711,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer, device->buffer + buf_offs_bytes,
|
memcpy(buffer, device->buffer + read_offs_bytes,
|
||||||
prebuf_frames * device->pwfx->nBlockAlign);
|
prebuf_frames * device->pwfx->nBlockAlign);
|
||||||
|
|
||||||
hr = IAudioRenderClient_ReleaseBuffer(device->render, prebuf_frames, 0);
|
hr = IAudioRenderClient_ReleaseBuffer(device->render, prebuf_frames, 0);
|
||||||
@ -727,9 +721,8 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if anything wrapped */
|
/* check if anything wrapped */
|
||||||
prebuf_frags = prebuf_frags + wave_fragpos - device->helfrags;
|
if(prebuf_bytes > 0){
|
||||||
if(prebuf_frags > 0){
|
prebuf_frames = prebuf_bytes / device->pwfx->nBlockAlign;
|
||||||
prebuf_frames = prebuf_frags * device->fraglen / device->pwfx->nBlockAlign;
|
|
||||||
|
|
||||||
hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
|
hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
|
||||||
if(FAILED(hr)){
|
if(FAILED(hr)){
|
||||||
@ -746,7 +739,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("queue now = %i\n", device->pwqueue);
|
TRACE("in_mmdev_bytes now = %i\n", device->in_mmdev_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -783,9 +776,9 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
|
|||||||
|
|
||||||
delta_frags = (pos_bytes - device->last_pos_bytes) / device->fraglen;
|
delta_frags = (pos_bytes - device->last_pos_bytes) / device->fraglen;
|
||||||
if(delta_frags > 0){
|
if(delta_frags > 0){
|
||||||
device->pwplay += delta_frags;
|
device->playing_offs_bytes += delta_frags * device->fraglen;
|
||||||
device->pwplay %= device->helfrags;
|
device->playing_offs_bytes %= device->buflen;
|
||||||
device->pwqueue -= delta_frags;
|
device->in_mmdev_bytes -= delta_frags * device->fraglen;
|
||||||
device->last_pos_bytes = pos_bytes - (pos_bytes % device->fraglen);
|
device->last_pos_bytes = pos_bytes - (pos_bytes % device->fraglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
|
|||||||
device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
|
device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
|
||||||
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
|
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
|
||||||
FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
|
FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
|
||||||
device->last_pos_bytes = device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
|
device->last_pos_bytes = device->playing_offs_bytes = device->in_mmdev_bytes = device->playpos = device->mixpos = 0;
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +221,6 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device)
|
|||||||
|
|
||||||
TRACE("(%p)\n", device);
|
TRACE("(%p)\n", device);
|
||||||
|
|
||||||
device->pwqueue = (DWORD)-1; /* resetting queues */
|
|
||||||
|
|
||||||
if(device->client){
|
if(device->client){
|
||||||
hr = IAudioClient_Stop(device->client);
|
hr = IAudioClient_Stop(device->client);
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
@ -230,7 +228,7 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear the queue */
|
/* clear the queue */
|
||||||
device->pwqueue = 0;
|
device->in_mmdev_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
|
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
|
||||||
@ -308,17 +306,14 @@ HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LP
|
|||||||
{
|
{
|
||||||
TRACE("(%p,%p,%p)\n", device, playpos, writepos);
|
TRACE("(%p,%p,%p)\n", device, playpos, writepos);
|
||||||
|
|
||||||
TRACE("pwplay=%i, pwqueue=%i\n", device->pwplay, device->pwqueue);
|
|
||||||
|
|
||||||
/* check if playpos was requested */
|
/* check if playpos was requested */
|
||||||
if (playpos)
|
if (playpos)
|
||||||
/* use the cached play position */
|
*playpos = device->playing_offs_bytes;
|
||||||
*playpos = device->pwplay * device->fraglen;
|
|
||||||
|
|
||||||
/* check if writepos was requested */
|
/* check if writepos was requested */
|
||||||
if (writepos)
|
if (writepos)
|
||||||
/* the writepos is the first non-queued position */
|
/* the writepos is the first non-queued position */
|
||||||
*writepos = ((device->pwplay + device->pwqueue) % device->helfrags) * device->fraglen;
|
*writepos = (device->playing_offs_bytes + device->in_mmdev_bytes) % device->buflen;
|
||||||
|
|
||||||
TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:-1, writepos?*writepos:-1, device, GetTickCount());
|
TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:-1, writepos?*writepos:-1, device, GetTickCount());
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user