diff options
Diffstat (limited to 'audio/alsaaudio.c')
-rw-r--r-- | audio/alsaaudio.c | 49 |
1 files 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); |