]> code.delx.au - pulseaudio/blobdiff - src/protocol-simple.c
esound protocol
[pulseaudio] / src / protocol-simple.c
index 1803936e40d32b343de58dbad976b085c556290d..80249eef0d9cde548704edf0663f5b575667af47 100644 (file)
@@ -9,6 +9,7 @@
 #include "sourceoutput.h"
 #include "protocol-simple.h"
 #include "client.h"
+#include "sample-util.h"
 
 struct connection {
     struct protocol_simple *protocol;
@@ -66,22 +67,21 @@ static int do_read(struct connection *c) {
     chunk.memblock = memblock_new(BUFSIZE);
     assert(chunk.memblock);
 
-    memblock_stamp(chunk.memblock);
-    
     if ((r = iochannel_read(c->io, chunk.memblock->data, BUFSIZE)) <= 0) {
         fprintf(stderr, "read(): %s\n", r == 0 ? "EOF" : strerror(errno));
         memblock_unref(chunk.memblock);
         return -1;
     }
 
-    chunk.memblock->length = r;
-    chunk.length = r;
+    chunk.memblock->length = chunk.length = r;
     chunk.index = 0;
 
     assert(c->input_memblockq);
     memblockq_push(c->input_memblockq, &chunk, 0);
     memblock_unref(chunk.memblock);
+    assert(c->sink_input);
     sink_notify(c->sink_input->sink);
+    
     return 0;
 }
 
@@ -96,7 +96,9 @@ static int do_write(struct connection *c) {
         return 0;    
 
     assert(c->output_memblockq);
-    memblockq_peek(c->output_memblockq, &chunk);
+    if (memblockq_peek(c->output_memblockq, &chunk) < 0)
+        return 0;
+        
     assert(chunk.memblock && chunk.length);
     
     if ((r = iochannel_write(c->io, chunk.memblock->data+chunk.index, chunk.length)) < 0) {
@@ -112,14 +114,14 @@ static int do_write(struct connection *c) {
 
 /*** sink_input callbacks ***/
 
-static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk, uint8_t *volume) {
-    struct connection*c = i->userdata;
-    assert(i && c && chunk && volume);
-
+static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk) {
+    struct connection*c;
+    assert(i && i->userdata && chunk);
+    c = i->userdata;
+    
     if (memblockq_peek(c->input_memblockq, chunk) < 0)
         return -1;
 
-    *volume = 0xFF;
     return 0;
 }
 
@@ -138,6 +140,13 @@ static void sink_input_kill_cb(struct sink_input *i) {
     destroy_connection((struct connection *) i->userdata);
 }
 
+
+static uint32_t sink_input_get_latency_cb(struct sink_input *i) {
+    struct connection*c = i->userdata;
+    assert(i && c);
+    return pa_samples_usec(memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec);
+}
+
 /*** source_output callbacks ***/
 
 static void source_output_push_cb(struct source_output *o, struct memchunk *chunk) {
@@ -145,6 +154,9 @@ static void source_output_push_cb(struct source_output *o, struct memchunk *chun
     assert(o && c && chunk);
 
     memblockq_push(c->output_memblockq, chunk, 0);
+
+    if (do_write(c) < 0)
+        destroy_connection(c);
 }
 
 static void source_output_kill_cb(struct source_output *o) {
@@ -152,7 +164,6 @@ static void source_output_kill_cb(struct source_output *o) {
     destroy_connection((struct connection *) o->userdata);
 }
 
-
 /*** client callbacks ***/
 
 static void client_kill_cb(struct client *c) {
@@ -175,6 +186,7 @@ static void io_callback(struct iochannel*io, void *userdata) {
 static void on_connection(struct socket_server*s, struct iochannel *io, void *userdata) {
     struct protocol_simple *p = userdata;
     struct connection *c = NULL;
+    char cname[256];
     assert(s && io && p);
 
     c = malloc(sizeof(struct connection));
@@ -185,7 +197,8 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
     c->input_memblockq = c->output_memblockq = NULL;
     c->protocol = p;
 
-    c->client = client_new(p->core, "SIMPLE", "Client");
+    iochannel_peer_to_string(io, cname, sizeof(cname));
+    c->client = client_new(p->core, "SIMPLE", cname);
     assert(c->client);
     c->client->kill = client_kill_cb;
     c->client->userdata = c;
@@ -194,7 +207,7 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
         struct source *source;
         size_t l;
 
-        if (!(source = core_get_default_source(p->core))) {
+        if (!(source = source_get_default(p->core))) {
             fprintf(stderr, "Failed to get default source.\n");
             goto fail;
         }
@@ -205,15 +218,15 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
         c->source_output->kill = source_output_kill_cb;
         c->source_output->userdata = c;
 
-        l = 5*bytes_per_second(&DEFAULT_SAMPLE_SPEC);
-        c->output_memblockq = memblockq_new(l, sample_size(&DEFAULT_SAMPLE_SPEC), l/2);
+        l = 5*pa_bytes_per_second(&DEFAULT_SAMPLE_SPEC); /* 5s */
+        c->output_memblockq = memblockq_new(l, pa_sample_size(&DEFAULT_SAMPLE_SPEC), l/2);
     }
 
     if (p->mode & PROTOCOL_SIMPLE_PLAYBACK) {
         struct sink *sink;
         size_t l;
 
-        if (!(sink = core_get_default_sink(p->core))) {
+        if (!(sink = sink_get_default(p->core))) {
             fprintf(stderr, "Failed to get default sink.\n");
             goto fail;
         }
@@ -223,10 +236,11 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
         c->sink_input->peek = sink_input_peek_cb;
         c->sink_input->drop = sink_input_drop_cb;
         c->sink_input->kill = sink_input_kill_cb;
+        c->sink_input->get_latency = sink_input_get_latency_cb;
         c->sink_input->userdata = c;
 
-        l = 5*bytes_per_second(&DEFAULT_SAMPLE_SPEC);
-        c->input_memblockq = memblockq_new(l, sample_size(&DEFAULT_SAMPLE_SPEC), l/2);
+        l = pa_bytes_per_second(&DEFAULT_SAMPLE_SPEC)/2; /* half a second */
+        c->input_memblockq = memblockq_new(l, pa_sample_size(&DEFAULT_SAMPLE_SPEC), l/2);
     }