Index: pulseaudio.c
===================================================================
--- pulseaudio.c	(revision 26783)
+++ pulseaudio.c	(working copy)
@@ -69,6 +69,7 @@
     const uint8_t  *pu8PeekBuf;
     size_t         cbPeekBuf;
     size_t         offPeekBuf;
+    pa_operation   *pDrainOperation;
 } PulseVoice;
 
 /* The desired buffer length in milliseconds. Will be the target total stream
@@ -233,6 +234,8 @@
         LogRel(("Pulse: Requested record buffer attributes: maxlength=%d fragsize=%d\n",
                 pBufAttr->maxlength, pBufAttr->fragsize));
 
+        flags |= PA_STREAM_START_CORKED;
+
         if (pa_stream_connect_record(pStream, /*dev=*/NULL, pBufAttr, flags) < 0)
         {
             LogRel(("Pulse: Cannot connect record stream: %s\n",
@@ -310,6 +313,8 @@
     audsettings_t obt_as;
     int cbBuf;
 
+    pPulse->pDrainOperation     = NULL;
+
     pPulse->SampleSpec.format   = aud_to_pulsefmt (as->fmt);
     pPulse->SampleSpec.rate     = as->freq;
     pPulse->SampleSpec.channels = as->nchannels;
@@ -439,6 +444,18 @@
     return audio_pcm_sw_write (sw, buf, len);
 }
 
+static int pulse_wait_for_operation (pa_operation *op)
+{
+    if (op)
+    {
+        while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
+            pa_threaded_mainloop_wait(g_pMainLoop);
+        pa_operation_unref(op);
+    }
+
+    return 1;
+}
+
 static void stream_success_callback(pa_stream *pStream, int success, void *userdata)
 {
     PulseVoice *pPulse = (PulseVoice *) userdata;
@@ -455,16 +472,25 @@
     pa_threaded_mainloop_signal(g_pMainLoop, 0);
 }
 
-static int pulse_wait_for_operation (pa_operation *op)
+static void stream_drain_callback(pa_stream *pStream, int success, void *userdata)
 {
-    if (op)
+PulseVoice *pPulse = (PulseVoice *) userdata;
+    pPulse->fOpSuccess = success;
+    if (!success)
     {
-        while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
-            pa_threaded_mainloop_wait(g_pMainLoop);
-        pa_operation_unref(op);
+        if (pPulse->cErrors < MAX_LOG_REL_ERRORS)
+        {
+            int rc = pa_context_errno(g_pContext);
+            pPulse->cErrors++;
+            LogRel(("Pulse: Failed stream operation: %s\n", pa_strerror(rc)));
+        }
     }
-
-    return 1;
+    else
+    {
+        pa_operation_unref(pa_stream_cork(pStream, 1, stream_success_callback, userdata));
+    }
+    pa_operation_unref(pPulse->pDrainOperation);
+    pPulse->pDrainOperation = NULL;
 }
 
 static int pulse_ctl_out (HWVoiceOut *hw, int cmd, ...)
@@ -476,24 +502,30 @@
         case VOICE_ENABLE:
             /* Start audio output. */
             pa_threaded_mainloop_lock(g_pMainLoop);
-            pulse_wait_for_operation(pa_stream_cork(pPulse->pStream, 0,
-                                                    stream_success_callback, pPulse));
+            if (pPulse->pDrainOperation &&
+                pa_operation_get_state(pPulse->pDrainOperation) != PA_OPERATION_DONE)
+            {
+                pa_operation_cancel(pPulse->pDrainOperation);
+                pa_operation_unref(pPulse->pDrainOperation);
+                pPulse->pDrainOperation = NULL;
+            } else {
+                pulse_wait_for_operation(pa_stream_cork(pPulse->pStream, 0,
+                                                        stream_success_callback, pPulse));
+            }
             pa_threaded_mainloop_unlock(g_pMainLoop);
             break;
 
         case VOICE_DISABLE:
-            /* Pause audio output. Note that we must return immediately from here
-             * so waiting until the buffers are flushed (trigger+drain) is not an
-             * option! It could be sufficient to cork the audio stream (we are
-             * called if the Pause bit of the AC97 x_CR register is set) but ALSA
-             * uses snd_pcm_drop() dropping all pending frames so we do the same
-             * here. */
+            /* Stop audio output. */
             pa_threaded_mainloop_lock(g_pMainLoop);
-            pulse_wait_for_operation(pa_stream_flush(pPulse->pStream,
-                                                     stream_success_callback, pPulse));
-            pulse_wait_for_operation(pa_stream_cork(pPulse->pStream, 1,
-                                                    stream_success_callback, pPulse));
-            pa_threaded_mainloop_unlock(g_pMainLoop);
+            if (!pPulse->pDrainOperation)
+            {
+                pulse_wait_for_operation(pa_stream_trigger(pPulse->pStream,
+                                                           stream_success_callback, pPulse));
+                pPulse->pDrainOperation = pa_stream_drain(pPulse->pStream,
+                                                          stream_drain_callback, pPulse);
+                pa_threaded_mainloop_unlock(g_pMainLoop);
+            }
             break;
 
         default:
Index: pulse_stubs.c
===================================================================
--- pulse_stubs.c	(revision 26783)
+++ pulse_stubs.c	(working copy)
@@ -182,6 +182,9 @@
 PROXY_STUB     (pa_operation_get_state, pa_operation_state_t,
                 (pa_operation *o),
                 (o))
+PROXY_STUB_VOID(pa_operation_cancel,
+                (pa_operation *o),
+                (o))
 PROXY_STUB     (pa_strerror, const char*,
                 (int error),
                 (error))
@@ -240,6 +243,7 @@
     ELEMENT(pa_channel_map_init_auto),
     ELEMENT(pa_operation_unref),
     ELEMENT(pa_operation_get_state),
+    ELEMENT(pa_operation_cancel),
     ELEMENT(pa_strerror),
     ELEMENT(pa_stream_readable_size)
 };
