From 60f4db034521c57ce7d418511cd604849d0f72c6 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 30 Jul 2007 16:44:50 +0200 Subject: [PATCH] dsound: Get rid of DS_HEL_FRAGS. --- dlls/dsound/dsound_private.h | 7 +-- dlls/dsound/mixer.c | 8 +-- dlls/dsound/primary.c | 105 +++++++++++++++++------------------ 3 files changed, 57 insertions(+), 63 deletions(-) diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 98575e32880..91ac107c92b 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -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; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index d927df96a7d..6390584e21c 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -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; ihwo, 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){ diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index dfcf10778f4..0b7986fced2 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -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; cpwave[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; chelfrags; 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; chwo, device->pwave[c], sizeof(WAVEHDR)); + for (c=0; chelfrags; 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; cpwave[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; cpwave[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;