dsound: Get rid of DS_HEL_FRAGS.

This commit is contained in:
Maarten Lankhorst 2007-07-30 16:44:50 +02:00 committed by Alexandre Julliard
parent 7fcce036da
commit 60f4db0345
3 changed files with 57 additions and 63 deletions

View File

@ -23,9 +23,6 @@
#define DS_TIME_RES 2 /* Resolution of multimedia timer */
#define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
#define DS_HEL_FRAGS 0x10 /* HEL only: number of waveOut fragments in primary buffer
* (changing this won't help you) */
/* direct sound hardware acceleration levels */
#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
@ -83,8 +80,8 @@ struct DirectSoundDevice
DWORD priolevel;
PWAVEFORMATEX pwfx;
HWAVEOUT hwo;
LPWAVEHDR pwave[DS_HEL_FRAGS];
UINT timerID, pwplay, pwqueue, prebuf;
LPWAVEHDR pwave;
UINT timerID, pwplay, pwqueue, prebuf, helfrags;
DWORD fraglen;
PIDSDRIVERBUFFER hwbuf;
LPBYTE buffer;

View File

@ -753,7 +753,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
TRACE("(%p)\n", device);
/* calculate the current wave frag position */
wave_fragpos = (device->pwplay + device->pwqueue) % DS_HEL_FRAGS;
wave_fragpos = (device->pwplay + device->pwqueue) % device->helfrags;
/* calculte the current wave write position */
wave_writepos = wave_fragpos * device->fraglen;
@ -787,9 +787,9 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
/* queue up the new buffers */
for(i=0; i<prebuf_frags; i++){
TRACE("queueing wave buffer %i\n", wave_fragpos);
waveOutWrite(device->hwo, device->pwave[wave_fragpos], sizeof(WAVEHDR));
waveOutWrite(device->hwo, &device->pwave[wave_fragpos], sizeof(WAVEHDR));
wave_fragpos++;
wave_fragpos %= DS_HEL_FRAGS;
wave_fragpos %= device->helfrags;
}
/* **** */
@ -1030,7 +1030,7 @@ void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, D
/* update playpos */
device->pwplay++;
device->pwplay %= DS_HEL_FRAGS;
device->pwplay %= device->helfrags;
/* sanity */
if(device->pwqueue == 0){

View File

@ -39,31 +39,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
{
DWORD nBlockAlign;
DWORD fraglen;
TRACE("(%p)\n", device);
nBlockAlign = device->pwfx->nBlockAlign;
if (device->hwbuf) {
DWORD fraglen;
/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
* If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
fraglen = 512 * nBlockAlign;
/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
* If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
fraglen = 512 * nBlockAlign;
/* Compensate for only being roughly accurate */
if (device->pwfx->nSamplesPerSec <= 26000)
fraglen /= 2;
/* Compensate for only being roughly accurate */
if (device->pwfx->nSamplesPerSec <= 26000)
fraglen /= 2;
if (device->pwfx->nSamplesPerSec <= 12000)
fraglen /= 2;
if (device->pwfx->nSamplesPerSec <= 12000)
fraglen /= 2;
if (device->pwfx->nSamplesPerSec >= 80000)
fraglen *= 2;
if (device->pwfx->nSamplesPerSec >= 80000)
fraglen *= 2;
/* If in emulation mode, reduce fragment size until an integer number of them fits in the buffer */
if (!device->driver)
while (device->buflen % fraglen)
fraglen -= nBlockAlign;
device->fraglen = fraglen;
device->helfrags = device->buflen / fraglen;
TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
/* reduce fragment size until an integer number of them fits in the buffer */
/* (FIXME: this may or may not be a good idea) */
while (device->buflen % fraglen) fraglen -= nBlockAlign;
device->fraglen = fraglen;
TRACE("fraglen=%d\n", device->fraglen);
}
if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
device->writelead = 0;
else
@ -79,6 +80,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
/* are we using waveOut stuff? */
if (!device->driver) {
LPBYTE newbuf;
LPWAVEHDR headers = NULL;
DWORD buflen;
HRESULT merr = DS_OK;
/* Start in pause mode, to allow buffers to get filled */
@ -89,6 +91,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
/* on original windows, the buffer it set to a fixed size, no matter what the settings are.
on windows this size is always fixed (tested on win-xp) */
buflen = ds_hel_buflen;
buflen -= ds_hel_buflen % device->pwfx->nBlockAlign;
TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
@ -98,6 +101,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
else
newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
if (newbuf == NULL) {
ERR("failed to allocate primary buffer\n");
merr = DSERR_OUTOFMEMORY;
@ -108,27 +112,38 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device->buffer = newbuf;
device->buflen = buflen;
}
if (device->buffer) {
DSOUND_RecalcPrimary(device);
if (device->pwave)
headers = HeapReAlloc(GetProcessHeap(),0,device->pwave, device->helfrags * sizeof(WAVEHDR));
else
headers = HeapAlloc(GetProcessHeap(),0,device->helfrags * sizeof(WAVEHDR));
if (!headers) {
ERR("failed to allocate wave headers\n");
merr = DSERR_OUTOFMEMORY;
}
else if (device->buffer) {
unsigned c;
device->fraglen = device->buflen / DS_HEL_FRAGS;
device->pwave = headers;
/* sanity */
if(device->buflen % DS_HEL_FRAGS){
ERR("Bad DS_HEL_FRAGS resolution\n");
if(device->buflen % device->helfrags){
ERR("Bad helfrags resolution\n");
}
/* prepare fragment headers */
for (c=0; c<DS_HEL_FRAGS; c++) {
device->pwave[c]->lpData = (char*)device->buffer + c*device->fraglen;
device->pwave[c]->dwBufferLength = device->fraglen;
device->pwave[c]->dwUser = (DWORD)device;
device->pwave[c]->dwFlags = 0;
device->pwave[c]->dwLoops = 0;
err = mmErr(waveOutPrepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR)));
for (c=0; c<device->helfrags; c++) {
device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
device->pwave[c].dwBufferLength = device->fraglen;
device->pwave[c].dwUser = (DWORD)device;
device->pwave[c].dwFlags = 0;
device->pwave[c].dwLoops = 0;
err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
if (err != DS_OK) {
while (c--)
waveOutUnprepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR));
waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
break;
}
}
@ -160,6 +175,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device->mixpos = 0;
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
}
DSOUND_RecalcPrimary(device);
return err;
}
@ -178,8 +194,8 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device)
/* **** */
device->pwqueue = (DWORD)-1; /* resetting queues */
waveOutReset(device->hwo);
for (c=0; c<DS_HEL_FRAGS; c++)
waveOutUnprepareHeader(device->hwo, device->pwave[c], sizeof(WAVEHDR));
for (c=0; c<device->helfrags; c++)
waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
/* **** */
EnterCriticalSection(&(device->mixlock));
@ -212,21 +228,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
return err;
}
}
if (!device->hwbuf) {
/* Allocate memory for HEL buffer headers */
unsigned c;
for (c=0; c<DS_HEL_FRAGS; c++) {
device->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
if (!device->pwave[c]) {
/* Argh, out of memory */
while (c--) {
HeapFree(GetProcessHeap(),0,device->pwave[c]);
}
WARN("out of memory\n");
return DSERR_OUTOFMEMORY;
}
}
}
err = DSOUND_PrimaryOpen(device);
@ -235,8 +236,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
return err;
}
/* calculate fragment size and write lead */
DSOUND_RecalcPrimary(device);
device->state = STATE_STOPPED;
return DS_OK;
}
@ -255,10 +254,8 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
device->hwbuf = 0;
}
} else {
unsigned c;
for (c=0; c<DS_HEL_FRAGS; c++) {
HeapFree(GetProcessHeap(),0,device->pwave[c]);
}
if (device->pwave)
HeapFree(GetProcessHeap(),0,device->pwave);
}
HeapFree(GetProcessHeap(),0,device->pwfx);
device->pwfx=NULL;
@ -459,8 +456,8 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
goto done;
}
/* FIXME: should we set err back to DS_OK in all cases ? */
DSOUND_RecalcPrimary(device);
}
DSOUND_RecalcPrimary(device);
if (nSamplesPerSec != device->pwfx->nSamplesPerSec) {
IDirectSoundBufferImpl** dsb = device->buffers;