diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index f37ce1ce85..4ef26818be 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -906,6 +906,7 @@ static struct audio_pcm_ops alsa_pcm_ops = {
     .init_out = alsa_init_out,
     .fini_out = alsa_fini_out,
     .write    = alsa_write,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = alsa_enable_out,
 
     .init_in  = alsa_init_in,
diff --git a/audio/audio.c b/audio/audio.c
index 922e95011c..81822bfec9 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1096,6 +1096,10 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
         }
     }
 
+    if (hw->pcm_ops->run_buffer_out) {
+        hw->pcm_ops->run_buffer_out(hw);
+    }
+
     return clipped;
 }
 
@@ -1412,6 +1416,28 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
     hw->pending_emul -= size;
 }
 
+void audio_generic_run_buffer_out(HWVoiceOut *hw)
+{
+    while (hw->pending_emul) {
+        size_t write_len, written;
+        ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
+
+        if (start < 0) {
+            start += hw->size_emul;
+        }
+        assert(start >= 0 && start < hw->size_emul);
+
+        write_len = MIN(hw->pending_emul, hw->size_emul - start);
+
+        written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len);
+        hw->pending_emul -= written;
+
+        if (written < write_len) {
+            break;
+        }
+    }
+}
+
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
 {
     if (unlikely(!hw->buf_emul)) {
@@ -1427,8 +1453,7 @@ void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
     return hw->buf_emul + hw->pos_emul;
 }
 
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
-                                            size_t size)
+size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
 {
     assert(buf == hw->buf_emul + hw->pos_emul &&
            size + hw->pending_emul <= hw->size_emul);
@@ -1439,35 +1464,6 @@ size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
     return size;
 }
 
-size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
-{
-    audio_generic_put_buffer_out_nowrite(hw, buf, size);
-
-    while (hw->pending_emul) {
-        size_t write_len, written;
-        ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
-        if (start < 0) {
-            start += hw->size_emul;
-        }
-        assert(start >= 0 && start < hw->size_emul);
-
-        write_len = MIN(hw->pending_emul, hw->size_emul - start);
-
-        written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len);
-        hw->pending_emul -= written;
-
-        if (written < write_len) {
-            break;
-        }
-    }
-
-    /*
-     * fake we have written everything. non-written data remain in pending_emul,
-     * so we do not have to clip them multiple times
-     */
-    return size;
-}
-
 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
 {
     size_t dst_size, copy_size;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 5ba2078346..3c8e48b55b 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -152,6 +152,7 @@ struct audio_pcm_ops {
     int    (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque);
     void   (*fini_out)(HWVoiceOut *hw);
     size_t (*write)   (HWVoiceOut *hw, void *buf, size_t size);
+    void   (*run_buffer_out)(HWVoiceOut *hw);
     /*
      * get a buffer that after later can be passed to put_buffer_out; optional
      * returns the buffer, and writes it's size to size (in bytes)
@@ -178,10 +179,9 @@ struct audio_pcm_ops {
 
 void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
 void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
+void audio_generic_run_buffer_out(HWVoiceOut *hw);
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
 size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size);
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
-                                            size_t size);
 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size);
 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size);
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 66f0f459cf..c7a7196c2d 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -411,7 +411,7 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
     }
 COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
                        (hw, size))
-COREAUDIO_WRAPPER_FUNC(put_buffer_out_nowrite, size_t,
+COREAUDIO_WRAPPER_FUNC(put_buffer_out, size_t,
                        (HWVoiceOut *hw, void *buf, size_t size),
                        (hw, buf, size))
 COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size),
@@ -687,9 +687,12 @@ static void coreaudio_audio_fini (void *opaque)
 static struct audio_pcm_ops coreaudio_pcm_ops = {
     .init_out = coreaudio_init_out,
     .fini_out = coreaudio_fini_out,
+  /* wrapper for audio_generic_write */
     .write    = coreaudio_write,
+  /* wrapper for audio_generic_get_buffer_out */
     .get_buffer_out = coreaudio_get_buffer_out,
-    .put_buffer_out = coreaudio_put_buffer_out_nowrite,
+  /* wrapper for audio_generic_put_buffer_out */
+    .put_buffer_out = coreaudio_put_buffer_out,
     .enable_out = coreaudio_enable_out
 };
 
diff --git a/audio/noaudio.c b/audio/noaudio.c
index ff99b253ff..05798ea210 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -118,6 +118,7 @@ static struct audio_pcm_ops no_pcm_ops = {
     .init_out = no_init_out,
     .fini_out = no_fini_out,
     .write    = no_write,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = no_enable_out,
 
     .init_in  = no_init_in,
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index c43faeeea4..4965084a5a 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -382,6 +382,15 @@ static size_t oss_get_available_bytes(OSSVoiceOut *oss)
     return audio_ring_dist(cntinfo.ptr, oss->hw.pos_emul, oss->hw.size_emul);
 }
 
+static void oss_run_buffer_out(HWVoiceOut *hw)
+{
+    OSSVoiceOut *oss = (OSSVoiceOut *)hw;
+
+    if (!oss->mmapped) {
+        audio_generic_run_buffer_out(hw);
+    }
+}
+
 static void *oss_get_buffer_out(HWVoiceOut *hw, size_t *size)
 {
     OSSVoiceOut *oss = (OSSVoiceOut *) hw;
@@ -748,6 +757,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
     .init_out = oss_init_out,
     .fini_out = oss_fini_out,
     .write    = oss_write,
+    .run_buffer_out = oss_run_buffer_out,
     .get_buffer_out = oss_get_buffer_out,
     .put_buffer_out = oss_put_buffer_out,
     .enable_out = oss_enable_out,
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index 5c6bcfcb3e..c00e7d7845 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -227,7 +227,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
 
 SDL_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
                  (hw, size), *size = 0, sdl_unlock)
-SDL_WRAPPER_FUNC(put_buffer_out_nowrite, size_t,
+SDL_WRAPPER_FUNC(put_buffer_out, size_t,
                  (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size),
                  /*nothing*/, sdl_unlock_and_post)
 SDL_WRAPPER_FUNC(write, size_t,
@@ -320,9 +320,12 @@ static void sdl_audio_fini (void *opaque)
 static struct audio_pcm_ops sdl_pcm_ops = {
     .init_out = sdl_init_out,
     .fini_out = sdl_fini_out,
+  /* wrapper for audio_generic_write */
     .write    = sdl_write,
+  /* wrapper for audio_generic_get_buffer_out */
     .get_buffer_out = sdl_get_buffer_out,
-    .put_buffer_out = sdl_put_buffer_out_nowrite,
+  /* wrapper for audio_generic_put_buffer_out */
+    .put_buffer_out = sdl_put_buffer_out,
     .enable_out = sdl_enable_out,
 };
 
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index e46d834bd3..20e6853f85 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -197,6 +197,7 @@ static struct audio_pcm_ops wav_pcm_ops = {
     .init_out = wav_init_out,
     .fini_out = wav_fini_out,
     .write    = wav_write_out,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = wav_enable_out,
 };
 
