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