Commit 866358211d8398823e72528daaa810eef49be8c5
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,6 +503,16 @@ static int alsa_recover (snd_pcm_t *handle) | ||
503 | return 0; | 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 | static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) | 516 | static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) |
507 | { | 517 | { |
508 | snd_pcm_sframes_t avail; | 518 | snd_pcm_sframes_t avail; |
@@ -580,6 +590,19 @@ static int alsa_run_out (HWVoiceOut *hw) | @@ -580,6 +590,19 @@ static int alsa_run_out (HWVoiceOut *hw) | ||
580 | } | 590 | } |
581 | continue; | 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 | case -EAGAIN: | 606 | case -EAGAIN: |
584 | goto exit; | 607 | goto exit; |
585 | 608 | ||
@@ -779,8 +802,30 @@ static int alsa_run_in (HWVoiceIn *hw) | @@ -779,8 +802,30 @@ static int alsa_run_in (HWVoiceIn *hw) | ||
779 | return 0; | 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 | decr = audio_MIN (dead, avail); | 831 | decr = audio_MIN (dead, avail); |