X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/e75b65715b2fc9a3363bd4ac598fe02888b7ed21..fa499dad06ba6558111cdef64c18f2401e803cff:/polyp/protocol-simple.c diff --git a/polyp/protocol-simple.c b/polyp/protocol-simple.c index 58343486..f7c69d6b 100644 --- a/polyp/protocol-simple.c +++ b/polyp/protocol-simple.c @@ -4,7 +4,7 @@ This file is part of polypaudio. polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published + it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with polypaudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. @@ -37,6 +37,7 @@ #include "sample-util.h" #include "namereg.h" #include "xmalloc.h" +#include "log.h" struct connection { struct pa_protocol_simple *protocol; @@ -79,10 +80,14 @@ static void connection_free(struct connection *c) { if (c->playback.current_memblock) pa_memblock_unref(c->playback.current_memblock); - if (c->sink_input) - pa_sink_input_free(c->sink_input); - if (c->source_output) - pa_source_output_free(c->source_output); + if (c->sink_input) { + pa_sink_input_disconnect(c->sink_input); + pa_sink_input_unref(c->sink_input); + } + if (c->source_output) { + pa_source_output_disconnect(c->source_output); + pa_source_output_unref(c->source_output); + } if (c->client) pa_client_free(c->client); if (c->io) @@ -120,8 +125,8 @@ static int do_read(struct connection *c) { c->playback.memblock_index = 0; } - if ((r = pa_iochannel_read(c->io, c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { - fprintf(stderr, __FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno)); + if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { + pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno)); return -1; } @@ -153,13 +158,13 @@ static int do_write(struct connection *c) { assert(chunk.memblock && chunk.length); - if ((r = pa_iochannel_write(c->io, chunk.memblock->data+chunk.index, chunk.length)) < 0) { + if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { pa_memblock_unref(chunk.memblock); - fprintf(stderr, "write(): %s\n", strerror(errno)); + pa_log(__FILE__": write(): %s\n", strerror(errno)); return -1; } - pa_memblockq_drop(c->output_memblockq, r); + pa_memblockq_drop(c->output_memblockq, &chunk, r); pa_memblock_unref(chunk.memblock); return 0; @@ -202,11 +207,11 @@ static int sink_input_peek_cb(struct pa_sink_input *i, struct pa_memchunk *chunk return 0; } -static void sink_input_drop_cb(struct pa_sink_input *i, size_t length) { +static void sink_input_drop_cb(struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length) { struct connection*c = i->userdata; assert(i && c && length); - pa_memblockq_drop(c->input_memblockq, length); + pa_memblockq_drop(c->input_memblockq, chunk, length); /* do something */ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); @@ -219,7 +224,7 @@ static void sink_input_kill_cb(struct pa_sink_input *i) { } -static uint32_t sink_input_get_latency_cb(struct pa_sink_input *i) { +static pa_usec_t sink_input_get_latency_cb(struct pa_sink_input *i) { struct connection*c = i->userdata; assert(i && c); return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); @@ -243,6 +248,12 @@ static void source_output_kill_cb(struct pa_source_output *o) { connection_free((struct connection *) o->userdata); } +static pa_usec_t source_output_get_latency_cb(struct pa_source_output *o) { + struct connection*c = o->userdata; + assert(o && c); + return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); +} + /*** client callbacks ***/ static void client_kill_cb(struct pa_client *c) { @@ -299,12 +310,12 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo size_t l; if (!(sink = pa_namereg_get(p->core, p->sink_name, PA_NAMEREG_SINK, 1))) { - fprintf(stderr, "Failed to get sink.\n"); + pa_log(__FILE__": Failed to get sink.\n"); goto fail; } - if (!(c->sink_input = pa_sink_input_new(sink, c->client->name, &p->sample_spec))) { - fprintf(stderr, "Failed to create sink input.\n"); + if (!(c->sink_input = pa_sink_input_new(sink, c->client->name, &p->sample_spec, 0, -1))) { + pa_log(__FILE__": Failed to create sink input.\n"); goto fail; } @@ -329,13 +340,13 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo size_t l; if (!(source = pa_namereg_get(p->core, p->source_name, PA_NAMEREG_SOURCE, 1))) { - fprintf(stderr, "Failed to get source.\n"); + pa_log(__FILE__": Failed to get source.\n"); goto fail; } - c->source_output = pa_source_output_new(source, c->client->name, &p->sample_spec); + c->source_output = pa_source_output_new(source, c->client->name, &p->sample_spec, -1); if (!c->source_output) { - fprintf(stderr, "Failed to create source output.\n"); + pa_log(__FILE__": Failed to create source output.\n"); goto fail; } c->source_output->owner = p->module; @@ -343,6 +354,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo c->source_output->push = source_output_push_cb; c->source_output->kill = source_output_kill_cb; + c->source_output->get_latency = source_output_get_latency_cb; c->source_output->userdata = c; l = (size_t) (pa_bytes_per_second(&p->sample_spec)*RECORD_BUFFER_SECONDS); @@ -366,7 +378,7 @@ fail: struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct pa_socket_server *server, struct pa_module *m, struct pa_modargs *ma) { struct pa_protocol_simple* p = NULL; - uint32_t enable; + int enable; assert(core && server && ma); p = pa_xmalloc0(sizeof(struct pa_protocol_simple)); @@ -377,7 +389,7 @@ struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct p p->sample_spec = core->default_sample_spec; if (pa_modargs_get_sample_spec(ma, &p->sample_spec) < 0) { - fprintf(stderr, "Failed to parse sample type specification.\n"); + pa_log(__FILE__": Failed to parse sample type specification.\n"); goto fail; } @@ -385,21 +397,21 @@ struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct p p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); enable = 0; - if (pa_modargs_get_value_u32(ma, "record", &enable) < 0) { - fprintf(stderr, __FILE__": record= expects a numeric argument.\n"); + if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) { + pa_log(__FILE__": record= expects a numeric argument.\n"); goto fail; } p->mode = enable ? RECORD : 0; enable = 1; - if (pa_modargs_get_value_u32(ma, "playback", &enable) < 0) { - fprintf(stderr, __FILE__": playback= expects a numeric argument.\n"); + if (pa_modargs_get_value_boolean(ma, "playback", &enable) < 0) { + pa_log(__FILE__": playback= expects a numeric argument.\n"); goto fail; } p->mode |= enable ? PLAYBACK : 0; if ((p->mode & (RECORD|PLAYBACK)) == 0) { - fprintf(stderr, __FILE__": neither playback nor recording enabled for protocol.\n"); + pa_log(__FILE__": neither playback nor recording enabled for protocol.\n"); goto fail; }