Allocate wave format structure dynamically based on format.
Remove format checks to allow driver to decide if format supported. Code cleanups.
This commit is contained in:
parent
cae33167d2
commit
dfe3c1c579
|
@ -161,7 +161,7 @@ HRESULT WINAPI IDirectSoundNotifyImpl_Create(
|
|||
IDirectSoundNotifyImpl * dsn;
|
||||
TRACE("(%p,%p)\n",dsb,pdsn);
|
||||
|
||||
dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsn));
|
||||
dsn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsn));
|
||||
|
||||
if (dsn == NULL) {
|
||||
WARN("out of memory\n");
|
||||
|
@ -285,7 +285,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
|
|||
}
|
||||
|
||||
if (freq == DSBFREQUENCY_ORIGINAL)
|
||||
freq = This->wfx.nSamplesPerSec;
|
||||
freq = This->pwfx->nSamplesPerSec;
|
||||
|
||||
if ((freq < DSBFREQUENCY_MIN) || (freq > DSBFREQUENCY_MAX)) {
|
||||
WARN("invalid parameter: freq = %ld\n", freq);
|
||||
|
@ -298,8 +298,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
|
|||
oldFreq = This->freq;
|
||||
This->freq = freq;
|
||||
if (freq != oldFreq) {
|
||||
This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->wfx.nSamplesPerSec;
|
||||
This->nAvgBytesPerSec = freq * This->wfx.nBlockAlign;
|
||||
This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->pwfx->nSamplesPerSec;
|
||||
This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
|
||||
DSOUND_RecalcFormat(This);
|
||||
if (!This->hwbuf)
|
||||
DSOUND_ForceRemix(This);
|
||||
|
@ -432,6 +432,9 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
|
|||
if (This->notifies != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, This->notifies);
|
||||
|
||||
if (This->pwfx)
|
||||
HeapFree(GetProcessHeap(), 0, This->pwfx);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
||||
TRACE("(%p) released\n",This);
|
||||
|
@ -469,12 +472,12 @@ DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
|
|||
pmix = 0;
|
||||
}
|
||||
/* divide the offset by its sample size */
|
||||
pmix /= This->dsound->wfx.nBlockAlign;
|
||||
pmix /= This->dsound->pwfx->nBlockAlign;
|
||||
TRACE("primary back-samples=%ld\n",pmix);
|
||||
/* adjust for our frequency */
|
||||
pmix = (pmix * This->freqAdjust) >> DSOUND_FREQSHIFT;
|
||||
/* multiply by our own sample size */
|
||||
pmix *= This->wfx.nBlockAlign;
|
||||
pmix *= This->pwfx->nBlockAlign;
|
||||
TRACE("this back-offset=%ld\n", pmix);
|
||||
/* subtract from our last mixed position */
|
||||
bplay = bmix;
|
||||
|
@ -501,13 +504,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
|
|||
WARN("IDsDriverBuffer_GetPosition failed\n");
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (playpos && (This->state != STATE_PLAYING)) {
|
||||
/* we haven't been merged into the primary buffer (yet) */
|
||||
*playpos = This->buf_mixpos;
|
||||
}
|
||||
else if (playpos) {
|
||||
} else if (playpos) {
|
||||
DWORD pplay, pwrite, lplay, splay, pstate;
|
||||
/* let's get this exact; first, recursively call GetPosition on the primary */
|
||||
EnterCriticalSection(&(This->dsound->mixlock));
|
||||
|
@ -538,21 +539,23 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
|
|||
/* let's just do what might work for Half-Life */
|
||||
DWORD wp;
|
||||
wp = (This->dsound->pwplay + ds_hel_margin) * This->dsound->fraglen;
|
||||
while (wp >= This->dsound->buflen)
|
||||
wp -= This->dsound->buflen;
|
||||
wp %= This->dsound->buflen;
|
||||
*playpos = DSOUND_CalcPlayPosition(This, pstate, wp, pwrite, lplay, splay);
|
||||
}
|
||||
LeaveCriticalSection(&(This->dsound->mixlock));
|
||||
}
|
||||
if (writepos) *writepos = This->buf_mixpos;
|
||||
if (writepos)
|
||||
*writepos = This->buf_mixpos;
|
||||
}
|
||||
if (writepos) {
|
||||
if (This->state != STATE_STOPPED)
|
||||
if (This->state != STATE_STOPPED) {
|
||||
/* apply the documented 10ms lead to writepos */
|
||||
*writepos += This->writelead;
|
||||
while (*writepos >= This->buflen) *writepos -= This->buflen;
|
||||
}
|
||||
*writepos %= This->buflen;
|
||||
}
|
||||
if (playpos) This->last_playpos = *playpos;
|
||||
if (playpos)
|
||||
This->last_playpos = *playpos;
|
||||
TRACE("playpos = %ld, writepos = %ld (%p, time=%ld)\n", playpos?*playpos:0, writepos?*writepos:0, This, GetTickCount());
|
||||
return DS_OK;
|
||||
}
|
||||
|
@ -581,27 +584,38 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(
|
|||
|
||||
|
||||
static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
|
||||
) {
|
||||
ICOM_THIS(IDirectSoundBufferImpl,iface);
|
||||
TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX lpwf,
|
||||
DWORD wfsize,
|
||||
LPDWORD wfwritten)
|
||||
{
|
||||
DWORD size;
|
||||
ICOM_THIS(IDirectSoundBufferImpl,iface);
|
||||
TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
|
||||
|
||||
if (wfsize>sizeof(This->wfx))
|
||||
wfsize = sizeof(This->wfx);
|
||||
if (lpwf) { /* NULL is valid */
|
||||
memcpy(lpwf,&(This->wfx),wfsize);
|
||||
if (wfwritten)
|
||||
*wfwritten = wfsize;
|
||||
} else {
|
||||
if (wfwritten)
|
||||
*wfwritten = sizeof(This->wfx);
|
||||
else {
|
||||
WARN("invalid parameter: wfwritten == NULL\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
size = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
|
||||
|
||||
return DS_OK;
|
||||
if (lpwf) { /* NULL is valid */
|
||||
if (wfsize >= size) {
|
||||
memcpy(lpwf,This->pwfx,size);
|
||||
if (wfwritten)
|
||||
*wfwritten = size;
|
||||
} else {
|
||||
WARN("invalid parameter: wfsize to small\n");
|
||||
if (wfwritten)
|
||||
*wfwritten = 0;
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
} else {
|
||||
if (wfwritten)
|
||||
*wfwritten = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
|
||||
else {
|
||||
WARN("invalid parameter: wfwritten == NULL\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
|
||||
|
@ -632,8 +646,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
|
|||
}
|
||||
writecursor += writepos;
|
||||
}
|
||||
while (writecursor >= This->buflen)
|
||||
writecursor -= This->buflen;
|
||||
writecursor %= This->buflen;
|
||||
if (flags & DSBLOCK_ENTIREBUFFER)
|
||||
writebytes = This->buflen;
|
||||
if (writebytes > This->buflen)
|
||||
|
@ -691,8 +704,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
|
|||
if (This->buf_mixpos > writecursor &&
|
||||
This->last_playpos < writecursor+writebytes)
|
||||
remix = TRUE;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (This->buf_mixpos > writecursor ||
|
||||
This->last_playpos < writecursor+writebytes)
|
||||
remix = TRUE;
|
||||
|
@ -718,8 +730,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition(
|
|||
/* **** */
|
||||
EnterCriticalSection(&(This->lock));
|
||||
|
||||
while (newpos >= This->buflen)
|
||||
newpos -= This->buflen;
|
||||
newpos %= This->buflen;
|
||||
This->buf_mixpos = newpos;
|
||||
if (This->hwbuf) {
|
||||
hres = IDsDriverBuffer_SetPosition(This->hwbuf, This->buf_mixpos);
|
||||
|
@ -803,10 +814,14 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
|
|||
|
||||
TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
|
||||
|
||||
/* **** */
|
||||
EnterCriticalSection(&(This->lock));
|
||||
|
||||
if (!(This->dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
|
||||
HRESULT hres;
|
||||
hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
|
||||
if (hres != DS_OK) {
|
||||
LeaveCriticalSection(&(This->lock));
|
||||
WARN("IDsDriverBuffer_Unlock failed\n");
|
||||
return hres;
|
||||
}
|
||||
|
@ -814,8 +829,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
|
|||
|
||||
if (p2) probably_valid_to = (((LPBYTE)p2)-This->buffer->memory) + x2;
|
||||
else probably_valid_to = (((LPBYTE)p1)-This->buffer->memory) + x1;
|
||||
while (probably_valid_to >= This->buflen)
|
||||
probably_valid_to -= This->buflen;
|
||||
probably_valid_to %= This->buflen;
|
||||
if ((probably_valid_to == 0) && ((x1+x2) == This->buflen) &&
|
||||
((This->state == STATE_STARTING) ||
|
||||
(This->state == STATE_PLAYING)))
|
||||
|
@ -823,6 +837,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
|
|||
probably_valid_to = (DWORD)-1;
|
||||
This->probably_valid_to = probably_valid_to;
|
||||
|
||||
LeaveCriticalSection(&(This->lock));
|
||||
/* **** */
|
||||
|
||||
TRACE("probably_valid_to=%ld\n", This->probably_valid_to);
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
@ -1052,7 +1070,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
LPWAVEFORMATEX wfex = dsbd->lpwfxFormat;
|
||||
HRESULT err = DS_OK;
|
||||
DWORD capf = 0;
|
||||
int use_hw;
|
||||
int use_hw, alloc_size, cp_size;
|
||||
TRACE("(%p,%p,%p)\n",ds,pdsb,dsbd);
|
||||
|
||||
if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
|
||||
|
@ -1061,24 +1079,41 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
return DSERR_INVALIDPARAM; /* FIXME: which error? */
|
||||
}
|
||||
|
||||
dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
|
||||
dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
|
||||
|
||||
if (dsb == 0) {
|
||||
WARN("out of memory\n");
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
TRACE("Created buffer at %p\n", dsb);
|
||||
|
||||
dsb->ref = 0;
|
||||
dsb->dsb = 0;
|
||||
dsb->dsound = ds;
|
||||
dsb->lpVtbl = &dsbvt;
|
||||
dsb->iks = NULL;
|
||||
|
||||
memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd));
|
||||
if (wfex)
|
||||
memcpy(&dsb->wfx, wfex, sizeof(dsb->wfx));
|
||||
/* size depends on version */
|
||||
memcpy(&dsb->dsbd, dsbd, dsbd->dwSize);
|
||||
|
||||
TRACE("Created buffer at %p\n", dsb);
|
||||
/* variable sized struct so calculate size based on format */
|
||||
if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
|
||||
alloc_size = sizeof(WAVEFORMATEX);
|
||||
cp_size = sizeof(PCMWAVEFORMAT);
|
||||
} else
|
||||
alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
|
||||
|
||||
dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,alloc_size);
|
||||
if (dsb->pwfx == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memcpy(dsb->pwfx, wfex, cp_size);
|
||||
|
||||
dsb->buflen = dsbd->dwBufferBytes;
|
||||
dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec;
|
||||
|
@ -1107,14 +1142,16 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
|
||||
if (dsb->buffer == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
if (dsb->buffer->memory == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
|
@ -1136,15 +1173,17 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
|
||||
if (dsb->buffer == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
if (dsb->buffer->memory == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
|
@ -1164,7 +1203,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
dsb->state = STATE_STOPPED;
|
||||
|
||||
dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) /
|
||||
ds->wfx.nSamplesPerSec;
|
||||
ds->pwfx->nSamplesPerSec;
|
||||
dsb->nAvgBytesPerSec = dsb->freq *
|
||||
dsbd->lpwfxFormat->nBlockAlign;
|
||||
|
||||
|
@ -1199,9 +1238,9 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
|
||||
IDirectSoundBufferImpl **newbuffers;
|
||||
if (ds->buffers)
|
||||
newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
|
||||
newbuffers = HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
|
||||
else
|
||||
newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
|
||||
newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
|
||||
|
||||
if (newbuffers) {
|
||||
ds->buffers = newbuffers;
|
||||
|
@ -1216,6 +1255,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
|
|||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
DeleteCriticalSection(&(dsb->lock));
|
||||
RtlReleaseResource(&(ds->lock));
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
|
@ -1545,7 +1585,7 @@ HRESULT WINAPI SecondaryBufferImpl_Create(
|
|||
SecondaryBufferImpl *sb;
|
||||
TRACE("(%p,%p)\n",dsb,psb);
|
||||
|
||||
sb = (SecondaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb));
|
||||
sb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb));
|
||||
|
||||
if (sb == 0) {
|
||||
WARN("out of memory\n");
|
||||
|
|
|
@ -134,7 +134,7 @@ DirectSoundCaptureCreate8(
|
|||
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
|
||||
lpcGUID = &DSDEVID_DefaultCapture;
|
||||
|
||||
*ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
|
||||
*ippDSC = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
|
||||
|
||||
if (*ippDSC == NULL) {
|
||||
|
@ -769,9 +769,9 @@ DSOUND_CreateDirectSoundCaptureBuffer(
|
|||
buflen = lpcDSCBufferDesc->dwBufferBytes;
|
||||
TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->buffer);
|
||||
if (ipDSC->buffer)
|
||||
newbuf = (LPBYTE)HeapReAlloc(GetProcessHeap(),0,ipDSC->buffer,buflen);
|
||||
newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->buffer,buflen);
|
||||
else
|
||||
newbuf = (LPBYTE)HeapAlloc(GetProcessHeap(),0,buflen);
|
||||
newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
|
||||
if (newbuf == NULL) {
|
||||
WARN("failed to allocate capture buffer\n");
|
||||
err = DSERR_OUTOFMEMORY;
|
||||
|
@ -905,7 +905,7 @@ HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
|
|||
IDirectSoundCaptureNotifyImpl * dscn;
|
||||
TRACE("(%p,%p)\n",dscb,pdscn);
|
||||
|
||||
dscn = (IDirectSoundCaptureNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn));
|
||||
dscn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn));
|
||||
|
||||
if (dscn == NULL) {
|
||||
WARN("out of memory\n");
|
||||
|
@ -1736,7 +1736,7 @@ DirectSoundFullDuplexCreate(
|
|||
return DSERR_NOAGGREGATION;
|
||||
}
|
||||
|
||||
*ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
|
||||
*ippDSFD = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
|
||||
|
||||
if (*ippDSFD == NULL) {
|
||||
|
|
|
@ -467,6 +467,7 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
|
|||
IDirectSoundBufferImpl* pdsb;
|
||||
IDirectSoundBufferImpl* dsb;
|
||||
HRESULT hres = DS_OK;
|
||||
int size;
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
|
||||
|
@ -553,7 +554,21 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
|
|||
dsb->ds3db = NULL;
|
||||
dsb->iks = NULL; /* FIXME? */
|
||||
dsb->dsb = NULL;
|
||||
memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
|
||||
|
||||
/* variable sized struct so calculate size based on format */
|
||||
size = sizeof(WAVEFORMATEX) + pdsb->pwfx->cbSize;
|
||||
|
||||
dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
|
||||
if (dsb->pwfx == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*ppdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memcpy(dsb->pwfx, pdsb->pwfx, size);
|
||||
|
||||
InitializeCriticalSection(&(dsb->lock));
|
||||
dsb->lock.DebugInfo->Spare[1] = (DWORD)"DSOUNDBUFFER_lock";
|
||||
/* register buffer */
|
||||
|
@ -575,6 +590,8 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
|
|||
IDirectSoundBuffer8_Release(psb);
|
||||
DeleteCriticalSection(&(dsb->lock));
|
||||
RtlReleaseResource(&(This->lock));
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb->pwfx);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*ppdsb = 0;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
|
@ -821,9 +838,9 @@ HRESULT WINAPI IDirectSoundImpl_Create(
|
|||
err = IDsDriver_GetDriverDesc(drv,&(pDS->drvdesc));
|
||||
if (err != DS_OK) {
|
||||
WARN("IDsDriver_GetDriverDesc failed\n");
|
||||
HeapFree(GetProcessHeap(),0,pDS);
|
||||
*ppDS = NULL;
|
||||
return err;
|
||||
HeapFree(GetProcessHeap(),0,pDS);
|
||||
*ppDS = NULL;
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* if no DirectSound interface available, use WINMM API instead */
|
||||
|
@ -833,17 +850,25 @@ HRESULT WINAPI IDirectSoundImpl_Create(
|
|||
pDS->drvdesc.dnDevNode = wod;
|
||||
|
||||
/* Set default wave format (may need it for waveOutOpen) */
|
||||
pDS->wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
pDS->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEX));
|
||||
if (pDS->pwfx == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,pDS);
|
||||
*ppDS = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
pDS->pwfx->wFormatTag = WAVE_FORMAT_PCM;
|
||||
/* We rely on the sound driver to return the actual sound format of
|
||||
* the device if it does not support 22050x8x2 and is given the
|
||||
* WAVE_DIRECTSOUND flag.
|
||||
*/
|
||||
pDS->wfx.nSamplesPerSec = 22050;
|
||||
pDS->wfx.wBitsPerSample = 8;
|
||||
pDS->wfx.nChannels = 2;
|
||||
pDS->wfx.nBlockAlign = pDS->wfx.wBitsPerSample * pDS->wfx.nChannels / 8;
|
||||
pDS->wfx.nAvgBytesPerSec = pDS->wfx.nSamplesPerSec * pDS->wfx.nBlockAlign;
|
||||
pDS->wfx.cbSize = 0;
|
||||
pDS->pwfx->nSamplesPerSec = 22050;
|
||||
pDS->pwfx->wBitsPerSample = 8;
|
||||
pDS->pwfx->nChannels = 2;
|
||||
pDS->pwfx->nBlockAlign = pDS->pwfx->wBitsPerSample * pDS->pwfx->nChannels / 8;
|
||||
pDS->pwfx->nAvgBytesPerSec = pDS->pwfx->nSamplesPerSec * pDS->pwfx->nBlockAlign;
|
||||
pDS->pwfx->cbSize = 0;
|
||||
|
||||
/* If the driver requests being opened through MMSYSTEM
|
||||
* (which is recommended by the DDK), it is supposed to happen
|
||||
|
@ -857,7 +882,7 @@ HRESULT WINAPI IDirectSoundImpl_Create(
|
|||
flags |= WAVE_DIRECTSOUND;
|
||||
|
||||
err = mmErr(waveOutOpen(&(pDS->hwo),
|
||||
pDS->drvdesc.dnDevNode, &(pDS->wfx),
|
||||
pDS->drvdesc.dnDevNode, pDS->pwfx,
|
||||
(DWORD)DSOUND_callback, (DWORD)pDS,
|
||||
flags));
|
||||
if (err != DS_OK) {
|
||||
|
|
|
@ -78,7 +78,7 @@ struct IDirectSoundImpl
|
|||
DSDRIVERDESC drvdesc;
|
||||
DSDRIVERCAPS drvcaps;
|
||||
DWORD priolevel;
|
||||
WAVEFORMATEX wfx; /* current main waveformat */
|
||||
PWAVEFORMATEX pwfx;
|
||||
HWAVEOUT hwo;
|
||||
LPWAVEHDR pwave[DS_HEL_FRAGS];
|
||||
UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
|
||||
|
@ -197,7 +197,7 @@ struct IDirectSoundBufferImpl
|
|||
IDirectSoundImpl* dsound;
|
||||
CRITICAL_SECTION lock;
|
||||
PIDSDRIVERBUFFER hwbuf;
|
||||
WAVEFORMATEX wfx;
|
||||
PWAVEFORMATEX pwfx;
|
||||
BufferMemory* buffer;
|
||||
DWORD playflags,state,leadin;
|
||||
DWORD playpos,startpos,writelead,buflen;
|
||||
|
|
|
@ -106,7 +106,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
|
|||
DWORD sw;
|
||||
TRACE("(%p)\n",dsb);
|
||||
|
||||
sw = dsb->wfx.nChannels * (dsb->wfx.wBitsPerSample / 8);
|
||||
sw = dsb->pwfx->nChannels * (dsb->pwfx->wBitsPerSample / 8);
|
||||
/* calculate the 10ms write lead */
|
||||
dsb->writelead = (dsb->freq / 100) * sw;
|
||||
}
|
||||
|
@ -180,41 +180,41 @@ static inline void cp_fields(const IDirectSoundBufferImpl *dsb, BYTE *ibuf, BYTE
|
|||
{
|
||||
INT fl,fr;
|
||||
|
||||
if (dsb->wfx.wBitsPerSample == 8) {
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 8 &&
|
||||
dsb->dsound->wfx.nChannels == dsb->wfx.nChannels) {
|
||||
if (dsb->pwfx->wBitsPerSample == 8) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 8 &&
|
||||
dsb->dsound->pwfx->nChannels == dsb->pwfx->nChannels) {
|
||||
/* avoid needless 8->16->8 conversion */
|
||||
*obuf=*ibuf;
|
||||
if (dsb->wfx.nChannels==2)
|
||||
if (dsb->pwfx->nChannels==2)
|
||||
*(obuf+1)=*(ibuf+1);
|
||||
return;
|
||||
}
|
||||
fl = cvtU8toS16(*ibuf);
|
||||
fr = (dsb->wfx.nChannels==2 ? cvtU8toS16(*(ibuf + 1)) : fl);
|
||||
fr = (dsb->pwfx->nChannels==2 ? cvtU8toS16(*(ibuf + 1)) : fl);
|
||||
} else {
|
||||
fl = *((INT16 *)ibuf);
|
||||
fr = (dsb->wfx.nChannels==2 ? *(((INT16 *)ibuf) + 1) : fl);
|
||||
fr = (dsb->pwfx->nChannels==2 ? *(((INT16 *)ibuf) + 1) : fl);
|
||||
}
|
||||
|
||||
if (dsb->dsound->wfx.nChannels == 2) {
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 8) {
|
||||
if (dsb->dsound->pwfx->nChannels == 2) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 8) {
|
||||
*obuf = cvtS16toU8(fl);
|
||||
*(obuf + 1) = cvtS16toU8(fr);
|
||||
return;
|
||||
}
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 16) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 16) {
|
||||
*((INT16 *)obuf) = fl;
|
||||
*(((INT16 *)obuf) + 1) = fr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (dsb->dsound->wfx.nChannels == 1) {
|
||||
if (dsb->dsound->pwfx->nChannels == 1) {
|
||||
fl = (fl + fr) >> 1;
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 8) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 8) {
|
||||
*obuf = cvtS16toU8(fl);
|
||||
return;
|
||||
}
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 16) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 16) {
|
||||
*((INT16 *)obuf) = fl;
|
||||
return;
|
||||
}
|
||||
|
@ -226,17 +226,17 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
{
|
||||
INT i, size, ipos, ilen;
|
||||
BYTE *ibp, *obp;
|
||||
INT iAdvance = dsb->wfx.nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->wfx.nBlockAlign;
|
||||
INT iAdvance = dsb->pwfx->nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->pwfx->nBlockAlign;
|
||||
|
||||
ibp = dsb->buffer->memory + dsb->buf_mixpos;
|
||||
obp = buf;
|
||||
|
||||
TRACE("(%p, %p, %p), buf_mixpos=%ld\n", dsb, ibp, obp, dsb->buf_mixpos);
|
||||
/* Check for the best case */
|
||||
if ((dsb->freq == dsb->dsound->wfx.nSamplesPerSec) &&
|
||||
(dsb->wfx.wBitsPerSample == dsb->dsound->wfx.wBitsPerSample) &&
|
||||
(dsb->wfx.nChannels == dsb->dsound->wfx.nChannels)) {
|
||||
if ((dsb->freq == dsb->dsound->pwfx->nSamplesPerSec) &&
|
||||
(dsb->pwfx->wBitsPerSample == dsb->dsound->pwfx->wBitsPerSample) &&
|
||||
(dsb->pwfx->nChannels == dsb->dsound->pwfx->nChannels)) {
|
||||
DWORD bytesleft = dsb->buflen - dsb->buf_mixpos;
|
||||
TRACE("(%p) Best case\n", dsb);
|
||||
if (len <= bytesleft )
|
||||
|
@ -249,9 +249,9 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
}
|
||||
|
||||
/* Check for same sample rate */
|
||||
if (dsb->freq == dsb->dsound->wfx.nSamplesPerSec) {
|
||||
if (dsb->freq == dsb->dsound->pwfx->nSamplesPerSec) {
|
||||
TRACE("(%p) Same sample rate %ld = primary %ld\n", dsb,
|
||||
dsb->freq, dsb->dsound->wfx.nSamplesPerSec);
|
||||
dsb->freq, dsb->dsound->pwfx->nSamplesPerSec);
|
||||
ilen = 0;
|
||||
for (i = 0; i < len; i += oAdvance) {
|
||||
cp_fields(dsb, ibp, obp );
|
||||
|
@ -273,7 +273,7 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
* TransGaming Technologies Inc. */
|
||||
|
||||
/* FIXME("(%p) Adjusting frequency: %ld -> %ld (need optimization)\n",
|
||||
dsb, dsb->freq, dsb->dsound->wfx.nSamplesPerSec); */
|
||||
dsb, dsb->freq, dsb->dsound->pwfx->nSamplesPerSec); */
|
||||
|
||||
size = len / oAdvance;
|
||||
ilen = 0;
|
||||
|
@ -286,8 +286,7 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
ULONG adv = (dsb->freqAcc>>DSOUND_FREQSHIFT) * iAdvance;
|
||||
dsb->freqAcc &= (1<<DSOUND_FREQSHIFT)-1;
|
||||
ipos += adv; ilen += adv;
|
||||
while (ipos >= dsb->buflen)
|
||||
ipos -= dsb->buflen;
|
||||
ipos %= dsb->buflen;
|
||||
}
|
||||
}
|
||||
return ilen;
|
||||
|
@ -312,11 +311,11 @@ static void DSOUND_MixerVol(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
/* with a mono primary buffer, it could sound very weird using */
|
||||
/* this method. Oh well, tough patooties. */
|
||||
|
||||
switch (dsb->dsound->wfx.wBitsPerSample) {
|
||||
switch (dsb->dsound->pwfx->wBitsPerSample) {
|
||||
case 8:
|
||||
/* 8-bit WAV is unsigned, but we need to operate */
|
||||
/* on signed data for this to work properly */
|
||||
switch (dsb->dsound->wfx.nChannels) {
|
||||
switch (dsb->dsound->pwfx->nChannels) {
|
||||
case 1:
|
||||
for (i = 0; i < len; i++) {
|
||||
INT val = *bpc - 128;
|
||||
|
@ -337,13 +336,13 @@ static void DSOUND_MixerVol(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("doesn't support %d channels\n", dsb->dsound->wfx.nChannels);
|
||||
FIXME("doesn't support %d channels\n", dsb->dsound->pwfx->nChannels);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
/* 16-bit WAV is signed -- much better */
|
||||
switch (dsb->dsound->wfx.nChannels) {
|
||||
switch (dsb->dsound->pwfx->nChannels) {
|
||||
case 1:
|
||||
for (i = 0; i < len; i += 2) {
|
||||
*bps = (*bps * dsb->cvolpan.dwTotalLeftAmpFactor) >> 16;
|
||||
|
@ -359,12 +358,12 @@ static void DSOUND_MixerVol(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("doesn't support %d channels\n", dsb->dsound->wfx.nChannels);
|
||||
FIXME("doesn't support %d channels\n", dsb->dsound->pwfx->nChannels);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("doesn't support %d bit samples\n", dsb->dsound->wfx.wBitsPerSample);
|
||||
FIXME("doesn't support %d bit samples\n", dsb->dsound->pwfx->wBitsPerSample);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -394,13 +393,13 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
|
|||
|
||||
len = fraglen;
|
||||
if (!(dsb->playflags & DSBPLAY_LOOPING)) {
|
||||
temp = MulDiv(dsb->dsound->wfx.nAvgBytesPerSec, dsb->buflen,
|
||||
temp = MulDiv(dsb->dsound->pwfx->nAvgBytesPerSec, dsb->buflen,
|
||||
dsb->nAvgBytesPerSec) -
|
||||
MulDiv(dsb->dsound->wfx.nAvgBytesPerSec, dsb->buf_mixpos,
|
||||
MulDiv(dsb->dsound->pwfx->nAvgBytesPerSec, dsb->buf_mixpos,
|
||||
dsb->nAvgBytesPerSec);
|
||||
len = (len > temp) ? temp : len;
|
||||
}
|
||||
nBlockAlign = dsb->dsound->wfx.nBlockAlign;
|
||||
nBlockAlign = dsb->dsound->pwfx->nBlockAlign;
|
||||
len = len / nBlockAlign * nBlockAlign; /* data alignment */
|
||||
|
||||
if (len == 0) {
|
||||
|
@ -421,7 +420,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
|
|||
(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
|
||||
DSOUND_MixerVol(dsb, ibuf, len);
|
||||
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 8) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 8) {
|
||||
BYTE *obuf = dsb->dsound->buffer + writepos;
|
||||
|
||||
if ((writepos + len) <= dsb->dsound->buflen)
|
||||
|
@ -499,8 +498,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
|
|||
if (dsb->buf_mixpos >= dsb->buflen) {
|
||||
if (dsb->playflags & DSBPLAY_LOOPING) {
|
||||
/* wrap */
|
||||
while (dsb->buf_mixpos >= dsb->buflen)
|
||||
dsb->buf_mixpos -= dsb->buflen;
|
||||
dsb->buf_mixpos %= dsb->buflen;
|
||||
if (dsb->leadin && (dsb->startpos <= dsb->buf_mixpos))
|
||||
dsb->leadin = FALSE; /* HACK: see above */
|
||||
}
|
||||
|
@ -516,7 +514,7 @@ static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWOR
|
|||
|
||||
TRACE("(%p,%ld,%ld)\n",dsb,writepos,len);
|
||||
|
||||
nBlockAlign = dsb->dsound->wfx.nBlockAlign;
|
||||
nBlockAlign = dsb->dsound->pwfx->nBlockAlign;
|
||||
len = len / nBlockAlign * nBlockAlign; /* data alignment */
|
||||
|
||||
TRACE("allocating buffer (size = %ld)\n", len);
|
||||
|
@ -532,7 +530,7 @@ static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWOR
|
|||
DSOUND_MixerVol(dsb, ibuf, len);
|
||||
|
||||
/* subtract instead of add, to phase out premixed data */
|
||||
if (dsb->dsound->wfx.wBitsPerSample == 8) {
|
||||
if (dsb->dsound->pwfx->wBitsPerSample == 8) {
|
||||
BYTE *obuf = dsb->dsound->buffer + writepos;
|
||||
|
||||
if ((writepos + len) <= dsb->dsound->buflen)
|
||||
|
@ -601,8 +599,8 @@ static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWOR
|
|||
static void DSOUND_MixCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, BOOL cancel)
|
||||
{
|
||||
DWORD size, flen, len, npos, nlen;
|
||||
INT iAdvance = dsb->wfx.nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->wfx.nBlockAlign;
|
||||
INT iAdvance = dsb->pwfx->nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->pwfx->nBlockAlign;
|
||||
/* determine amount of premixed data to cancel */
|
||||
DWORD primary_done =
|
||||
((dsb->primary_mixpos < writepos) ? dsb->dsound->buflen : 0) +
|
||||
|
@ -628,9 +626,9 @@ static void DSOUND_MixCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, BOOL c
|
|||
len = ((dsb->buf_mixpos < npos) ? dsb->buflen : 0) +
|
||||
dsb->buf_mixpos - npos;
|
||||
flen = dsb->freqAcc;
|
||||
nlen = len / dsb->wfx.nBlockAlign;
|
||||
nlen = len / dsb->pwfx->nBlockAlign;
|
||||
nlen = ((nlen << DSOUND_FREQSHIFT) + flen) / dsb->freqAdjust;
|
||||
nlen *= dsb->dsound->wfx.nBlockAlign;
|
||||
nlen *= dsb->dsound->pwfx->nBlockAlign;
|
||||
writepos =
|
||||
((dsb->primary_mixpos < nlen) ? dsb->dsound->buflen : 0) +
|
||||
dsb->primary_mixpos - nlen;
|
||||
|
@ -650,8 +648,8 @@ void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos)
|
|||
{
|
||||
#if 0
|
||||
DWORD i, size, flen, len, npos, nlen;
|
||||
INT iAdvance = dsb->wfx.nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->wfx.nBlockAlign;
|
||||
INT iAdvance = dsb->pwfx->nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->pwfx->nBlockAlign;
|
||||
/* determine amount of premixed data to cancel */
|
||||
DWORD buf_done =
|
||||
((dsb->buf_mixpos < buf_writepos) ? dsb->buflen : 0) +
|
||||
|
@ -761,8 +759,8 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
|
|||
/* adjust for our frequency and our sample size */
|
||||
probably_valid_left = MulDiv(probably_valid_left,
|
||||
1 << DSOUND_FREQSHIFT,
|
||||
dsb->wfx.nBlockAlign * dsb->freqAdjust) *
|
||||
dsb->dsound->wfx.nBlockAlign;
|
||||
dsb->pwfx->nBlockAlign * dsb->freqAdjust) *
|
||||
dsb->dsound->pwfx->nBlockAlign;
|
||||
/* check whether to clip mix_len */
|
||||
if (probably_valid_left < mixlen) {
|
||||
TRACE("clipping to probably_valid_left=%ld\n", probably_valid_left);
|
||||
|
@ -800,8 +798,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
|
|||
still_behind = FALSE;
|
||||
|
||||
dsb->primary_mixpos += slen; len -= slen;
|
||||
while (dsb->primary_mixpos >= dsb->dsound->buflen)
|
||||
dsb->primary_mixpos -= dsb->dsound->buflen;
|
||||
dsb->primary_mixpos %= dsb->dsound->buflen;
|
||||
|
||||
if ((dsb->state == STATE_STOPPED) || !slen) break;
|
||||
}
|
||||
|
@ -885,7 +882,7 @@ static void DSOUND_MixReset(IDirectSoundImpl *dsound, DWORD writepos)
|
|||
TRACE("(%ld)\n", writepos);
|
||||
|
||||
/* the sound of silence */
|
||||
nfiller = dsound->wfx.wBitsPerSample == 8 ? 128 : 0;
|
||||
nfiller = dsound->pwfx->wBitsPerSample == 8 ? 128 : 0;
|
||||
|
||||
/* reset all buffer mix positions */
|
||||
for (i = dsound->nrofbuffers - 1; i >= 0; i--) {
|
||||
|
@ -966,7 +963,7 @@ void DSOUND_PerformMix(IDirectSoundImpl *dsound)
|
|||
TRACE("()\n");
|
||||
|
||||
/* the sound of silence */
|
||||
nfiller = dsound->wfx.wBitsPerSample == 8 ? 128 : 0;
|
||||
nfiller = dsound->pwfx->wBitsPerSample == 8 ? 128 : 0;
|
||||
|
||||
/* whether the primary is forced to play even without secondary buffers */
|
||||
forced = ((dsound->state == STATE_PLAYING) || (dsound->state == STATE_STARTING));
|
||||
|
@ -986,16 +983,14 @@ void DSOUND_PerformMix(IDirectSoundImpl *dsound)
|
|||
/* rather add our safety margin to the writepos, if we're playing */
|
||||
if (!paused) {
|
||||
writepos += dsound->writelead;
|
||||
while (writepos >= dsound->buflen)
|
||||
writepos -= dsound->buflen;
|
||||
writepos %= dsound->buflen;
|
||||
} else writepos = playpos;
|
||||
} else {
|
||||
playpos = dsound->pwplay * dsound->fraglen;
|
||||
writepos = playpos;
|
||||
if (!paused) {
|
||||
writepos += ds_hel_margin * dsound->fraglen;
|
||||
while (writepos >= dsound->buflen)
|
||||
writepos -= dsound->buflen;
|
||||
writepos %= dsound->buflen;
|
||||
}
|
||||
}
|
||||
TRACE("primary playpos=%ld, writepos=%ld, clrpos=%ld, mixpos=%ld, buflen=%ld\n",
|
||||
|
@ -1086,8 +1081,7 @@ void DSOUND_PerformMix(IDirectSoundImpl *dsound)
|
|||
frag = DSOUND_MixToPrimary(dsound, playpos, writepos, maxq, paused);
|
||||
if (forced) frag = maxq - inq;
|
||||
dsound->mixpos += frag;
|
||||
while (dsound->mixpos >= dsound->buflen)
|
||||
dsound->mixpos -= dsound->buflen;
|
||||
dsound->mixpos %= dsound->buflen;
|
||||
|
||||
if (frag) {
|
||||
/* buffers have been filled, restart playback */
|
||||
|
|
|
@ -54,11 +54,11 @@ void DSOUND_RecalcPrimary(IDirectSoundImpl *This)
|
|||
DWORD sw;
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
sw = This->wfx.nChannels * (This->wfx.wBitsPerSample / 8);
|
||||
sw = This->pwfx->nChannels * (This->pwfx->wBitsPerSample / 8);
|
||||
if (This->hwbuf) {
|
||||
DWORD fraglen;
|
||||
/* let fragment size approximate the timer delay */
|
||||
fraglen = (This->wfx.nSamplesPerSec * DS_TIME_DEL / 1000) * sw;
|
||||
fraglen = (This->pwfx->nSamplesPerSec * DS_TIME_DEL / 1000) * sw;
|
||||
/* reduce fragment size until an integer number of them fits in the buffer */
|
||||
/* (FIXME: this may or may not be a good idea) */
|
||||
while (This->buflen % fraglen) fraglen -= sw;
|
||||
|
@ -66,7 +66,7 @@ void DSOUND_RecalcPrimary(IDirectSoundImpl *This)
|
|||
TRACE("fraglen=%ld\n", This->fraglen);
|
||||
}
|
||||
/* calculate the 10ms write lead */
|
||||
This->writelead = (This->wfx.nSamplesPerSec / 100) * sw;
|
||||
This->writelead = (This->pwfx->nSamplesPerSec / 100) * sw;
|
||||
}
|
||||
|
||||
static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
|
||||
|
@ -85,14 +85,14 @@ static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
|
|||
else if (This->state == STATE_STOPPING) This->state = STATE_STOPPED;
|
||||
/* use fragments of 10ms (1/100s) each (which should get us within
|
||||
* the documented write cursor lead of 10-15ms) */
|
||||
buflen = ((This->wfx.nAvgBytesPerSec / 100) & ~3) * DS_HEL_FRAGS;
|
||||
buflen = ((This->pwfx->nAvgBytesPerSec / 100) & ~3) * DS_HEL_FRAGS;
|
||||
TRACE("desired buflen=%ld, old buffer=%p\n", buflen, This->buffer);
|
||||
/* reallocate emulated primary buffer */
|
||||
|
||||
if (This->buffer)
|
||||
newbuf = (LPBYTE)HeapReAlloc(GetProcessHeap(),0,This->buffer,buflen);
|
||||
newbuf = HeapReAlloc(GetProcessHeap(),0,This->buffer,buflen);
|
||||
else
|
||||
newbuf = (LPBYTE)HeapAlloc(GetProcessHeap(),0,buflen);
|
||||
newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
|
||||
|
||||
if (newbuf == NULL) {
|
||||
ERR("failed to allocate primary buffer\n");
|
||||
|
@ -127,26 +127,24 @@ static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
|
|||
This->pwqueue = 0;
|
||||
This->playpos = 0;
|
||||
This->mixpos = 0;
|
||||
memset(This->buffer, (This->wfx.wBitsPerSample == 16) ? 0 : 128, This->buflen);
|
||||
memset(This->buffer, (This->pwfx->wBitsPerSample == 16) ? 0 : 128, This->buflen);
|
||||
TRACE("fraglen=%ld\n", This->fraglen);
|
||||
DSOUND_WaveQueue(This, (DWORD)-1);
|
||||
}
|
||||
if ((err == DS_OK) && (merr != DS_OK))
|
||||
err = merr;
|
||||
} else {
|
||||
if (!This->hwbuf) {
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
|
||||
DSBCAPS_PRIMARYBUFFER,0,
|
||||
&(This->buflen),&(This->buffer),
|
||||
(LPVOID*)&(This->hwbuf));
|
||||
if (err != DS_OK) {
|
||||
WARN("IDsDriver_CreateSoundBuffer failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
|
||||
else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
|
||||
} else if (!This->hwbuf) {
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
|
||||
DSBCAPS_PRIMARYBUFFER,0,
|
||||
&(This->buflen),&(This->buffer),
|
||||
(LPVOID*)&(This->hwbuf));
|
||||
if (err != DS_OK) {
|
||||
WARN("IDsDriver_CreateSoundBuffer failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
|
||||
else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -177,12 +175,12 @@ HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This)
|
|||
HRESULT err = DS_OK;
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
This->buflen = This->wfx.nAvgBytesPerSec;
|
||||
This->buflen = This->pwfx->nAvgBytesPerSec;
|
||||
|
||||
/* FIXME: verify that hardware capabilities (DSCAPS_PRIMARY flags) match */
|
||||
|
||||
if (This->driver) {
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
|
||||
DSBCAPS_PRIMARYBUFFER,0,
|
||||
&(This->buflen),&(This->buffer),
|
||||
(LPVOID*)&(This->hwbuf));
|
||||
|
@ -236,6 +234,10 @@ HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This)
|
|||
HeapFree(GetProcessHeap(),0,This->pwave[c]);
|
||||
}
|
||||
}
|
||||
if (This->pwfx) {
|
||||
HeapFree(GetProcessHeap(),0,This->pwfx);
|
||||
This->pwfx=NULL;
|
||||
}
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
@ -274,10 +276,10 @@ HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This)
|
|||
waveOutClose(This->hwo);
|
||||
This->hwo = 0;
|
||||
err = mmErr(waveOutOpen(&(This->hwo), This->drvdesc.dnDevNode,
|
||||
&(This->wfx), (DWORD)DSOUND_callback, (DWORD)This,
|
||||
This->pwfx, (DWORD)DSOUND_callback, (DWORD)This,
|
||||
flags));
|
||||
if (err == DS_OK) {
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
|
||||
DSBCAPS_PRIMARYBUFFER,0,
|
||||
&(This->buflen),&(This->buffer),
|
||||
(LPVOID)&(This->hwbuf));
|
||||
|
@ -307,8 +309,7 @@ HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWO
|
|||
WARN("IDsDriverBuffer_GetPosition failed\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (playpos) {
|
||||
MMTIME mtime;
|
||||
mtime.wType = TIME_BYTES;
|
||||
|
@ -328,7 +329,6 @@ HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWO
|
|||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* PrimaryBuffer
|
||||
*/
|
||||
|
@ -340,8 +340,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
|
|||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
IDirectSoundImpl* dsound = This->dsound;
|
||||
HRESULT err = DS_OK;
|
||||
int i;
|
||||
DWORD nSamplesPerSec;
|
||||
int i, alloc_size, cp_size;
|
||||
DWORD nSamplesPerSec;
|
||||
TRACE("(%p,%p)\n",This,wfex);
|
||||
|
||||
if (This->dsound->priolevel == DSSCL_NORMAL) {
|
||||
|
@ -360,24 +360,20 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
|
|||
wfex->nAvgBytesPerSec, wfex->nBlockAlign,
|
||||
wfex->wBitsPerSample, wfex->cbSize);
|
||||
|
||||
if ((wfex->wFormatTag != WAVE_FORMAT_PCM) ||
|
||||
(wfex->nChannels < 1) || (wfex->nChannels > 2) ||
|
||||
(wfex->nSamplesPerSec < 1) ||
|
||||
((wfex->wBitsPerSample != 8) && (wfex->wBitsPerSample != 16))) {
|
||||
WARN("invalid paramemer: unsupported format!\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* **** */
|
||||
RtlAcquireResourceExclusive(&(dsound->lock), TRUE);
|
||||
|
||||
nSamplesPerSec = dsound->wfx.nSamplesPerSec;
|
||||
dsound->wfx.nSamplesPerSec = wfex->nSamplesPerSec;
|
||||
dsound->wfx.nChannels = wfex->nChannels;
|
||||
dsound->wfx.wBitsPerSample = wfex->wBitsPerSample;
|
||||
dsound->wfx.nBlockAlign = dsound->wfx.wBitsPerSample / 8 * dsound->wfx.nChannels;
|
||||
dsound->wfx.nAvgBytesPerSec =
|
||||
dsound->wfx.nSamplesPerSec * dsound->wfx.nBlockAlign;
|
||||
if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
|
||||
alloc_size = sizeof(WAVEFORMATEX);
|
||||
cp_size = sizeof(PCMWAVEFORMAT);
|
||||
} else
|
||||
alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
|
||||
|
||||
dsound->pwfx = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dsound->pwfx,alloc_size);
|
||||
|
||||
nSamplesPerSec = dsound->pwfx->nSamplesPerSec;
|
||||
|
||||
memcpy(dsound->pwfx, wfex, cp_size);
|
||||
|
||||
if (dsound->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) {
|
||||
DWORD flags = CALLBACK_FUNCTION;
|
||||
|
@ -388,7 +384,7 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
|
|||
waveOutClose(dsound->hwo);
|
||||
dsound->hwo = 0;
|
||||
err = mmErr(waveOutOpen(&(dsound->hwo), dsound->drvdesc.dnDevNode,
|
||||
&(dsound->wfx), (DWORD)DSOUND_callback, (DWORD)dsound,
|
||||
dsound->pwfx, (DWORD)DSOUND_callback, (DWORD)dsound,
|
||||
flags));
|
||||
if (err == DS_OK) {
|
||||
err = DSOUND_PrimaryOpen(dsound);
|
||||
|
@ -403,11 +399,11 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
|
|||
return err;
|
||||
}
|
||||
} else if (dsound->hwbuf) {
|
||||
err = IDsDriverBuffer_SetFormat(dsound->hwbuf, &(dsound->wfx));
|
||||
err = IDsDriverBuffer_SetFormat(dsound->hwbuf, dsound->pwfx);
|
||||
if (err == DSERR_BUFFERLOST) {
|
||||
/* Wine-only: the driver wants us to recreate the HW buffer */
|
||||
IDsDriverBuffer_Release(dsound->hwbuf);
|
||||
err = IDsDriver_CreateSoundBuffer(dsound->driver,&(dsound->wfx),
|
||||
err = IDsDriver_CreateSoundBuffer(dsound->driver,dsound->pwfx,
|
||||
DSBCAPS_PRIMARYBUFFER,0,
|
||||
&(dsound->buflen),&(dsound->buffer),
|
||||
(LPVOID)&(dsound->hwbuf));
|
||||
|
@ -427,7 +423,7 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
|
|||
}
|
||||
DSOUND_RecalcPrimary(dsound);
|
||||
|
||||
if (nSamplesPerSec != dsound->wfx.nSamplesPerSec) {
|
||||
if (nSamplesPerSec != dsound->pwfx->nSamplesPerSec) {
|
||||
IDirectSoundBufferImpl** dsb = dsound->buffers;
|
||||
for (i = 0; i < dsound->nrofbuffers; i++, dsb++) {
|
||||
/* **** */
|
||||
|
@ -656,27 +652,38 @@ static HRESULT WINAPI PrimaryBufferImpl_GetStatus(
|
|||
|
||||
|
||||
static HRESULT WINAPI PrimaryBufferImpl_GetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
|
||||
) {
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX lpwf,
|
||||
DWORD wfsize,
|
||||
LPDWORD wfwritten)
|
||||
{
|
||||
DWORD size;
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
|
||||
|
||||
if (wfsize>sizeof(This->dsound->wfx))
|
||||
wfsize = sizeof(This->dsound->wfx);
|
||||
if (lpwf) { /* NULL is valid */
|
||||
memcpy(lpwf,&(This->dsound->wfx),wfsize);
|
||||
if (wfwritten)
|
||||
*wfwritten = wfsize;
|
||||
} else {
|
||||
if (wfwritten)
|
||||
*wfwritten = sizeof(This->dsound->wfx);
|
||||
else {
|
||||
WARN("invalid parameter: wfwritten == NULL\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
size = sizeof(WAVEFORMATEX) + This->dsound->pwfx->cbSize;
|
||||
|
||||
return DS_OK;
|
||||
if (lpwf) { /* NULL is valid */
|
||||
if (wfsize >= size) {
|
||||
memcpy(lpwf,This->dsound->pwfx,size);
|
||||
if (wfwritten)
|
||||
*wfwritten = size;
|
||||
} else {
|
||||
WARN("invalid parameter: wfsize to small\n");
|
||||
if (wfwritten)
|
||||
*wfwritten = 0;
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
} else {
|
||||
if (wfwritten)
|
||||
*wfwritten = sizeof(WAVEFORMATEX) + This->dsound->pwfx->cbSize;
|
||||
else {
|
||||
WARN("invalid parameter: wfwritten == NULL\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PrimaryBufferImpl_Lock(
|
||||
|
@ -891,7 +898,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(
|
|||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
|
||||
*freq = This->dsound->wfx.nSamplesPerSec;
|
||||
*freq = This->dsound->pwfx->nSamplesPerSec;
|
||||
TRACE("-> %ld\n", *freq);
|
||||
|
||||
return DS_OK;
|
||||
|
@ -993,7 +1000,7 @@ static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(
|
|||
|
||||
*ppobj = NULL; /* assume failure */
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
|
||||
IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This);
|
||||
*ppobj = This;
|
||||
|
@ -1084,7 +1091,7 @@ HRESULT WINAPI PrimaryBufferImpl_Create(
|
|||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
dsb = (PrimaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
|
||||
dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
|
||||
|
||||
if (dsb == NULL) {
|
||||
WARN("out of memory\n");
|
||||
|
@ -1101,9 +1108,9 @@ HRESULT WINAPI PrimaryBufferImpl_Create(
|
|||
TRACE("Created primary buffer at %p\n", dsb);
|
||||
TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
|
||||
"bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
|
||||
ds->wfx.wFormatTag, ds->wfx.nChannels, ds->wfx.nSamplesPerSec,
|
||||
ds->wfx.nAvgBytesPerSec, ds->wfx.nBlockAlign,
|
||||
ds->wfx.wBitsPerSample, ds->wfx.cbSize);
|
||||
ds->pwfx->wFormatTag, ds->pwfx->nChannels, ds->pwfx->nSamplesPerSec,
|
||||
ds->pwfx->nAvgBytesPerSec, ds->pwfx->nBlockAlign,
|
||||
ds->pwfx->wBitsPerSample, ds->pwfx->cbSize);
|
||||
|
||||
*pdsb = dsb;
|
||||
return S_OK;
|
||||
|
|
|
@ -208,7 +208,7 @@ HRESULT WINAPI IKsBufferPropertySetImpl_Create(
|
|||
IKsBufferPropertySetImpl *iks;
|
||||
TRACE("(%p,%p)\n",dsb,piks);
|
||||
|
||||
iks = (IKsBufferPropertySetImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
|
||||
iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
|
||||
iks->ref = 0;
|
||||
iks->dsb = dsb;
|
||||
dsb->iks = iks;
|
||||
|
@ -1140,7 +1140,7 @@ HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
|
|||
{
|
||||
IKsPrivatePropertySetImpl *iks;
|
||||
|
||||
iks = (IKsPrivatePropertySetImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
|
||||
iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
|
||||
iks->ref = 0;
|
||||
iks->lpVtbl = &ikspvt;
|
||||
|
||||
|
|
|
@ -733,7 +733,7 @@ HRESULT WINAPI IDirectSound3DBufferImpl_Create(
|
|||
IDirectSound3DBufferImpl *ds3db;
|
||||
TRACE("(%p,%p)\n",dsb,pds3db);
|
||||
|
||||
ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
|
||||
ds3db = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
|
||||
|
||||
if (ds3db == NULL) {
|
||||
WARN("out of memory\n");
|
||||
|
@ -1111,7 +1111,7 @@ HRESULT WINAPI IDirectSound3DListenerImpl_Create(
|
|||
IDirectSound3DListenerImpl *dsl;
|
||||
TRACE("(%p,%p)\n",This,pdsl);
|
||||
|
||||
dsl = (IDirectSound3DListenerImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsl));
|
||||
dsl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsl));
|
||||
|
||||
if (dsl == NULL) {
|
||||
WARN("out of memory\n");
|
||||
|
|
Loading…
Reference in New Issue