Commit 866358211d8398823e72528daaa810eef49be8c5

Authored by Bjørn Mork
Committed by malc
1 parent 4c955388

alsa: add host suspend/resume support

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 <bjorn@mork.no>
Signed-off-by: malc <av1474@comtv.ru>
Showing 1 changed file with 47 additions and 2 deletions
audio/alsaaudio.c
... ... @@ -503,6 +503,16 @@ static int alsa_recover (snd_pcm_t *handle)
503 503 return 0;
504 504 }
505 505  
  506 +static int alsa_resume (snd_pcm_t *handle)
  507 +{
  508 + int err = snd_pcm_resume (handle);
  509 + if (err < 0) {
  510 + alsa_logerr (err, "Failed to resume handle %p\n", handle);
  511 + return -1;
  512 + }
  513 + return 0;
  514 +}
  515 +
506 516 static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
507 517 {
508 518 snd_pcm_sframes_t avail;
... ... @@ -580,6 +590,19 @@ static int alsa_run_out (HWVoiceOut *hw)
580 590 }
581 591 continue;
582 592  
  593 + case -ESTRPIPE:
  594 + /* stream is suspended and waiting for an
  595 + application recovery */
  596 + if (alsa_resume (alsa->handle)) {
  597 + alsa_logerr (written, "Failed to write %d frames\n",
  598 + len);
  599 + goto exit;
  600 + }
  601 + if (conf.verbose) {
  602 + dolog ("Resuming suspended output stream\n");
  603 + }
  604 + continue;
  605 +
583 606 case -EAGAIN:
584 607 goto exit;
585 608  
... ... @@ -779,8 +802,30 @@ static int alsa_run_in (HWVoiceIn *hw)
779 802 return 0;
780 803 }
781 804  
782   - if (!avail && (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) {
783   - avail = hw->samples;
  805 + if (!avail) {
  806 + snd_pcm_state_t state;
  807 +
  808 + state = snd_pcm_state (alsa->handle);
  809 + switch (state) {
  810 + case SND_PCM_STATE_PREPARED:
  811 + avail = hw->samples;
  812 + break;
  813 + case SND_PCM_STATE_SUSPENDED:
  814 + /* stream is suspended and waiting for an application recovery */
  815 + if (alsa_resume (alsa->handle)) {
  816 + dolog ("Failed to resume suspended input stream\n");
  817 + return 0;
  818 + }
  819 + if (conf.verbose) {
  820 + dolog ("Resuming suspended input stream\n");
  821 + }
  822 + break;
  823 + default:
  824 + if (conf.verbose) {
  825 + dolog ("No frames available and ALSA state is %d\n", state);
  826 + }
  827 + return 0;
  828 + }
784 829 }
785 830  
786 831 decr = audio_MIN (dead, avail);
... ...