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:
Robert Reif 2004-08-18 00:30:37 +00:00 committed by Alexandre Julliard
parent cae33167d2
commit dfe3c1c579
8 changed files with 272 additions and 206 deletions

View File

@ -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");

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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");