Maarten Lankhorst : dsound: Get rid of DS_HEL_FRAGS.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Aug 1 05:16:44 CDT 2007
Module: wine
Branch: master
Commit: 60f4db034521c57ce7d418511cd604849d0f72c6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=60f4db034521c57ce7d418511cd604849d0f72c6
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Mon Jul 30 16:44:50 2007 +0200
dsound: Get rid of DS_HEL_FRAGS.
---
dlls/dsound/dsound_private.h | 7 +--
dlls/dsound/mixer.c | 8 ++--
dlls/dsound/primary.c | 113 ++++++++++++++++++++---------------------
3 files changed, 61 insertions(+), 67 deletions(-)
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 98575e3..91ac107 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 d927df9..6390584 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; 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){
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index dfcf107..0b7986f 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;
-
- /* Compensate for only being roughly accurate */
- if (device->pwfx->nSamplesPerSec <= 26000)
- fraglen /= 2;
-
- if (device->pwfx->nSamplesPerSec <= 12000)
- fraglen /= 2;
-
- if (device->pwfx->nSamplesPerSec >= 80000)
- fraglen *= 2;
-
- /* 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);
- }
+ /* 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;
+
+ if (device->pwfx->nSamplesPerSec <= 12000)
+ 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);
+
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;
More information about the wine-cvs
mailing list