Blob Blame History Raw
Index: src/modules/module-alsa-sink.c
===================================================================
--- src/modules/module-alsa-sink.c	(revision 1431)
+++ src/modules/module-alsa-sink.c	(working copy)
@@ -141,6 +141,33 @@
     return ret;
 }
 
+static int suspend_recovery(struct userdata *u) {
+    int ret;
+    assert(u);
+
+    pa_log_info("*** ALSA-SUSPEND (playback) ***");
+
+    if ((ret = snd_pcm_resume(u->pcm_handle)) < 0) {
+        if (ret == -EAGAIN)
+            return -1;
+
+        if (ret != -ENOSYS)
+            pa_log("snd_pcm_resume() failed: %s", snd_strerror(-ret));
+        else {
+            if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0)
+                pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret));
+        }
+
+        if (ret < 0) {
+            clear_up(u);
+            pa_module_unload_request(u->module);
+            return -1;
+        }
+    }
+
+    return ret;
+}
+
 static void do_write(struct userdata *u) {
     assert(u);
 
@@ -176,6 +203,13 @@
                 continue;
             }
 
+            if (frames == -ESTRPIPE) {
+                if (suspend_recovery(u) < 0)
+                    return;
+
+                continue;
+            }
+
             pa_log("snd_pcm_writei() failed: %s", snd_strerror(-frames));
 
             clear_up(u);
@@ -207,6 +241,10 @@
         if (xrun_recovery(u) < 0)
             return;
 
+    if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_SUSPENDED)
+        if (suspend_recovery(u) < 0)
+            return;
+
     do_write(u);
 }
 
Index: src/modules/module-alsa-source.c
===================================================================
--- src/modules/module-alsa-source.c	(revision 1429)
+++ src/modules/module-alsa-source.c	(working copy)
@@ -143,6 +143,34 @@
     return 0;
 }
 
+
+static int suspend_recovery(struct userdata *u) {
+    int ret;
+    assert(u);
+
+    pa_log_info("*** ALSA-SUSPEND (capture) ***");
+
+    if ((ret = snd_pcm_resume(u->pcm_handle)) < 0) {
+        if (ret == -EAGAIN)
+            return -1;
+
+        if (ret != -ENOSYS)
+            pa_log("snd_pcm_resume() failed: %s", snd_strerror(-ret));
+        else {
+            if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0)
+                pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret));
+        }
+
+        if (ret < 0) {
+            clear_up(u);
+            pa_module_unload_request(u->module);
+            return -1;
+        }
+    }
+
+    return ret;
+}
+
 static void do_read(struct userdata *u) {
     assert(u);
 
@@ -175,6 +203,13 @@
                 continue;
             }
 
+            if (frames == -ESTRPIPE) {
+                if (suspend_recovery(u) < 0)
+                    return;
+
+                continue;
+            }
+
             pa_log("snd_pcm_readi() failed: %s", snd_strerror(-frames));
 
             clear_up(u);
@@ -210,6 +245,10 @@
         if (xrun_recovery(u) < 0)
             return;
 
+    if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_SUSPENDED)
+        if (suspend_recovery(u) < 0)
+            return;
+
     do_read(u);
 }