Andrew Nguyen : winealsa.drv: Replicate the snd_pcm_recover alsa-lib implementation to cope with older alsa-lib versions .
Alexandre Julliard
julliard at winehq.org
Fri Jun 11 09:58:33 CDT 2010
Module: wine
Branch: master
Commit: 13a7708abb481f2903db6b62efcf53a0a7f7b79e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=13a7708abb481f2903db6b62efcf53a0a7f7b79e
Author: Andrew Nguyen <anguyen at codeweavers.com>
Date: Fri Jun 11 03:54:24 2010 -0500
winealsa.drv: Replicate the snd_pcm_recover alsa-lib implementation to cope with older alsa-lib versions.
---
dlls/winealsa.drv/alsa.c | 45 +++++++++++++++++++++++++++++------------
dlls/winealsa.drv/alsa.h | 2 +-
dlls/winealsa.drv/dsoutput.c | 2 +-
dlls/winealsa.drv/waveout.c | 4 +-
4 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
index 9eb50cd..4f0f1ce 100644
--- a/dlls/winealsa.drv/alsa.c
+++ b/dlls/winealsa.drv/alsa.c
@@ -2,6 +2,7 @@
* Wine Driver for ALSA
*
* Copyright 2002 Eric Pouech
+ * Copyright 2006 Jaroslav Kysela
* Copyright 2007 Maarten Lankhorst
*
* 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 */
- err = snd_pcm_prepare(wwo->pcm);
- if (err < 0)
- ERR( "underrun recovery failed. prepare failed: %s\n", snd_strerror(err));
+ if (err > 0)
+ err = -err;
+ if (err == -EINTR) /* nothing to do, continue */
return 0;
- } else if (err == -ESTRPIPE) {
- while ((err = snd_pcm_resume(wwo->pcm)) == -EAGAIN)
- sleep(1); /* wait until the suspend flag is released */
+ if (err == -EPIPE) {
+ const char *s;
+ 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) {
+ ERR("cannot recover from %s, prepare failed: %s", s, snd_strerror(err));
+ return 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(wwo->pcm);
- if (err < 0)
- ERR("recovery from suspend failed, prepare failed: %s\n", snd_strerror(err));
+ err = snd_pcm_prepare(pcm);
+ if (err < 0) {
+ ERR("cannot recover from suspend, prepare failed: %s", snd_strerror(err));
+ return err;
+ }
}
return 0;
}
diff --git a/dlls/winealsa.drv/alsa.h b/dlls/winealsa.drv/alsa.h
index 7c2f0f4..d961dce 100644
--- a/dlls/winealsa.drv/alsa.h
+++ b/dlls/winealsa.drv/alsa.h
@@ -187,7 +187,7 @@ const char * ALSA_getFormat(WORD wFormatTag);
BOOL ALSA_NearMatch(int rate1, int rate2);
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);
-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);
BOOL ALSA_supportedFormat(LPWAVEFORMATEX wf);
diff --git a/dlls/winealsa.drv/dsoutput.c b/dlls/winealsa.drv/dsoutput.c
index bb81621..8a277de 100644
--- a/dlls/winealsa.drv/dsoutput.c
+++ b/dlls/winealsa.drv/dsoutput.c
@@ -406,7 +406,7 @@ static HRESULT WINAPI IDsDriverBufferImpl_Unlock(PIDSDRIVERBUFFER iface,
if (ret == -EPIPE)
{
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);
/* Advance mmap pointer a little to make dsound notice the underrun and respond to it */
diff --git a/dlls/winealsa.drv/waveout.c b/dlls/winealsa.drv/waveout.c
index 4001f26..18693c1 100644
--- a/dlls/winealsa.drv/waveout.c
+++ b/dlls/winealsa.drv/waveout.c
@@ -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)
{
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;
}
@@ -244,7 +244,7 @@ static int wodPlayer_WriteMaxFrags(WINE_WAVEDEV* wwo, DWORD* frames)
written = (wwo->write)(wwo->pcm, lpWaveHdr->lpData + wwo->dwPartialOffset, toWrite);
if ( written < 0) {
/* 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);
}
if (written <= 0) {
More information about the wine-cvs
mailing list