]> code.delx.au - pulseaudio/commitdiff
cleanup
authorLennart Poettering <lennart@poettering.net>
Tue, 15 Jun 2004 17:05:03 +0000 (17:05 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 15 Jun 2004 17:05:03 +0000 (17:05 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@18 fefdeb5f-60dc-0310-8127-8f9354f1896f

19 files changed:
src/Makefile.am
src/client.c
src/client.h
src/core.c
src/core.h
src/idxset.c
src/idxset.h
src/module-pipe-sink.c
src/protocol-simple.c
src/sample.c
src/sample.h
src/sink.c
src/sink.h
src/sinkinput.c
src/sinkinput.h
src/source.c
src/source.h
src/sourceoutput.c
src/sourceoutput.h

index f09538462841478f2656010c3ce0ee639095e537..40e2039d492c01483ecd9822d813319ef66d513c 100644 (file)
@@ -26,7 +26,7 @@ pkglib_LTLIBRARIES=libprotocol-simple.la module-simple-protocol-tcp.la \
 
 polypaudio_SOURCES = idxset.c queue.c strbuf.c mainloop.c  \
                memblock.c sample.c memblockq.c client.c \
-               core.c main.c outputstream.c inputstream.c source.c sink.c \
+               core.c main.c sourceoutput.c sinkinput.c source.c sink.c \
                module.c
 polypaudio_INCLUDES = $(INCLTDL)
 polypaudio_LDADD = $(LIBLTDL) 
index 578d51c32539cabf536beff44f593760a9885c4f..1b84c6bf59c452210a888ee9196a859ee3eec6b5 100644 (file)
@@ -12,11 +12,12 @@ struct client *client_new(struct core *core, const char *protocol_name, char *na
 
     c = malloc(sizeof(struct client));
     assert(c);
-    c->protocol_name = protocol_name;
     c->name = name ? strdup(name) : NULL;
-    c->kill = NULL;
-    c->kill_userdata = NULL;
     c->core = core;
+    c->protocol_name = protocol_name;
+
+    c->kill = NULL;
+    c->userdata = NULL;
 
     r = idxset_put(core->clients, c, &c->index);
     assert(c->index != IDXSET_INVALID && r >= 0);
@@ -35,14 +36,9 @@ void client_free(struct client *c) {
     free(c);
 }
 
-void client_set_kill_callback(struct client *c, void (*kill)(struct client *c, void *userdata), void *userdata) {
-    assert(c && kill);
-    c->kill = kill;
-    c->kill_userdata = userdata;
-}
-
 void client_kill(struct client *c) {
     assert(c);
-    c->kill(c, c->kill_userdata);
+    if (c->kill)
+        c->kill(c);
 }
 
index 8d9e519c09cdfc17b75b130e8969a7524ce352ac..556b5fb3dfa1d7cb59900a70a5dbff65dc9f34a6 100644 (file)
@@ -4,15 +4,15 @@
 #include "core.h"
 
 struct client {
-    char *name;
     uint32_t index;
-    
+
+    char *name;
+    struct core *core;
     const char *protocol_name;
 
-    void *kill_userdata;
-    void (*kill)(struct client *c, void *userdata);
+    void (*kill)(struct client *c);
 
-    struct core *core;
+    void *userdata;
 };
 
 struct client *client_new(struct core *c, const char *protocol_name, char *name);
@@ -20,11 +20,6 @@ struct client *client_new(struct core *c, const char *protocol_name, char *name)
 /* This function should be called only by the code that created the client */
 void client_free(struct client *c);
 
-/* The registrant of the client should call this function to set a
- * callback function which is called when destruction of the client is
- * requested */
-void client_set_kill_callback(struct client *c, void (*kill)(struct client *c, void *userdata), void *userdata);
-
 /* Code that didn't create the client should call this function to
  * request destruction of the client */
 void client_kill(struct client *c);
index 2e67118a9484a8d9f57a2bf14eb9cfd9d5c0717a..0bc13a5b9a8a77671fa6ce7f0e335b0517cca3ba 100644 (file)
@@ -16,8 +16,8 @@ struct core* core_new(struct mainloop *m) {
     c->clients = idxset_new(NULL, NULL);
     c->sinks = idxset_new(NULL, NULL);
     c->sources = idxset_new(NULL, NULL);
-    c->output_streams = idxset_new(NULL, NULL);
-    c->input_streams = idxset_new(NULL, NULL);
+    c->source_outputs = idxset_new(NULL, NULL);
+    c->sink_inputs = idxset_new(NULL, NULL);
 
     c->default_source_index = c->default_sink_index = IDXSET_INVALID;
 
@@ -41,11 +41,11 @@ void core_free(struct core *c) {
     assert(idxset_isempty(c->sources));
     idxset_free(c->sources, NULL, NULL);
     
-    assert(idxset_isempty(c->output_streams));
-    idxset_free(c->output_streams, NULL, NULL);
+    assert(idxset_isempty(c->source_outputs));
+    idxset_free(c->source_outputs, NULL, NULL);
     
-    assert(idxset_isempty(c->input_streams));
-    idxset_free(c->input_streams, NULL, NULL);
+    assert(idxset_isempty(c->sink_inputs));
+    idxset_free(c->sink_inputs, NULL, NULL);
 
     free(c);    
 };
index 649c9dbad4d5bba81f9b2e0cfbe43b84bc903f8a..a8a140b8939a9cfa07a092a725c66d341737d203 100644 (file)
@@ -7,7 +7,7 @@
 struct core {
     struct mainloop *mainloop;
 
-    struct idxset *clients, *sinks, *sources, *output_streams, *input_streams, *modules;
+    struct idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules;
 
     uint32_t default_source_index, default_sink_index;
 };
index 4442190d7b356a05496ec8e61b2171897a7acf7b..ea609f601281639b06b35c7a477d4a06bcbb99d3 100644 (file)
@@ -291,9 +291,7 @@ void* idxset_rrobin(struct idxset *s, uint32_t *index) {
     if (!e)
         return NULL;
     
-    if (index)
-        *index = e->index;
-
+    *index = e->index;
     return e->data;
 }
 
@@ -308,6 +306,22 @@ void* idxset_first(struct idxset *s, uint32_t *index) {
     return s->iterate_list_head->data;
 }
 
+void *idxset_next(struct idxset *s, uint32_t *index) {
+    struct idxset_entry **a, *e = NULL;
+    assert(s && index);
+
+    if ((a = array_index(s, *index)) && *a)
+        e = (*a)->iterate_next;
+    
+    if (e) {
+        *index = e->index;
+        return e->data;
+    } else {
+        *index = IDXSET_INVALID;
+        return NULL;
+    }
+}
+
 
 int idxset_foreach(struct idxset*s, int (*func)(void *p, uint32_t index, int *del, void*userdata), void *userdata) {
     struct idxset_entry *e;
@@ -341,3 +355,4 @@ int idxset_isempty(struct idxset *s) {
     assert(s);
     return s->n_entries == 0;
 }
+
index fdcb7b54bdda54d148cc48462d64cee51fb52508..90b9d247818b805f4bf300e3e7077c7db5cd233e 100644 (file)
@@ -26,10 +26,12 @@ void* idxset_rrobin(struct idxset *s, uint32_t *index);
 
 /* Return the oldest entry in the idxset */
 void* idxset_first(struct idxset *s, uint32_t *index);
+void *idxset_next(struct idxset *s, uint32_t *index);
 
 int idxset_foreach(struct idxset*s, int (*func)(void *p, uint32_t index, int *del, void*userdata), void *userdata);
 
 unsigned idxset_ncontents(struct idxset*s);
 int idxset_isempty(struct idxset *s);
 
+
 #endif
index e63a7a86fdf072fa8482dcf817784ac2c597b394..c0a903e9493a3794fac69423ac337203c9121e5a 100644 (file)
@@ -52,9 +52,9 @@ static void do_write(struct userdata *u) {
     }
 }
 
-static void notify_callback(struct sink*s, void *userdata) {
-    struct userdata *u = userdata;
-    assert(u);
+static void notify_cb(struct sink*s) {
+    struct userdata *u = s->userdata;
+    assert(s && u);
 
     if (iochannel_is_writable(u->io))
         mainloop_source_enable(u->mainloop_source, 1);
@@ -77,7 +77,7 @@ int module_init(struct core *c, struct module*m) {
     struct stat st;
     char *p;
     int fd = -1;
-    const static struct sample_spec ss = {
+    static const struct sample_spec ss = {
         .format = SAMPLE_S16NE,
         .rate = 44100,
         .channels = 2,
@@ -110,7 +110,8 @@ int module_init(struct core *c, struct module*m) {
     u->core = c;
     u->sink = sink_new(c, "fifo", &ss);
     assert(u->sink);
-    sink_set_notify_callback(u->sink, notify_callback, u);
+    u->sink->notify = notify_cb;
+    u->sink->userdata = u;
 
     u->io = iochannel_new(c->mainloop, -1, fd);
     assert(u->io);
index d34a5d021182f503fd1a1a16c8137e3484ed9edc..1803936e40d32b343de58dbad976b085c556290d 100644 (file)
@@ -5,17 +5,18 @@
 #include <errno.h>
 #include <string.h>
 
-#include "inputstream.h"
-#include "outputstream.h"
+#include "sinkinput.h"
+#include "sourceoutput.h"
 #include "protocol-simple.h"
 #include "client.h"
 
 struct connection {
     struct protocol_simple *protocol;
     struct iochannel *io;
-    struct input_stream *istream;
-    struct output_stream *ostream;
+    struct sink_input *sink_input;
+    struct source_output *source_output;
     struct client *client;
+    struct memblockq *input_memblockq, *output_memblockq;
 };
 
 struct protocol_simple {
@@ -31,14 +32,18 @@ static void free_connection(void *data, void *userdata) {
     struct connection *c = data;
     assert(data);
     
-    if (c->istream)
-        input_stream_free(c->istream);
-    if (c->ostream)
-        output_stream_free(c->ostream);
-
-    client_free(c->client);
-
-    iochannel_free(c->io);
+    if (c->sink_input)
+        sink_input_free(c->sink_input);
+    if (c->source_output)
+        source_output_free(c->source_output);
+    if (c->client)
+        client_free(c->client);
+    if (c->io)
+        iochannel_free(c->io);
+    if (c->input_memblockq)
+        memblockq_free(c->input_memblockq);
+    if (c->output_memblockq)
+        memblockq_free(c->output_memblockq);
     free(c);
 }
 
@@ -48,24 +53,6 @@ static void destroy_connection(struct connection *c) {
     free_connection(c, NULL);
 }
 
-static void istream_kill_cb(struct input_stream *i, void *userdata) {
-    struct connection *c = userdata;
-    assert(i && c);
-    destroy_connection(c);
-}
-
-static void ostream_kill_cb(struct output_stream *o, void *userdata) {
-    struct connection *c = userdata;
-    assert(o && c);
-    destroy_connection(c);
-}
-
-static void client_kill_cb(struct client *client, void*userdata) {
-    struct connection *c= userdata;
-    assert(client && c);
-    destroy_connection(c);
-}
-
 static int do_read(struct connection *c) {
     struct memchunk chunk;
     ssize_t r;
@@ -73,7 +60,7 @@ static int do_read(struct connection *c) {
     if (!iochannel_is_readable(c->io))
         return 0;
     
-    if (!c->istream || !memblockq_is_writable(c->istream->memblockq, BUFSIZE))
+    if (!c->sink_input || !memblockq_is_writable(c->input_memblockq, BUFSIZE))
         return 0;
     
     chunk.memblock = memblock_new(BUFSIZE);
@@ -90,10 +77,11 @@ static int do_read(struct connection *c) {
     chunk.memblock->length = r;
     chunk.length = r;
     chunk.index = 0;
-    
-    memblockq_push(c->istream->memblockq, &chunk, 0);
-    input_stream_notify_sink(c->istream);
+
+    assert(c->input_memblockq);
+    memblockq_push(c->input_memblockq, &chunk, 0);
     memblock_unref(chunk.memblock);
+    sink_notify(c->sink_input->sink);
     return 0;
 }
 
@@ -104,10 +92,11 @@ static int do_write(struct connection *c) {
     if (!iochannel_is_writable(c->io))
         return 0;
     
-    if (!c->ostream)
+    if (!c->source_output)
         return 0;    
 
-    memblockq_peek(c->ostream->memblockq, &chunk);
+    assert(c->output_memblockq);
+    memblockq_peek(c->output_memblockq, &chunk);
     assert(chunk.memblock && chunk.length);
     
     if ((r = iochannel_write(c->io, chunk.memblock->data+chunk.index, chunk.length)) < 0) {
@@ -116,11 +105,63 @@ static int do_write(struct connection *c) {
         return -1;
     }
     
-    memblockq_drop(c->ostream->memblockq, r);
+    memblockq_drop(c->output_memblockq, r);
     memblock_unref(chunk.memblock);
     return 0;
 }
 
+/*** 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);
+
+    if (memblockq_peek(c->input_memblockq, chunk) < 0)
+        return -1;
+
+    *volume = 0xFF;
+    return 0;
+}
+
+static void sink_input_drop_cb(struct sink_input *i, size_t length) {
+    struct connection*c = i->userdata;
+    assert(i && c && length);
+
+    memblockq_drop(c->input_memblockq, length);
+    
+    if (do_read(c) < 0)
+        destroy_connection(c);
+}
+
+static void sink_input_kill_cb(struct sink_input *i) {
+    assert(i && i->userdata);
+    destroy_connection((struct connection *) i->userdata);
+}
+
+/*** source_output callbacks ***/
+
+static void source_output_push_cb(struct source_output *o, struct memchunk *chunk) {
+    struct connection *c = o->userdata;
+    assert(o && c && chunk);
+
+    memblockq_push(c->output_memblockq, chunk, 0);
+}
+
+static void source_output_kill_cb(struct source_output *o) {
+    assert(o && o->userdata);
+    destroy_connection((struct connection *) o->userdata);
+}
+
+
+/*** client callbacks ***/
+
+static void client_kill_cb(struct client *c) {
+    assert(c && c->userdata);
+    destroy_connection((struct connection *) c->userdata);
+}
+
+/*** iochannel callbacks ***/
+
 static void io_callback(struct iochannel*io, void *userdata) {
     struct connection *c = userdata;
     assert(io && c && c->io == io);
@@ -129,13 +170,7 @@ static void io_callback(struct iochannel*io, void *userdata) {
         destroy_connection(c);
 }
 
-static void istream_notify_cb(struct input_stream *i, void *userdata) {
-    struct connection*c = userdata;
-    assert(i && c && c->istream == i);
-    
-    if (do_read(c) < 0)
-        destroy_connection(c);
-}
+/*** socket_server callbacks */
 
 static void on_connection(struct socket_server*s, struct iochannel *io, void *userdata) {
     struct protocol_simple *p = userdata;
@@ -145,39 +180,53 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
     c = malloc(sizeof(struct connection));
     assert(c);
     c->io = io;
-    c->istream = NULL;
-    c->ostream = NULL;
+    c->sink_input = NULL;
+    c->source_output = NULL;
+    c->input_memblockq = c->output_memblockq = NULL;
     c->protocol = p;
 
     c->client = client_new(p->core, "SIMPLE", "Client");
     assert(c->client);
-    client_set_kill_callback(c->client, client_kill_cb, c);
+    c->client->kill = client_kill_cb;
+    c->client->userdata = c;
 
     if (p->mode & PROTOCOL_SIMPLE_RECORD) {
         struct source *source;
+        size_t l;
 
         if (!(source = core_get_default_source(p->core))) {
             fprintf(stderr, "Failed to get default source.\n");
             goto fail;
         }
 
-        c->ostream = output_stream_new(source, &DEFAULT_SAMPLE_SPEC, c->client->name);
-        assert(c->ostream);
-        output_stream_set_kill_callback(c->ostream, ostream_kill_cb, c);
+        c->source_output = source_output_new(source, &DEFAULT_SAMPLE_SPEC, c->client->name);
+        assert(c->source_output);
+        c->source_output->push = source_output_push_cb;
+        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);
     }
 
     if (p->mode & PROTOCOL_SIMPLE_PLAYBACK) {
         struct sink *sink;
+        size_t l;
 
         if (!(sink = core_get_default_sink(p->core))) {
             fprintf(stderr, "Failed to get default sink.\n");
             goto fail;
         }
 
-        c->istream = input_stream_new(sink, &DEFAULT_SAMPLE_SPEC, c->client->name);
-        assert(c->istream);
-        input_stream_set_kill_callback(c->istream, istream_kill_cb, c);
-        input_stream_set_notify_callback(c->istream, istream_notify_cb, c);
+        c->sink_input = sink_input_new(sink, &DEFAULT_SAMPLE_SPEC, c->client->name);
+        assert(c->sink_input);
+        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->userdata = c;
+
+        l = 5*bytes_per_second(&DEFAULT_SAMPLE_SPEC);
+        c->input_memblockq = memblockq_new(l, sample_size(&DEFAULT_SAMPLE_SPEC), l/2);
     }
 
 
@@ -187,13 +236,7 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
     
 fail:
     if (c) {
-        if (c->client)
-            client_free(c->client);
-        if (c->istream)
-            input_stream_free(c->istream);
-        if (c->ostream)
-            output_stream_free(c->ostream);
-
+        free_connection(c, NULL);
         iochannel_free(c->io);
         free(c);
     }
index 6a00022822bf9dff09e0a351133a50366934d4aa..21c04628522f2ac3ca9d4f3f9d24595b39bb448b 100644 (file)
@@ -60,9 +60,9 @@ size_t bytes_per_second(struct sample_spec *spec) {
     return spec->rate*sample_size(spec);
 }
 
-size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct sample_spec *spec) {
+size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct sample_spec *spec, uint8_t volume) {
     unsigned c, d;
-    assert(chunks && target && spec);
+    assert(channels && data && length && spec);
     assert(spec->format == SAMPLE_S16NE);
 
     for (d = 0;; d += sizeof(int16_t)) {
@@ -81,7 +81,7 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si
             if (volume == 0)
                 v = 0;
             else {
-                v = *((int16_t*) (channels[c].chunk->memblock->data + channels[c].chunk->index + d));
+                v = *((int16_t*) (channels[c].chunk.memblock->data + channels[c].chunk.index + d));
 
                 if (volume != 0xFF)
                     v = v*volume/0xFF;
@@ -90,8 +90,15 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si
             sum += v;
         }
 
+        if (volume == 0)
+            sum = 0;
+        else if (volume != 0xFF)
+            sum = sum*volume/0xFF;
+        
         if (sum < -0x8000) sum = -0x8000;
         if (sum > 0x7FFF) sum = 0x7FFF;
-        *(data++) = sum;
+        
+        *((int16_t*) data) = sum;
+        data += sizeof(int16_t);
     }
 }
index 651788bae5a1dd59e0373202ce0c6be19560ba34..f8ba66983cc4f23d85a86546329f6bc94313caf8 100644 (file)
@@ -35,7 +35,7 @@ struct mix_info {
     void *userdata;
 };
 
-size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct sample_spec *spec) {
+size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct sample_spec *spec, uint8_t volume);
 
 size_t bytes_per_second(struct sample_spec *spec);
 size_t sample_size(struct sample_spec *spec);
index 82cde8f293bbdcb2ddb8abc21d867bd82813ae84..951191dd48bf660949878adbf06f7402d44e4644 100644 (file)
@@ -4,7 +4,9 @@
 #include <stdio.h>
 
 #include "sink.h"
-#include "inputstream.h"
+#include "sinkinput.h"
+
+#define MAX_MIX_CHANNELS 32
 
 struct sink* sink_new(struct core *core, const char *name, const struct sample_spec *spec) {
     struct sink *s;
@@ -16,9 +18,6 @@ struct sink* sink_new(struct core *core, const char *name, const struct sample_s
     assert(s);
     
     s->name = name ? strdup(name) : NULL;
-    r = idxset_put(core->sinks, s, &s->index);
-    assert(s->index != IDXSET_INVALID && r >= 0);
-
     s->core = core;
     s->sample_spec = *spec;
     s->inputs = idxset_new(NULL, NULL);
@@ -34,8 +33,11 @@ struct sink* sink_new(struct core *core, const char *name, const struct sample_s
     s->volume = 0xFF;
 
     s->notify = NULL;
-    s->notify_userdata = NULL;
+    s->userdata = NULL;
 
+    r = idxset_put(core->sinks, s, &s->index);
+    assert(s->index != IDXSET_INVALID && r >= 0);
+    
     fprintf(stderr, "sink: created %u \"%s\".\n", s->index, s->name);
     
     return s;
@@ -46,15 +48,14 @@ void sink_free(struct sink *s) {
     assert(s);
 
     while ((i = idxset_first(s->inputs, NULL))) {
-        assert(i != j && i->kill);
-        i->kill(i);
+        assert(i != j);
+        sink_input_kill(i);
         j = i;
     }
-
     idxset_free(s->inputs, NULL, NULL);
-        
-    idxset_remove_by_data(s->core->sinks, s, NULL);
+
     source_free(s->monitor_source);
+    idxset_remove_by_data(s->core->sinks, s, NULL);
 
     fprintf(stderr, "sink: freed %u \"%s\"\n", s->index, s->name);
     
@@ -66,24 +67,17 @@ void sink_notify(struct sink*s) {
     assert(s);
 
     if (s->notify)
-        s->notify(s, s->notify_userdata);
-}
-
-void sink_set_notify_callback(struct sink *s, void (*notify_callback)(struct sink*sink, void *userdata), void *userdata) {
-    assert(s && notify_callback);
-
-    s->notify = notify_callback;
-    s->notify_userdata = userdata;
+        s->notify(s);
 }
 
 static unsigned fill_mix_info(struct sink *s, struct mix_info *info, unsigned maxinfo) {
-    uint32_t index = IDXSET_ANY;
+    uint32_t index = IDXSET_INVALID;
     struct sink_input *i;
-    unsigned n;
+    unsigned n = 0;
     
     assert(s && info);
 
-    while (maxinfo > 0 && i = idxset_rrobin(s->inputs, &index)) {
+    for (i = idxset_first(s->inputs, &index); maxinfo > 0 && i; i = idxset_next(s->inputs, &index)) {
         assert(i->peek);
         if (i->peek(i, &info->chunk, &info->volume) < 0)
             continue;
@@ -125,7 +119,7 @@ int sink_render(struct sink*s, size_t length, struct memchunk *result) {
 
     if (n == 1) {
         struct sink_info *i = info[0].userdata;
-        assert(i && b);
+        assert(i);
         *result = info[0].chunk;
         memblock_ref(result->memblock);
 
@@ -137,7 +131,7 @@ int sink_render(struct sink*s, size_t length, struct memchunk *result) {
         result->memblock = memblock_new(length);
         assert(result->memblock);
 
-        result->length = l = mix_chunks(info, n, result->memblock->data, length, &s->sample_spec);
+        result->length = l = mix_chunks(info, n, result->memblock->data, length, &s->sample_spec, s->volume);
         result->index = 0;
         
         assert(l);
@@ -160,7 +154,7 @@ int sink_render_into(struct sink*s, struct memblock *target, struct memchunk *re
 
     if (n == 1) {
         struct sink_info *i = info[0].userdata;
-        assert(i && b);
+        assert(i);
 
         l = target->length;
         if (l > info[0].chunk.length)
@@ -170,15 +164,10 @@ int sink_render_into(struct sink*s, struct memblock *target, struct memchunk *re
         memcpy(target->data, info[0].chunk.memblock->data + info[0].chunk.index, l);
         result->length = target->length = l;
         result->index = 0;
-
-        if (result->length > length)
-            result->length = length;
-
-        l = result->length;
     } else {
 
         result->memblock = target;
-        result->length = l = mix_chunks(info, n, target->data, target->length, &s->sample_spec);
+        result->length = l = mix_chunks(info, n, target->data, target->length, &s->sample_spec, s->volume);
         result->index = 0;
         assert(l);
     }
index bd43d49de757a8650b4e70828e304991be854088..ccfa2590169573afeb70d5c2b98e316725034a26 100644 (file)
@@ -10,21 +10,10 @@ struct sink;
 #include "idxset.h"
 #include "source.h"
 
-
-struct sink_input {
-    int (*peek) (struct sink_input *i, struct memchunk *chunk, uint8_t *volume);
-    void (*drop) (struct sink_input *i, size_t length);
-    void (*kill) (struct sink_input *i);
-
-    void *userdata;
-    int index;
-    struct sink *sink;
-};
-
 struct sink {
-    char *name;
     uint32_t index;
-    
+
+    char *name;
     struct core *core;
     struct sample_spec sample_spec;
     struct idxset *inputs;
@@ -33,8 +22,8 @@ struct sink {
 
     uint8_t volume;
 
-    void (*notify)(struct sink*sink, void *userdata);
-    void *notify_userdata;
+    void (*notify)(struct sink*sink);
+    void *userdata;
 };
 
 struct sink* sink_new(struct core *core, const char *name, const struct sample_spec *spec);
@@ -44,6 +33,5 @@ int sink_render(struct sink*s, size_t length, struct memchunk *result);
 int sink_render_into(struct sink*s, struct memblock *target, struct memchunk *result);
 
 void sink_notify(struct sink*s);
-void sink_set_notify_callback(struct sink *s, void (*notify_callback)(struct sink*sink, void *userdata), void *userdata);
 
 #endif
index 6bc841acfa324d7878218c391a9b3be9a04f0dc0..ae7b27ff79b02428cea881b59c182908a436a833 100644 (file)
@@ -2,81 +2,47 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "inputstream.h"
+#include "sinkinput.h"
 
-struct input_stream* input_stream_new(struct sink *s, struct sample_spec *spec, const char *name) {
-    struct input_stream *i;
+struct sink_input* sink_input_new(struct sink *s, struct sample_spec *spec, const char *name) {
+    struct sink_input *i;
     int r;
     assert(s && spec);
 
-    i = malloc(sizeof(struct input_stream));
+    i = malloc(sizeof(struct sink_input));
     assert(i);
     i->name = name ? strdup(name) : NULL;
     i->sink = s;
     i->spec = *spec;
 
+    i->peek = NULL;
+    i->drop = NULL;
     i->kill = NULL;
-    i->kill_userdata = NULL;
-    i->notify = NULL;
-    i->notify_userdata = NULL;
+    i->userdata = NULL;
 
-    i->memblockq = memblockq_new(bytes_per_second(spec)/2, sample_size(spec), (size_t) -1);
-    assert(i->memblockq);
-    
     assert(s->core);
-    r = idxset_put(s->core->input_streams, i, &i->index);
+    r = idxset_put(s->core->sink_inputs, i, &i->index);
     assert(r == 0 && i->index != IDXSET_INVALID);
-    r = idxset_put(s->input_streams, i, NULL);
+    r = idxset_put(s->inputs, i, NULL);
     assert(r == 0);
     
     return i;    
 }
 
-void input_stream_free(struct input_stream* i) {
+void sink_input_free(struct sink_input* i) {
     assert(i);
 
-    memblockq_free(i->memblockq);
-
     assert(i->sink && i->sink->core);
-    idxset_remove_by_data(i->sink->core->input_streams, i, NULL);
-    idxset_remove_by_data(i->sink->input_streams, i, NULL);
+    idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL);
+    idxset_remove_by_data(i->sink->inputs, i, NULL);
     
     free(i->name);
     free(i);
 }
 
-void input_stream_notify_sink(struct input_stream *i) {
-    assert(i);
-
-    if (!memblockq_is_readable(i->memblockq))
-        return;
-    
-    sink_notify(i->sink);
-}
-
-void input_stream_set_kill_callback(struct input_stream *i, void (*kill)(struct input_stream*i, void *userdata), void *userdata) {
-    assert(i && kill);
-    i->kill = kill;
-    i->kill_userdata = userdata;
-}
-
-
-void input_stream_kill(struct input_stream*i) {
+void sink_input_kill(struct sink_input*i) {
     assert(i);
 
     if (i->kill)
-        i->kill(i, i->kill_userdata);
-}
-
-void input_stream_set_notify_callback(struct input_stream *i, void (*notify)(struct input_stream*i, void *userdata), void *userdata) {
-    assert(i && notify);
-
-    i->notify = notify;
-    i->notify_userdata = userdata;
-}
-
-void input_stream_notify(struct input_stream *i) {
-    assert(i);
-    if (i->notify)
-        i->notify(i, i->notify_userdata);
+        i->kill(i);
 }
index 544c3318839d3bbed2954a7ae99dbd7ab00db49f..5e71d2108700512235aaaf23a8828b39ac7a1134 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef fooinputstreamhfoo
-#define fooinputstreamhfoo
+#ifndef foosinkinputhfoo
+#define foosinkinputhfoo
 
 #include <inttypes.h>
 
@@ -7,44 +7,26 @@
 #include "sample.h"
 #include "memblockq.h"
 
-struct input_stream {
-    char *name;
+struct sink_input {
     uint32_t index;
 
+    char *name;
     struct sink *sink;
     struct sample_spec spec;
     
-    struct memblockq *memblockq;
+    int (*peek) (struct sink_input *i, struct memchunk *chunk, uint8_t *volume);
+    void (*drop) (struct sink_input *i, size_t length);
+    void (*kill) (struct sink_input *i);
 
-    void (*kill)(struct input_stream* i, void *userdata);
-    void *kill_userdata;
-
-    void (*notify)(struct input_stream*i, void *userdata);
-    void *notify_userdata;
+    void *userdata;
 };
 
-struct input_stream* input_stream_new(struct sink *s, struct sample_spec *spec, const char *name);
-void input_stream_free(struct input_stream* i);
-
-/* This function notifies the attached sink that new data is available
- * in the memblockq */
-void input_stream_notify_sink(struct input_stream *i);
-
-
-/* The registrant of the input stream should call this function to set a
- * callback function which is called when destruction of the input stream is
- * requested */
-void input_stream_set_kill_callback(struct input_stream *i, void (*kill)(struct input_stream*i, void *userdata), void *userdata);
+struct sink_input* sink_input_new(struct sink *s, struct sample_spec *spec, const char *name);
+void sink_input_free(struct sink_input* i);
 
 /* Code that didn't create the input stream should call this function to
  * request destruction of it */
-void input_stream_kill(struct input_stream *i);
-
-/* Notify the code that created this input stream that some data has
- * been removed from the memblockq */
-void input_stream_set_notify_callback(struct input_stream *i, void (*notify)(struct input_stream*i, void *userdata), void *userdata);
-
-void input_stream_notify(struct input_stream *i);
+void sink_input_kill(struct sink_input *i);
 
 
 #endif
index a7fc9a64f22970bc7edf9dd34eac8a3e73b69e4b..e01e9f8362f4002a746e9ec2b2a95bb3c8697ec0 100644 (file)
@@ -4,7 +4,7 @@
 #include <string.h>
 
 #include "source.h"
-#include "outputstream.h"
+#include "sourceoutput.h"
 
 struct source* source_new(struct core *core, const char *name, const struct sample_spec *spec) {
     struct source *s;
@@ -15,31 +15,31 @@ struct source* source_new(struct core *core, const char *name, const struct samp
     assert(s);
 
     s->name = name ? strdup(name) : NULL;
-    r = idxset_put(core->sources, s, &s->index);
-    assert(s->index != IDXSET_INVALID && r >= 0);
-
     s->core = core;
     s->sample_spec = *spec;
-    s->output_streams = idxset_new(NULL, NULL);
+    s->outputs = idxset_new(NULL, NULL);
 
-    s->link_change_callback = NULL;
+    s->notify = NULL;
     s->userdata = NULL;
 
+    r = idxset_put(core->sources, s, &s->index);
+    assert(s->index != IDXSET_INVALID && r >= 0);
+
     fprintf(stderr, "source: created %u \"%s\"\n", s->index, s->name);
     
     return s;
 }
 
 void source_free(struct source *s) {
-    struct output_stream *o, *j = NULL;
+    struct source_output *o, *j = NULL;
     assert(s);
 
-    while ((o = idxset_first(s->output_streams, NULL))) {
+    while ((o = idxset_first(s->outputs, NULL))) {
         assert(o != j);
-        output_stream_free(o);
+        source_output_kill(o);
         j = o;
     }
-    idxset_free(s->output_streams, NULL, NULL);
+    idxset_free(s->outputs, NULL, NULL);
     
     idxset_remove_by_data(s->core->sources, s, NULL);
 
@@ -49,17 +49,24 @@ void source_free(struct source *s) {
     free(s);
 }
 
+void source_notify(struct source*s) {
+    assert(s);
+
+    if (s->notify)
+        s->notify(s);
+}
+
 static int do_post(void *p, uint32_t index, int *del, void*userdata) {
     struct memchunk *chunk = userdata;
-    struct output_stream *o = p;
-    assert(o && o->memblockq && index && del && chunk);
+    struct source_output *o = p;
+    assert(o && o->push && index && del && chunk);
 
-    memblockq_push(o->memblockq, chunk, 0);
+    o->push(o, chunk);
     return 0;
 }
 
 void source_post(struct source*s, struct memchunk *chunk) {
     assert(s && chunk);
 
-    idxset_foreach(s->output_streams, do_post, chunk);
+    idxset_foreach(s->outputs, do_post, chunk);
 }
index 3beb3f9636a21f294ced557ef09833b01d7be57e..1442b9f01fa8c6958877336fb62f049941c1c626 100644 (file)
@@ -10,14 +10,14 @@ struct source;
 #include "memblock.h"
 
 struct source {
-    char *name;
     uint32_t index;
     
+    char *name;
     struct core *core;
     struct sample_spec sample_spec;
-    struct idxset *output_streams;
+    struct idxset *outputs;
 
-    void (*link_change_callback)(struct source*source, void *userdata);
+    void (*notify)(struct source*source);
     void *userdata;
 };
 
@@ -27,4 +27,6 @@ void source_free(struct source *s);
 /* Pass a new memory block to all output streams */
 void source_post(struct source*s, struct memchunk *b);
 
+void source_notify(struct source *s);
+
 #endif
index c3f68a0ee7c880ebe47fac5327ea022185381622..d4e7a50f266213135d2ed07fc9c08bc34a5917e8 100644 (file)
@@ -2,56 +2,46 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "outputstream.h"
+#include "sourceoutput.h"
 
-struct output_stream* output_stream_new(struct source *s, struct sample_spec *spec, const char *name) {
-    struct output_stream *o;
+struct source_output* source_output_new(struct source *s, struct sample_spec *spec, const char *name) {
+    struct source_output *o;
     int r;
     assert(s && spec);
 
-    o = malloc(sizeof(struct output_stream));
+    o = malloc(sizeof(struct source_output));
     assert(o);
     o->name = name ? strdup(name) : NULL;
     o->source = s;
     o->spec = *spec;
-    o->kill = NULL;
-    o->kill_userdata = NULL;
 
-    o->memblockq = memblockq_new(bytes_per_second(spec)*5, sample_size(spec), (size_t) -1);
-    assert(o->memblockq);
+    o->push = NULL;
+    o->kill = NULL;
+    o->userdata = NULL;
     
     assert(s->core);
-    r = idxset_put(s->core->output_streams, o, &o->index);
+    r = idxset_put(s->core->source_outputs, o, &o->index);
     assert(r == 0 && o->index != IDXSET_INVALID);
-    r = idxset_put(s->output_streams, o, NULL);
+    r = idxset_put(s->outputs, o, NULL);
     assert(r == 0);
     
     return o;    
 }
 
-void output_stream_free(struct output_stream* o) {
+void source_output_free(struct source_output* o) {
     assert(o);
 
-    memblockq_free(o->memblockq);
-
     assert(o->source && o->source->core);
-    idxset_remove_by_data(o->source->core->output_streams, o, NULL);
-    idxset_remove_by_data(o->source->output_streams, o, NULL);
+    idxset_remove_by_data(o->source->core->source_outputs, o, NULL);
+    idxset_remove_by_data(o->source->outputs, o, NULL);
     
     free(o->name);
     free(o);
 }
 
-void output_stream_set_kill_callback(struct output_stream *i, void (*kill)(struct output_stream*i, void *userdata), void *userdata) {
-    assert(i && kill);
-    i->kill = kill;
-    i->kill_userdata = userdata;
-}
-
-
-void output_stream_kill(struct output_stream*i) {
+void source_output_kill(struct source_output*i) {
     assert(i);
 
     if (i->kill)
-        i->kill(i, i->kill_userdata);
+        i->kill(i);
 }
index c6c0a717e4036e62740eafb86b77e514a42e5832..fecfea34749fb347c06ea01ece69cae5ba8b64f9 100644 (file)
@@ -1,27 +1,28 @@
-#ifndef foooutputstreamhfoo
-#define foooutputstreamhfoo
+#ifndef foosourceoutputhfoo
+#define foosourceoutputhfoo
 
 #include <inttypes.h>
+
 #include "source.h"
 #include "sample.h"
 #include "memblockq.h"
 
-struct output_stream {
-    char *name;
+struct source_output {
     uint32_t index;
 
+    char *name;
     struct source *source;
     struct sample_spec spec;
     
-    struct memblockq *memblockq;
-    void (*kill)(struct output_stream* i, void *userdata);
-    void *kill_userdata;
+    void (*push)(struct source_output *o, struct memchunk *chunk);
+    void (*kill)(struct source_output* o);
+
+    void *userdata;
 };
 
-struct output_stream* output_stream_new(struct source *s, struct sample_spec *spec, const char *name);
-void output_stream_free(struct output_stream* o);
+struct source_output* source_output_new(struct source *s, struct sample_spec *spec, const char *name);
+void source_output_free(struct source_output* o);
 
-void output_stream_set_kill_callback(struct output_stream *i, void (*kill)(struct output_stream*i, void *userdata), void *userdata);
-void output_stream_kill(struct output_stream*i);
+void source_output_kill(struct source_output*o);
 
 #endif