winealsa: Make SetFormat work better with new behavior of dsound.

This commit is contained in:
Maarten Lankhorst 2007-08-27 14:28:52 +02:00 committed by Alexandre Julliard
parent 7850caa714
commit cdc8d97181
1 changed files with 21 additions and 18 deletions

View File

@ -73,6 +73,7 @@ struct IDsDriverImpl
/* IDsDriverImpl fields */ /* IDsDriverImpl fields */
IDsDriverBufferImpl* primary; IDsDriverBufferImpl* primary;
UINT wDevID; UINT wDevID;
DWORD forceformat;
}; };
struct IDsDriverBufferImpl struct IDsDriverBufferImpl
@ -292,6 +293,9 @@ static HRESULT WINAPI IDsDriverBufferImpl_Lock(PIDSDRIVERBUFFER iface,
/* **** */ /* **** */
EnterCriticalSection(&This->pcm_crst); EnterCriticalSection(&This->pcm_crst);
if (dwFlags & DSBLOCK_ENTIREBUFFER)
dwWriteLen = This->mmap_buflen_bytes;
if (dwWriteLen > This->mmap_buflen_bytes || dwWritePosition >= This->mmap_buflen_bytes) if (dwWriteLen > This->mmap_buflen_bytes || dwWritePosition >= This->mmap_buflen_bytes)
{ {
/* **** */ /* **** */
@ -368,7 +372,7 @@ static HRESULT WINAPI IDsDriverBufferImpl_Unlock(PIDSDRIVERBUFFER iface,
return DS_OK; return DS_OK;
} }
static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL forced) static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx)
{ {
snd_pcm_t *pcm = NULL; snd_pcm_t *pcm = NULL;
snd_pcm_hw_params_t *hw_params = This->hw_params; snd_pcm_hw_params_t *hw_params = This->hw_params;
@ -387,11 +391,7 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
default: FIXME("Unsupported bpp: %d\n", pwfx->wBitsPerSample); return DSERR_GENERIC; default: FIXME("Unsupported bpp: %d\n", pwfx->wBitsPerSample); return DSERR_GENERIC;
} }
/* **** */
EnterCriticalSection(&This->pcm_crst);
err = snd_pcm_open(&pcm, WOutDev[This->drv->wDevID].pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); err = snd_pcm_open(&pcm, WOutDev[This->drv->wDevID].pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
if (err < 0) if (err < 0)
{ {
if (errno != EBUSY || !This->pcm) if (errno != EBUSY || !This->pcm)
@ -427,13 +427,18 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
* side effects, which may include: Less granular pointer, changing buffer sizes, etc * side effects, which may include: Less granular pointer, changing buffer sizes, etc
*/ */
#if SND_LIB_VERSION >= 0x010009 #if SND_LIB_VERSION >= 0x010009
snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0 && forced); snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
#endif #endif
err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, NULL); err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, NULL);
if (err < 0) { rate = pwfx->nSamplesPerSec; WARN("Could not set rate\n"); goto err; } if (err < 0) { rate = pwfx->nSamplesPerSec; WARN("Could not set rate\n"); goto err; }
if (!ALSA_NearMatch(rate, pwfx->nSamplesPerSec)) if (!ALSA_NearMatch(rate, pwfx->nSamplesPerSec) && (This->drv->forceformat++))
{
WARN("Could not set exact rate %d, instead %d, bombing out\n", pwfx->nSamplesPerSec, rate);
goto err;
}
else if (!ALSA_NearMatch(rate, pwfx->nSamplesPerSec))
{ {
WARN("Could not set sound rate to %d, but instead to %d\n", pwfx->nSamplesPerSec, rate); WARN("Could not set sound rate to %d, but instead to %d\n", pwfx->nSamplesPerSec, rate);
pwfx->nSamplesPerSec = rate; pwfx->nSamplesPerSec = rate;
@ -463,12 +468,8 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
snd_pcm_close(This->pcm); snd_pcm_close(This->pcm);
} }
This->pcm = pcm; This->pcm = pcm;
snd_pcm_prepare(This->pcm); snd_pcm_prepare(This->pcm);
DSDB_CreateMMAP(This); DSDB_CreateMMAP(This);
/* **** */
LeaveCriticalSection(&This->pcm_crst);
return S_OK; return S_OK;
err: err:
@ -483,8 +484,6 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
if (This->pcm) if (This->pcm)
snd_pcm_hw_params_current(This->pcm, This->hw_params); snd_pcm_hw_params_current(This->pcm, This->hw_params);
/* **** */
LeaveCriticalSection(&This->pcm_crst);
return DSERR_BADFORMAT; return DSERR_BADFORMAT;
} }
@ -495,11 +494,15 @@ static HRESULT WINAPI IDsDriverBufferImpl_SetFormat(PIDSDRIVERBUFFER iface, LPWA
TRACE("(%p, %p)\n", iface, pwfx); TRACE("(%p, %p)\n", iface, pwfx);
hr = SetFormat(This, pwfx, TRUE); /* **** */
EnterCriticalSection(&This->pcm_crst);
This->drv->forceformat = FALSE;
hr = SetFormat(This, pwfx);
/* **** */
LeaveCriticalSection(&This->pcm_crst);
if (hr == S_OK) if (hr == DS_OK)
/* Buffer size / Location changed, so tell dsound to recreate */ return S_FALSE;
return DSERR_BUFFERLOST;
return hr; return hr;
} }
@ -778,7 +781,7 @@ static HRESULT WINAPI IDsDriverImpl_CreateSoundBuffer(PIDSDRIVER iface,
(*ippdsdb)->pcm_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_DSOUTPUT.pcm_crst"); (*ippdsdb)->pcm_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_DSOUTPUT.pcm_crst");
/* SetFormat has to re-initialize pcm here anyway */ /* SetFormat has to re-initialize pcm here anyway */
err = SetFormat(*ippdsdb, pwfx, FALSE); err = SetFormat(*ippdsdb, pwfx);
if (FAILED(err)) if (FAILED(err))
{ {
WARN("Error occurred: %08x\n", err); WARN("Error occurred: %08x\n", err);