From 866358211d8398823e72528daaa810eef49be8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 30 Jul 2009 09:44:26 +0200 Subject: [PATCH] alsa: add host suspend/resume support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both input and output streams may be in SND_PCM_STATE_SUSPENDED after the host is suspended and resumed, meaning "Hardware is suspended". snd_pcm_readi() and snd_pcm_writei() will return -ESTRPIPE if called while the stream is in this state. Call snd_pcm_resume() to enable audio output and capture after host resume. Signed-off-by: Bjørn Mork Signed-off-by: malc --- audio/alsaaudio.c | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index d0b7cd0bd3..5a49eb55ac 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -503,6 +503,16 @@ static int alsa_recover (snd_pcm_t *handle) return 0; } +static int alsa_resume (snd_pcm_t *handle) +{ + int err = snd_pcm_resume (handle); + if (err < 0) { + alsa_logerr (err, "Failed to resume handle %p\n", handle); + return -1; + } + return 0; +} + static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) { snd_pcm_sframes_t avail; @@ -580,6 +590,19 @@ static int alsa_run_out (HWVoiceOut *hw) } continue; + case -ESTRPIPE: + /* stream is suspended and waiting for an + application recovery */ + if (alsa_resume (alsa->handle)) { + alsa_logerr (written, "Failed to write %d frames\n", + len); + goto exit; + } + if (conf.verbose) { + dolog ("Resuming suspended output stream\n"); + } + continue; + case -EAGAIN: goto exit; @@ -779,8 +802,30 @@ static int alsa_run_in (HWVoiceIn *hw) return 0; } - if (!avail && (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) { - avail = hw->samples; + if (!avail) { + snd_pcm_state_t state; + + state = snd_pcm_state (alsa->handle); + switch (state) { + case SND_PCM_STATE_PREPARED: + avail = hw->samples; + break; + case SND_PCM_STATE_SUSPENDED: + /* stream is suspended and waiting for an application recovery */ + if (alsa_resume (alsa->handle)) { + dolog ("Failed to resume suspended input stream\n"); + return 0; + } + if (conf.verbose) { + dolog ("Resuming suspended input stream\n"); + } + break; + default: + if (conf.verbose) { + dolog ("No frames available and ALSA state is %d\n", state); + } + return 0; + } } decr = audio_MIN (dead, avail);