Commit 60f4db03 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

dsound: Get rid of DS_HEL_FRAGS.

parent 7fcce036
...@@ -23,9 +23,6 @@ ...@@ -23,9 +23,6 @@
#define DS_TIME_RES 2 /* Resolution of multimedia timer */ #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_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 */ /* direct sound hardware acceleration levels */
#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */ #define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */ #define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
...@@ -83,8 +80,8 @@ struct DirectSoundDevice ...@@ -83,8 +80,8 @@ struct DirectSoundDevice
DWORD priolevel; DWORD priolevel;
PWAVEFORMATEX pwfx; PWAVEFORMATEX pwfx;
HWAVEOUT hwo; HWAVEOUT hwo;
LPWAVEHDR pwave[DS_HEL_FRAGS]; LPWAVEHDR pwave;
UINT timerID, pwplay, pwqueue, prebuf; UINT timerID, pwplay, pwqueue, prebuf, helfrags;
DWORD fraglen; DWORD fraglen;
PIDSDRIVERBUFFER hwbuf; PIDSDRIVERBUFFER hwbuf;
LPBYTE buffer; LPBYTE buffer;
......
...@@ -753,7 +753,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force) ...@@ -753,7 +753,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
TRACE("(%p)\n", device); TRACE("(%p)\n", device);
/* calculate the current wave frag position */ /* 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 */ /* calculte the current wave write position */
wave_writepos = wave_fragpos * device->fraglen; wave_writepos = wave_fragpos * device->fraglen;
...@@ -787,9 +787,9 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force) ...@@ -787,9 +787,9 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
/* queue up the new buffers */ /* queue up the new buffers */
for(i=0; i<prebuf_frags; i++){ for(i=0; i<prebuf_frags; i++){
TRACE("queueing wave buffer %i\n", wave_fragpos); 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++;
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 ...@@ -1030,7 +1030,7 @@ void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, D
/* update playpos */ /* update playpos */
device->pwplay++; device->pwplay++;
device->pwplay %= DS_HEL_FRAGS; device->pwplay %= device->helfrags;
/* sanity */ /* sanity */
if(device->pwqueue == 0){ if(device->pwqueue == 0){
......
...@@ -39,31 +39,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); ...@@ -39,31 +39,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
static void DSOUND_RecalcPrimary(DirectSoundDevice *device) static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
{ {
DWORD nBlockAlign; DWORD nBlockAlign;
DWORD fraglen;
TRACE("(%p)\n", device); TRACE("(%p)\n", device);
nBlockAlign = device->pwfx->nBlockAlign; nBlockAlign = device->pwfx->nBlockAlign;
if (device->hwbuf) { /* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
DWORD fraglen; * If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2, fraglen = 512 * nBlockAlign;
* 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)
/* Compensate for only being roughly accurate */ fraglen /= 2;
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)
/* reduce fragment size until an integer number of them fits in the buffer */ while (device->buflen % fraglen)
/* (FIXME: this may or may not be a good idea) */ fraglen -= nBlockAlign;
while (device->buflen % fraglen) fraglen -= nBlockAlign; device->fraglen = fraglen;
device->fraglen = fraglen; device->helfrags = device->buflen / fraglen;
TRACE("fraglen=%d\n", device->fraglen); TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
}
if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD) if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
device->writelead = 0; device->writelead = 0;
else else
...@@ -79,6 +80,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -79,6 +80,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
/* are we using waveOut stuff? */ /* are we using waveOut stuff? */
if (!device->driver) { if (!device->driver) {
LPBYTE newbuf; LPBYTE newbuf;
LPWAVEHDR headers = NULL;
DWORD buflen; DWORD buflen;
HRESULT merr = DS_OK; HRESULT merr = DS_OK;
/* Start in pause mode, to allow buffers to get filled */ /* Start in pause mode, to allow buffers to get filled */
...@@ -89,6 +91,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -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 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) */ on windows this size is always fixed (tested on win-xp) */
buflen = ds_hel_buflen; buflen = ds_hel_buflen;
buflen -= ds_hel_buflen % device->pwfx->nBlockAlign;
TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer); TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
...@@ -98,6 +101,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -98,6 +101,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
else else
newbuf = HeapAlloc(GetProcessHeap(),0,buflen); newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
if (newbuf == NULL) { if (newbuf == NULL) {
ERR("failed to allocate primary buffer\n"); ERR("failed to allocate primary buffer\n");
merr = DSERR_OUTOFMEMORY; merr = DSERR_OUTOFMEMORY;
...@@ -108,27 +112,38 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -108,27 +112,38 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device->buffer = newbuf; device->buffer = newbuf;
device->buflen = buflen; 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; unsigned c;
device->fraglen = device->buflen / DS_HEL_FRAGS; device->pwave = headers;
/* sanity */ /* sanity */
if(device->buflen % DS_HEL_FRAGS){ if(device->buflen % device->helfrags){
ERR("Bad DS_HEL_FRAGS resolution\n"); ERR("Bad helfrags resolution\n");
} }
/* prepare fragment headers */ /* prepare fragment headers */
for (c=0; c<DS_HEL_FRAGS; c++) { for (c=0; c<device->helfrags; c++) {
device->pwave[c]->lpData = (char*)device->buffer + c*device->fraglen; device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
device->pwave[c]->dwBufferLength = device->fraglen; device->pwave[c].dwBufferLength = device->fraglen;
device->pwave[c]->dwUser = (DWORD)device; device->pwave[c].dwUser = (DWORD)device;
device->pwave[c]->dwFlags = 0; device->pwave[c].dwFlags = 0;
device->pwave[c]->dwLoops = 0; device->pwave[c].dwLoops = 0;
err = mmErr(waveOutPrepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR))); err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
if (err != DS_OK) { if (err != DS_OK) {
while (c--) while (c--)
waveOutUnprepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR)); waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
break; break;
} }
} }
...@@ -160,6 +175,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) ...@@ -160,6 +175,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device->mixpos = 0; device->mixpos = 0;
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0); FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
} }
DSOUND_RecalcPrimary(device);
return err; return err;
} }
...@@ -178,8 +194,8 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device) ...@@ -178,8 +194,8 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device)
/* **** */ /* **** */
device->pwqueue = (DWORD)-1; /* resetting queues */ device->pwqueue = (DWORD)-1; /* resetting queues */
waveOutReset(device->hwo); waveOutReset(device->hwo);
for (c=0; c<DS_HEL_FRAGS; c++) for (c=0; c<device->helfrags; c++)
waveOutUnprepareHeader(device->hwo, device->pwave[c], sizeof(WAVEHDR)); waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
/* **** */ /* **** */
EnterCriticalSection(&(device->mixlock)); EnterCriticalSection(&(device->mixlock));
...@@ -212,21 +228,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) ...@@ -212,21 +228,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
return err; 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); err = DSOUND_PrimaryOpen(device);
...@@ -235,8 +236,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) ...@@ -235,8 +236,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
return err; return err;
} }
/* calculate fragment size and write lead */
DSOUND_RecalcPrimary(device);
device->state = STATE_STOPPED; device->state = STATE_STOPPED;
return DS_OK; return DS_OK;
} }
...@@ -255,10 +254,8 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) ...@@ -255,10 +254,8 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
device->hwbuf = 0; device->hwbuf = 0;
} }
} else { } else {
unsigned c; if (device->pwave)
for (c=0; c<DS_HEL_FRAGS; c++) { HeapFree(GetProcessHeap(),0,device->pwave);
HeapFree(GetProcessHeap(),0,device->pwave[c]);
}
} }
HeapFree(GetProcessHeap(),0,device->pwfx); HeapFree(GetProcessHeap(),0,device->pwfx);
device->pwfx=NULL; device->pwfx=NULL;
...@@ -459,8 +456,8 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) ...@@ -459,8 +456,8 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
goto done; goto done;
} }
/* FIXME: should we set err back to DS_OK in all cases ? */ /* FIXME: should we set err back to DS_OK in all cases ? */
DSOUND_RecalcPrimary(device);
} }
DSOUND_RecalcPrimary(device);
if (nSamplesPerSec != device->pwfx->nSamplesPerSec) { if (nSamplesPerSec != device->pwfx->nSamplesPerSec) {
IDirectSoundBufferImpl** dsb = device->buffers; IDirectSoundBufferImpl** dsb = device->buffers;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment