@@ -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);
@@ -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,
@@ -1097,6 +1097,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;
}
@@ -1413,40 +1417,12 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
hw->pending_emul -= size;
}
-void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
+void audio_generic_run_buffer_out(HWVoiceOut *hw)
{
- if (unlikely(!hw->buf_emul)) {
- size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame;
-
- hw->buf_emul = g_malloc(calc_size);
- hw->size_emul = calc_size;
- hw->pos_emul = hw->pending_emul = 0;
- }
-
- *size = MIN(hw->size_emul - hw->pending_emul,
- hw->size_emul - hw->pos_emul);
- return hw->buf_emul + hw->pos_emul;
-}
-
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
- size_t size)
-{
- assert(buf == hw->buf_emul + hw->pos_emul &&
- size + hw->pending_emul <= hw->size_emul);
-
- hw->pending_emul += size;
- hw->pos_emul = (hw->pos_emul + size) % hw->size_emul;
-
- 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;
}
@@ -1461,11 +1437,31 @@ size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
break;
}
}
+}
+
+void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
+{
+ if (unlikely(!hw->buf_emul)) {
+ size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame;
+
+ hw->buf_emul = g_malloc(calc_size);
+ hw->size_emul = calc_size;
+ hw->pos_emul = hw->pending_emul = 0;
+ }
+
+ *size = MIN(hw->size_emul - hw->pending_emul,
+ hw->size_emul - hw->pos_emul);
+ return hw->buf_emul + hw->pos_emul;
+}
+
+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);
+
+ hw->pending_emul += size;
+ hw->pos_emul = (hw->pos_emul + size) % hw->size_emul;
- /*
- * fake we have written everything. non-written data remain in pending_emul,
- * so we do not have to clip them multiple times
- */
return size;
}
@@ -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
};
@@ -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,
@@ -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,
@@ -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,
};
@@ -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,
};