From e9cd585d196728e24eb6e2086405b73842bc3eb5 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 22 Apr 2010 18:01:34 +0200 Subject: [PATCH] osx_write fixes. Boy, that was broken since the switch to the buffer tree API and hasn't obviously seen any testing since then. That code is rather strange and full of braindead crap. It should be rewritten eventually. For now, this patch beats it a little bit into the direction of sanitity. --- ggo/osx_write.ggo | 2 +- osx_write.c | 59 +++++++++++++++++++++-------------------------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/ggo/osx_write.ggo b/ggo/osx_write.ggo index c73ad2a8..33c495ab 100644 --- a/ggo/osx_write.ggo +++ b/ggo/osx_write.ggo @@ -30,5 +30,5 @@ option "numbuffers" n you get buffer underruns)" int typestr="num" - default="5" + default="20" optional diff --git a/osx_write.c b/osx_write.c index f3917f64..bcff09f7 100644 --- a/osx_write.c +++ b/osx_write.c @@ -98,8 +98,7 @@ static void fill_buffer(struct osx_buffer *b, short *source, long size) { float *dest; - if (b->remaining) /* Non empty buffer, must still be playing */ - return; + assert(b->remaining == 0 || size > 0); if (b->size != size) { b->buffer = para_realloc(b->buffer, size * sizeof(float)); b->size = size; @@ -129,9 +128,14 @@ static OSStatus osx_callback(void * inClientData, m = outOutputData->mBuffers[i].mDataByteSize / sizeof(float); dest = outOutputData->mBuffers[i].mData; while (m > 0) { - if ((n = powd->from->remaining) <= 0) { - PARA_INFO_LOG("buffer underrun\n"); - return 0; + n = powd->from->remaining; + if (n <= 0) { + n = powd->from->next->remaining; + if (n <= 0) { + PARA_INFO_LOG("buffer underrun\n"); + return 0; + } + powd->from = powd->from->next; } // PARA_INFO_LOG("buf %p: n = %ld, m= %ld\n", powd->from->buffer, n, m); /* @@ -276,17 +280,6 @@ static void osx_write_close(struct writer_node *wn) free(powd); } -static int need_new_buffer(struct writer_node *wn) -{ - struct private_osx_write_data *powd = wn->private_data; - - if (wn->min_iqs > btr_get_input_queue_size(wn->btrn)) - return 0; - if (powd->to->remaining) /* Non empty buffer, must still be playing */ - return 0; - return 1; -} - static void osx_write_post_select(__a_unused struct sched *s, struct task *t) { struct writer_node *wn = container_of(t, struct writer_node, task); @@ -294,25 +287,25 @@ static void osx_write_post_select(__a_unused struct sched *s, struct task *t) struct btr_node *btrn = wn->btrn; char *data; size_t bytes; - int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF); + int ret = 0; - if (ret <= 0) - goto out; - if (!need_new_buffer(wn)) - goto out; - btr_merge(btrn, wn->min_iqs); - bytes = btr_next_buffer(btrn, &data); - fill_buffer(powd->to, (short *)data, bytes / sizeof(short)); - btr_consume(btrn, bytes); - powd->to = powd->to->next; - if (!powd->play) { - ret = -E_UNIT_START; - if (AudioOutputUnitStart(powd->audio_unit)) - goto out; - powd->play = 1; + while (powd->to->remaining <= 0) { + ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF); + if (ret <= 0) + break; + btr_merge(btrn, 8192); + bytes = btr_next_buffer(btrn, &data); + //PARA_CRIT_LOG("have: %zu\n", bytes); + fill_buffer(powd->to, (short *)data, bytes / sizeof(short)); + btr_consume(btrn, bytes); + if (!powd->play) { + ret = -E_UNIT_START; + if (AudioOutputUnitStart(powd->audio_unit)) + break; + powd->play = 1; + } + powd->to = powd->to->next; } - ret = 1; -out: if (ret < 0) btr_remove_node(btrn); t->error = ret; -- 2.39.2