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 */
IDsDriverBufferImpl* primary;
UINT wDevID;
DWORD forceformat;
};
struct IDsDriverBufferImpl
@ -292,6 +293,9 @@ static HRESULT WINAPI IDsDriverBufferImpl_Lock(PIDSDRIVERBUFFER iface,
/* **** */
EnterCriticalSection(&This->pcm_crst);
if (dwFlags & DSBLOCK_ENTIREBUFFER)
dwWriteLen = 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;
}
static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL forced)
static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx)
{
snd_pcm_t *pcm = NULL;
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;
}
/* **** */
EnterCriticalSection(&This->pcm_crst);
err = snd_pcm_open(&pcm, WOutDev[This->drv->wDevID].pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
if (err < 0)
{
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
*/
#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
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 (!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);
pwfx->nSamplesPerSec = rate;
@ -463,12 +468,8 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
snd_pcm_close(This->pcm);
}
This->pcm = pcm;
snd_pcm_prepare(This->pcm);
DSDB_CreateMMAP(This);
/* **** */
LeaveCriticalSection(&This->pcm_crst);
return S_OK;
err:
@ -483,8 +484,6 @@ static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx, BOOL fo
if (This->pcm)
snd_pcm_hw_params_current(This->pcm, This->hw_params);
/* **** */
LeaveCriticalSection(&This->pcm_crst);
return DSERR_BADFORMAT;
}
@ -495,11 +494,15 @@ static HRESULT WINAPI IDsDriverBufferImpl_SetFormat(PIDSDRIVERBUFFER iface, LPWA
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)
/* Buffer size / Location changed, so tell dsound to recreate */
return DSERR_BUFFERLOST;
if (hr == DS_OK)
return S_FALSE;
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");
/* SetFormat has to re-initialize pcm here anyway */
err = SetFormat(*ippdsdb, pwfx, FALSE);
err = SetFormat(*ippdsdb, pwfx);
if (FAILED(err))
{
WARN("Error occurred: %08x\n", err);