From: Andre Noll Date: Wed, 23 Aug 2006 18:37:07 +0000 (+0200) Subject: osx_write.c: fix pre_select() X-Git-Tag: v0.2.14~33 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=4ca9b7b4365ee056687c4c9a626beb90452e7997 osx_write.c: fix pre_select() The old code was just a quick hack. Good enough for para_write, but it had no chance to work for para_audiod. Fix it by looking at the number of bytes left in the current from buffer and calculating the delay accordingly. --- diff --git a/osx_write.c b/osx_write.c index 39af5000..287601c7 100644 --- a/osx_write.c +++ b/osx_write.c @@ -44,7 +44,7 @@ struct osx_buffer { long remaining; struct osx_buffer *next; }; -typedef struct osx_buffer osx_buffer; +typedef struct osx_buffer osx_buffer; /* FIXME */ struct private_osx_write_data { long size; @@ -103,7 +103,6 @@ static void fill_buffer(osx_buffer *b, short *source, long size) if (b->remaining) /* Non empty buffer, must still be playing */ return; - PARA_INFO_LOG("%ld\n", size); if (b->size != size) { b->buffer = para_realloc(b->buffer, size * sizeof(float)); b->size = size; @@ -146,7 +145,7 @@ static OSStatus osx_callback(void * inClientData, /* wait for the results */ usleep(2000); } - PARA_INFO_LOG("buf %p: n = %ld, m= %ld\n", powd->from->buffer, n, m); +// PARA_INFO_LOG("buf %p: n = %ld, m= %ld\n", powd->from->buffer, n, m); /* * we dump what we can. In fact, just the necessary * should be sufficient @@ -308,8 +307,28 @@ static int osx_write_post_select(__a_unused struct sched *s, static int osx_write_pre_select(struct sched *s, __a_unused struct writer_node *wn) { + struct private_osx_write_data *powd = wn->private_data; + struct writer_node_group *wng = wn->wng; + size_t numbytes = powd->to->remaining * sizeof(short); + struct timeval tmp = {.tv_sec = 1, .tv_usec = 0}, delay = tmp; + unsigned long divisor; + + if (!numbytes && *wng->loaded >= sizeof(short)) + goto min_delay; /* there's a buffer to fill */ + if (!numbytes) + return 1; + divisor = powd->samplerate * powd->channels * 2 / numbytes; + if (divisor) + tv_divide(divisor, &tmp, &delay); + if (tv_diff(&s->timeout, &delay, NULL) > 0) + s->timeout = delay; +// PARA_DEBUG_LOG("delay: %lu:%lu\n", (long unsigned) s->timeout.tv_sec, +// (long unsigned) s->timeout.tv_usec); + return 1; +min_delay: + PARA_DEBUG_LOG("%s\n", "minimal delay"); s->timeout.tv_sec = 0; - s->timeout.tv_usec = 20; + s->timeout.tv_usec = 1; return 1; }