winealsa.drv: Replicate the snd_pcm_recover alsa-lib implementation to cope with older alsa-lib versions.
This commit is contained in:
parent
dd12cf7110
commit
13a7708abb
@ -2,6 +2,7 @@
|
|||||||
* Wine Driver for ALSA
|
* Wine Driver for ALSA
|
||||||
*
|
*
|
||||||
* Copyright 2002 Eric Pouech
|
* Copyright 2002 Eric Pouech
|
||||||
|
* Copyright 2006 Jaroslav Kysela
|
||||||
* Copyright 2007 Maarten Lankhorst
|
* Copyright 2007 Maarten Lankhorst
|
||||||
*
|
*
|
||||||
* This file has a few shared generic subroutines shared among the alsa
|
* This file has a few shared generic subroutines shared among the alsa
|
||||||
@ -556,24 +557,42 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* ALSA_XRUNRecovery [internal]
|
* wine_snd_pcm_recover [internal]
|
||||||
*
|
*
|
||||||
* used to recovery from XRUN errors (buffer underflow/overflow)
|
* Code slightly modified from alsa-lib v1.0.23 snd_pcm_recover implementation.
|
||||||
|
* used to recover from XRUN errors (buffer underflow/overflow)
|
||||||
*/
|
*/
|
||||||
int ALSA_XRUNRecovery(WINE_WAVEDEV * wwo, int err)
|
int wine_snd_pcm_recover(snd_pcm_t *pcm, int err, int silent)
|
||||||
{
|
{
|
||||||
if (err == -EPIPE) { /* under-run */
|
if (err > 0)
|
||||||
err = snd_pcm_prepare(wwo->pcm);
|
err = -err;
|
||||||
if (err < 0)
|
if (err == -EINTR) /* nothing to do, continue */
|
||||||
ERR( "underrun recovery failed. prepare failed: %s\n", snd_strerror(err));
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (err == -ESTRPIPE) {
|
if (err == -EPIPE) {
|
||||||
while ((err = snd_pcm_resume(wwo->pcm)) == -EAGAIN)
|
const char *s;
|
||||||
sleep(1); /* wait until the suspend flag is released */
|
if (snd_pcm_stream(pcm) == SND_PCM_STREAM_PLAYBACK)
|
||||||
|
s = "underrun";
|
||||||
|
else
|
||||||
|
s = "overrun";
|
||||||
|
if (!silent)
|
||||||
|
ERR("%s occurred", s);
|
||||||
|
err = snd_pcm_prepare(pcm);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err = snd_pcm_prepare(wwo->pcm);
|
ERR("cannot recover from %s, prepare failed: %s", s, snd_strerror(err));
|
||||||
if (err < 0)
|
return err;
|
||||||
ERR("recovery from suspend failed, prepare failed: %s\n", snd_strerror(err));
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (err == -ESTRPIPE) {
|
||||||
|
while ((err = snd_pcm_resume(pcm)) == -EAGAIN)
|
||||||
|
/* wait until suspend flag is released */
|
||||||
|
poll(NULL, 0, 1000);
|
||||||
|
if (err < 0) {
|
||||||
|
err = snd_pcm_prepare(pcm);
|
||||||
|
if (err < 0) {
|
||||||
|
ERR("cannot recover from suspend, prepare failed: %s", snd_strerror(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ const char * ALSA_getFormat(WORD wFormatTag);
|
|||||||
BOOL ALSA_NearMatch(int rate1, int rate2);
|
BOOL ALSA_NearMatch(int rate1, int rate2);
|
||||||
DWORD ALSA_bytes_to_mmtime(LPMMTIME lpTime, DWORD position, WAVEFORMATPCMEX* format);
|
DWORD ALSA_bytes_to_mmtime(LPMMTIME lpTime, DWORD position, WAVEFORMATPCMEX* format);
|
||||||
void ALSA_TraceParameters(snd_pcm_hw_params_t * hw_params, snd_pcm_sw_params_t * sw, int full);
|
void ALSA_TraceParameters(snd_pcm_hw_params_t * hw_params, snd_pcm_sw_params_t * sw, int full);
|
||||||
int ALSA_XRUNRecovery(WINE_WAVEDEV * wwo, int err);
|
int wine_snd_pcm_recover(snd_pcm_t *pcm, int err, int silent);
|
||||||
void ALSA_copyFormat(LPWAVEFORMATEX wf1, LPWAVEFORMATPCMEX wf2);
|
void ALSA_copyFormat(LPWAVEFORMATEX wf1, LPWAVEFORMATPCMEX wf2);
|
||||||
BOOL ALSA_supportedFormat(LPWAVEFORMATEX wf);
|
BOOL ALSA_supportedFormat(LPWAVEFORMATEX wf);
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ static HRESULT WINAPI IDsDriverBufferImpl_Unlock(PIDSDRIVERBUFFER iface,
|
|||||||
if (ret == -EPIPE)
|
if (ret == -EPIPE)
|
||||||
{
|
{
|
||||||
WARN("Underrun occurred\n");
|
WARN("Underrun occurred\n");
|
||||||
snd_pcm_recover(This->pcm, -EPIPE, 1);
|
wine_snd_pcm_recover(This->pcm, -EPIPE, 1);
|
||||||
ret = snd_pcm_writei(This->pcm, pvAudio1, writelen);
|
ret = snd_pcm_writei(This->pcm, pvAudio1, writelen);
|
||||||
|
|
||||||
/* Advance mmap pointer a little to make dsound notice the underrun and respond to it */
|
/* Advance mmap pointer a little to make dsound notice the underrun and respond to it */
|
||||||
|
@ -110,7 +110,7 @@ static BOOL wodUpdatePlayedTotal(WINE_WAVEDEV* wwo, snd_pcm_status_t* ps)
|
|||||||
if (state != SND_PCM_STATE_RUNNING && state != SND_PCM_STATE_PREPARED)
|
if (state != SND_PCM_STATE_RUNNING && state != SND_PCM_STATE_PREPARED)
|
||||||
{
|
{
|
||||||
WARN("Unexpected state (%d) while updating Total Played, resetting\n", state);
|
WARN("Unexpected state (%d) while updating Total Played, resetting\n", state);
|
||||||
snd_pcm_recover(wwo->pcm, -EPIPE, 0);
|
wine_snd_pcm_recover(wwo->pcm, -EPIPE, 0);
|
||||||
delay=0;
|
delay=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ static int wodPlayer_WriteMaxFrags(WINE_WAVEDEV* wwo, DWORD* frames)
|
|||||||
written = (wwo->write)(wwo->pcm, lpWaveHdr->lpData + wwo->dwPartialOffset, toWrite);
|
written = (wwo->write)(wwo->pcm, lpWaveHdr->lpData + wwo->dwPartialOffset, toWrite);
|
||||||
if ( written < 0) {
|
if ( written < 0) {
|
||||||
/* XRUN occurred. let's try to recover */
|
/* XRUN occurred. let's try to recover */
|
||||||
ALSA_XRUNRecovery(wwo, written);
|
wine_snd_pcm_recover(wwo->pcm, written, 0);
|
||||||
written = (wwo->write)(wwo->pcm, lpWaveHdr->lpData + wwo->dwPartialOffset, toWrite);
|
written = (wwo->write)(wwo->pcm, lpWaveHdr->lpData + wwo->dwPartialOffset, toWrite);
|
||||||
}
|
}
|
||||||
if (written <= 0) {
|
if (written <= 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user