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 | 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); | ... | ... |