Commit cdc8d971 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

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

parent 7850caa7
...@@ -73,6 +73,7 @@ struct IDsDriverImpl ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment