]> code.delx.au - pulseaudio/commitdiff
add name registrar
authorLennart Poettering <lennart@poettering.net>
Sun, 27 Jun 2004 22:42:17 +0000 (22:42 +0000)
committerLennart Poettering <lennart@poettering.net>
Sun, 27 Jun 2004 22:42:17 +0000 (22:42 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@39 fefdeb5f-60dc-0310-8127-8f9354f1896f

17 files changed:
src/Makefile.am
src/core.c
src/core.h
src/hashset.c [new file with mode: 0644]
src/hashset.h [new file with mode: 0644]
src/idxset.c
src/idxset.h
src/module-oss-mmap.c
src/module-oss.c
src/module-pipe-sink.c
src/namereg.c [new file with mode: 0644]
src/namereg.h [new file with mode: 0644]
src/sink.c
src/sink.h
src/source.c
src/source.h
src/todo

index 75da02c17d5497ef2c1ec87af25997b81390ec05..a67f395e854c649cc19473f56424c2fbbfdedf75 100644 (file)
@@ -49,7 +49,10 @@ polypaudio_SOURCES = idxset.c idxset.h \
                module.c module.h \
                mainloop-signal.c mainloop-signal.h \
                mainloop-api.c mainloop-api.h \
-               util.c util.h
+               util.c util.h \
+               hashset.c hashset.h \
+               namereg.c namereg.h
+
 polypaudio_CFLAGS = $(AM_CFLAGS)
 
 polypaudio_INCLUDES = $(INCLTDL)
index d9df38e1e9c05714b1c7f99ef665363e538f14e3..ec38da910588148c74232d5284c1119962d7b95e 100644 (file)
@@ -6,6 +6,7 @@
 #include "module.h"
 #include "sink.h"
 #include "source.h"
+#include "namereg.h"
 
 struct core* core_new(struct pa_mainloop_api *m) {
     struct core* c;
@@ -22,6 +23,7 @@ struct core* core_new(struct pa_mainloop_api *m) {
     c->default_source_index = c->default_sink_index = IDXSET_INVALID;
 
     c->modules = NULL;
+    c->namereg = NULL;
     
     return c;
 };
@@ -47,6 +49,8 @@ void core_free(struct core *c) {
     assert(idxset_isempty(c->sink_inputs));
     idxset_free(c->sink_inputs, NULL, NULL);
 
+    namereg_free(c);
+    
     free(c);    
 };
 
index 8c4c6233d3eba46edf829367676bdff3319941d3..289bec85db8c8585d22e9129fc33955255ea6f6f 100644 (file)
@@ -2,6 +2,7 @@
 #define foocorehfoo
 
 #include "idxset.h"
+#include "hashset.h"
 #include "mainloop-api.h"
 
 struct core {
@@ -9,6 +10,8 @@ struct core {
 
     struct idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules;
 
+    struct hashset *namereg;
+    
     uint32_t default_source_index, default_sink_index;
 };
 
diff --git a/src/hashset.c b/src/hashset.c
new file mode 100644 (file)
index 0000000..298650d
--- /dev/null
@@ -0,0 +1,145 @@
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "hashset.h"
+#include "idxset.h"
+
+struct hashset_entry {
+    struct hashset_entry *next, *previous, *bucket_next, *bucket_previous;
+    unsigned hash;
+    const void *key;
+    void *value;
+};
+
+struct hashset {
+    unsigned size;
+    struct hashset_entry **data;
+    struct hashset_entry *first_entry;
+    
+    unsigned n_entries;
+    unsigned (*hash_func) (const void *p);
+    int (*compare_func) (const void*a, const void*b);
+};
+
+struct hashset *hashset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)) {
+    struct hashset *h;
+    h = malloc(sizeof(struct hashset));
+    assert(h);
+    h->data = malloc(sizeof(struct hashset_entry*)*(h->size = 1023));
+    assert(h->data);
+    memset(h->data, 0, sizeof(struct hashset_entry*)*(h->size = 1023));
+    h->first_entry = NULL;
+    h->n_entries = 0;
+    h->hash_func = hash_func ? hash_func : idxset_trivial_hash_func;
+    h->compare_func = compare_func ? compare_func : idxset_trivial_compare_func;
+    return h;
+}
+
+static void remove(struct hashset *h, struct hashset_entry *e) {
+    assert(e);
+
+    if (e->next)
+        e->next->previous = e->previous;
+    if (e->previous)
+        e->previous->next = e->next;
+    else
+        h->first_entry = e->next;
+
+    if (e->bucket_next)
+        e->bucket_next->bucket_previous = e->bucket_previous;
+    if (e->bucket_previous)
+        e->bucket_previous->bucket_next = e->bucket_next;
+    else
+        h->data[e->hash] = e->bucket_next;
+
+    free(e);
+    h->n_entries--;
+}
+
+void hashset_free(struct hashset*h, void (*free_func)(void *p, void *userdata), void *userdata) {
+    assert(h);
+
+    while (h->first_entry) {
+        if (free_func)
+            free_func(h->first_entry->value, userdata);
+        remove(h, h->first_entry);
+    }
+    
+    free(h->data);
+    free(h);
+}
+
+static struct hashset_entry *get(struct hashset *h, unsigned hash, const void *key) {
+    struct hashset_entry *e;
+
+    for (e = h->data[hash]; e; e = e->bucket_next)
+        if (h->compare_func(e->key, key) == 0)
+            return e;
+
+    return NULL;
+}
+
+int hashset_put(struct hashset *h, const void *key, void *value) {
+    struct hashset_entry *e;
+    unsigned hash;
+    assert(h && key);
+
+    hash = h->hash_func(key) % h->size;
+
+    if ((e = get(h, hash, key)))
+        return -1;
+    
+    e = malloc(sizeof(struct hashset_entry));
+    assert(e);
+    
+    e->hash = hash;
+    e->key = key;
+    e->value = value;
+    
+    e->previous = NULL;
+    e->next = h->first_entry;
+    if (h->first_entry)
+        h->first_entry->previous = e;
+    h->first_entry = e;
+    
+    e->bucket_previous = NULL;
+    e->bucket_next = h->data[hash];
+    if (h->data[hash])
+        h->data[hash]->bucket_previous = e;
+    h->data[hash] = e;
+    
+    h->n_entries ++;
+    return 0;
+}
+
+void* hashset_get(struct hashset *h, const void *key) {
+    unsigned hash;
+    struct hashset_entry *e;
+    assert(h && key);
+
+    hash = h->hash_func(key) % h->size;
+
+    if (!(e = get(h, hash, key)))
+        return NULL;
+
+    return e->value;
+}
+
+int hashset_remove(struct hashset *h, const void *key) {
+    struct hashset_entry *e;
+    unsigned hash;
+    assert(h && key);
+
+    hash = h->hash_func(key) % h->size;
+
+    if (!(e = get(h, hash, key)))
+        return 1;
+
+    remove(h, e);
+    return 0;
+}
+
+unsigned hashset_ncontents(struct hashset *h) {
+    return h->n_entries;
+}
diff --git a/src/hashset.h b/src/hashset.h
new file mode 100644 (file)
index 0000000..7e035c0
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef foohashsethfoo
+#define foohashsethfoo
+
+struct hashset;
+
+struct hashset *hashset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b));
+void hashset_free(struct hashset*, void (*free_func)(void *p, void *userdata), void *userdata);
+
+int hashset_put(struct hashset *h, const void *key, void *value);
+void* hashset_get(struct hashset *h, const void *key);
+
+int hashset_remove(struct hashset *h, const void *key);
+
+unsigned hashset_ncontents(struct hashset *h);
+
+#endif
index ea609f601281639b06b35c7a477d4a06bcbb99d3..090bfc7260baa766bcadad11dcc7139b1fb2165b 100644 (file)
@@ -15,29 +15,43 @@ struct idxset_entry {
 };
 
 struct idxset {
-    unsigned (*hash_func) (void *p);
-    int (*compare_func)(void *a, void *b);
+    unsigned (*hash_func) (const void *p);
+    int (*compare_func)(const void *a, const void *b);
     
     unsigned hash_table_size, n_entries;
     struct idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail;
     uint32_t index, start_index, array_size;
 };
 
-static unsigned trivial_hash_func(void *p) {
+unsigned idxset_string_hash_func(const void *p) {
+    unsigned hash = 0;
+    const char *c;
+    
+    for (c = p; *c; c++)
+        hash = 31 * hash + *c;
+
+    return hash;
+}
+
+int idxset_string_compare_func(const void *a, const void *b) {
+    return strcmp(a, b);
+}
+
+unsigned idxset_trivial_hash_func(const void *p) {
     return (unsigned) p;
 }
 
-static int trivial_compare_func(void *a, void *b) {
+int idxset_trivial_compare_func(const void *a, const void *b) {
     return a != b;
 }
 
-struct idxset* idxset_new(unsigned (*hash_func) (void *p), int (*compare_func) (void*a, void*b)) {
+struct idxset* idxset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)) {
     struct idxset *s;
 
     s = malloc(sizeof(struct idxset));
     assert(s);
-    s->hash_func = hash_func ? hash_func : trivial_hash_func;
-    s->compare_func = compare_func ? compare_func : trivial_compare_func;
+    s->hash_func = hash_func ? hash_func : idxset_trivial_hash_func;
+    s->compare_func = compare_func ? compare_func : idxset_trivial_compare_func;
     s->hash_table_size = 1023;
     s->hash_table = malloc(sizeof(struct idxset_entry*)*s->hash_table_size);
     assert(s->hash_table);
index 90b9d247818b805f4bf300e3e7077c7db5cd233e..615039776a26e067e5f815cd03d9e3b7c654f72a 100644 (file)
@@ -5,9 +5,15 @@
 
 #define IDXSET_INVALID ((uint32_t) -1)
 
+unsigned idxset_trivial_hash_func(const void *p);
+int idxset_trivial_compare_func(const void *a, const void *b);
+
+unsigned idxset_string_hash_func(const void *p);
+int idxset_string_compare_func(const void *a, const void *b);
+
 struct idxset;
 
-struct idxset* idxset_new(unsigned (*hash_func) (void *p), int (*compare_func) (void*a, void*b));
+struct idxset* idxset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b));
 void idxset_free(struct idxset *s, void (*free_func) (void *p, void *userdata), void *userdata);
 
 int idxset_put(struct idxset*s, void *p, uint32_t *index);
index f08dd7d3c950c10c3edc18fd27c7df273ba975d6..3997c4907f01b5e9685eee0cf5d723d25315610f 100644 (file)
@@ -262,7 +262,7 @@ int module_init(struct core *c, struct module*m) {
             }
         } else {
         
-            u->source = source_new(c, "dsp", &u->sample_spec);
+            u->source = source_new(c, "dsp", 0, &u->sample_spec);
             assert(u->source);
             u->source->userdata = u;
             
@@ -293,7 +293,7 @@ int module_init(struct core *c, struct module*m) {
         } else {
             silence_memory(u->out_mmap, u->out_mmap_length, &u->sample_spec);
             
-            u->sink = sink_new(c, "dsp", &u->sample_spec);
+            u->sink = sink_new(c, "dsp", 0, &u->sample_spec);
             assert(u->sink);
             u->sink->get_latency = sink_get_latency_cb;
             u->sink->userdata = u;
index b5d1427a44081a1f6a3fdec683e261d9ded6ea42..75082a7fd8da613fa14228b37eb086e86e7af2e0 100644 (file)
@@ -180,7 +180,7 @@ int module_init(struct core *c, struct module*m) {
     u->core = c;
 
     if (mode != O_RDONLY) {
-        u->sink = sink_new(c, "dsp", &ss);
+        u->sink = sink_new(c, "dsp", 0, &ss);
         assert(u->sink);
         u->sink->get_latency = sink_get_latency_cb;
         u->sink->userdata = u;
@@ -188,7 +188,7 @@ int module_init(struct core *c, struct module*m) {
         u->sink = NULL;
 
     if (mode != O_WRONLY) {
-        u->source = source_new(c, "dsp", &ss);
+        u->source = source_new(c, "dsp", 0, &ss);
         assert(u->source);
         u->source->userdata = u;
     } else
index 9dcf5d2316ebe716ddcf7ced8de072df1252848a..6cc4de8825eccdfb302d800bcfeeabe1df5fb484 100644 (file)
@@ -109,7 +109,7 @@ int module_init(struct core *c, struct module*m) {
     u->filename = strdup(p);
     assert(u->filename);
     u->core = c;
-    u->sink = sink_new(c, "fifo", &ss);
+    u->sink = sink_new(c, "fifo", 0, &ss);
     assert(u->sink);
     u->sink->notify = notify_cb;
     u->sink->userdata = u;
diff --git a/src/namereg.c b/src/namereg.c
new file mode 100644 (file)
index 0000000..b286171
--- /dev/null
@@ -0,0 +1,97 @@
+#include <string.h>
+#include <assert.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+
+#include "namereg.h"
+
+struct namereg_entry {
+    enum namereg_type type;
+    char *name;
+    void *data;
+};
+
+void namereg_free(struct core *c) {
+    assert(c);
+    if (!c->namereg)
+        return;
+    assert(hashset_ncontents(c->namereg) == 0);
+    hashset_free(c->namereg, NULL, NULL);
+}
+
+const char *namereg_register(struct core *c, const char *name, enum namereg_type type, void *data, int fail) {
+    struct namereg_entry *e;
+    char *n = NULL;
+    int r;
+    
+    assert(c && name && data);
+
+    if (!c->namereg) {
+        c->namereg = hashset_new(idxset_string_hash_func, idxset_string_compare_func);
+        assert(c->namereg);
+    }
+
+    if ((e = hashset_get(c->namereg, name)) && fail)
+        return NULL;
+
+    if (!e)
+        n = strdup(name);
+    else {
+        unsigned i;
+        size_t l = strlen(name);
+        n = malloc(l+3);
+        assert(n);
+        
+        for (i = 1; i <= 99; i++) {
+            snprintf(n, l+2, "%s%u", name, i);
+
+            if (!(e = hashset_get(c->namereg, n)))
+                break;
+        }
+
+        if (e) {
+            free(n);
+            return NULL;
+        }
+    }
+    
+    assert(n);
+    e = malloc(sizeof(struct namereg_entry));
+    assert(e);
+    e->type = type;
+    e->name = n;
+    e->data = data;
+
+    r = hashset_put(c->namereg, e->name, e);
+    assert (r >= 0);
+
+    return e->name;
+    
+}
+
+void namereg_unregister(struct core *c, const char *name) {
+    struct namereg_entry *e;
+    int r;
+    assert(c && name);
+
+    e = hashset_get(c->namereg, name);
+    assert(e);
+
+    r = hashset_remove(c->namereg, name);
+    assert(r >= 0);
+
+    free(e->name);
+    free(e);
+}
+
+void* namereg_get(struct core *c, const char *name, enum namereg_type type) {
+    struct namereg_entry *e;
+    assert(c && name);
+
+    if (!(e = hashset_get(c->namereg, name)))
+        if (e->type == e->type)
+            return e->data;
+
+    return NULL;
+}
diff --git a/src/namereg.h b/src/namereg.h
new file mode 100644 (file)
index 0000000..5632143
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef foonamereghfoo
+#define foonamereghfoo
+
+#include "core.h"
+
+enum namereg_type {
+    NAMEREG_SINK,
+    NAMEREG_SOURCE
+};
+
+void namereg_free(struct core *c);
+
+const char *namereg_register(struct core *c, const char *name, enum namereg_type type, void *data, int fail);
+void namereg_unregister(struct core *c, const char *name);
+void* namereg_get(struct core *c, const char *name, enum namereg_type type);
+
+#endif
index a334424c201c8797a01db0838b95440606bc18f6..5ab1a7a7887d155bc36aed544222b04c4f9aacc8 100644 (file)
@@ -7,10 +7,11 @@
 #include "sinkinput.h"
 #include "strbuf.h"
 #include "sample-util.h"
+#include "namereg.h"
 
 #define MAX_MIX_CHANNELS 32
 
-struct sink* sink_new(struct core *core, const char *name, const struct pa_sample_spec *spec) {
+struct sink* sink_new(struct core *core, const char *name, int fail, const struct pa_sample_spec *spec) {
     struct sink *s;
     char *n = NULL;
     int r;
@@ -18,8 +19,13 @@ struct sink* sink_new(struct core *core, const char *name, const struct pa_sampl
 
     s = malloc(sizeof(struct sink));
     assert(s);
+
+    if (!(name = namereg_register(core, name, NAMEREG_SINK, s, fail))) {
+        free(s);
+        return NULL;
+    }
     
-    s->name = name ? strdup(name) : NULL;
+    s->name = strdup(name);
     s->core = core;
     s->sample_spec = *spec;
     s->inputs = idxset_new(NULL, NULL);
@@ -29,7 +35,8 @@ struct sink* sink_new(struct core *core, const char *name, const struct pa_sampl
         sprintf(n, "%s_monitor", name);
     }
     
-    s->monitor_source = source_new(core, n, spec);
+    s->monitor_source = source_new(core, n, 0, spec);
+    assert(s->monitor_source);
     free(n);
     
     s->volume = 0xFF;
@@ -50,6 +57,8 @@ void sink_free(struct sink *s) {
     struct sink_input *i, *j = NULL;
     assert(s);
 
+    namereg_unregister(s->core, s->name);
+    
     while ((i = idxset_first(s->inputs, NULL))) {
         assert(i != j);
         sink_input_kill(i);
index d9f80059d229ca60227bd8843da262d3d6ddfe90..a5b1ff68ee732a8fd6facd8ad396ab8c3a1ef691 100644 (file)
@@ -27,7 +27,7 @@ struct sink {
     void *userdata;
 };
 
-struct sink* sink_new(struct core *core, const char *name, const struct pa_sample_spec *spec);
+struct sink* sink_new(struct core *core, const char *name, int fail, const struct pa_sample_spec *spec);
 void sink_free(struct sink* s);
 
 int sink_render(struct sink*s, size_t length, struct memchunk *result);
index 21ac24f3533a44df0f674f72170409b16b6730e2..deacfb3d69c95b9d17b7d087ef986558b97e260f 100644 (file)
@@ -6,8 +6,9 @@
 #include "source.h"
 #include "sourceoutput.h"
 #include "strbuf.h"
+#include "namereg.h"
 
-struct source* source_new(struct core *core, const char *name, const struct pa_sample_spec *spec) {
+struct source* source_new(struct core *core, const char *name, int fail, const struct pa_sample_spec *spec) {
     struct source *s;
     int r;
     assert(core && spec);
@@ -15,7 +16,12 @@ struct source* source_new(struct core *core, const char *name, const struct pa_s
     s = malloc(sizeof(struct source));
     assert(s);
 
-    s->name = name ? strdup(name) : NULL;
+    if (!(name = namereg_register(core, name, NAMEREG_SOURCE, s, fail))) {
+        free(s);
+        return NULL;
+    }
+
+    s->name = strdup(name);
     s->core = core;
     s->sample_spec = *spec;
     s->outputs = idxset_new(NULL, NULL);
@@ -35,6 +41,8 @@ void source_free(struct source *s) {
     struct source_output *o, *j = NULL;
     assert(s);
 
+    namereg_unregister(s->core, s->name);
+    
     while ((o = idxset_first(s->outputs, NULL))) {
         assert(o != j);
         source_output_kill(o);
index 04f3984f7379816c8acdf72a0e553f8ec20bad76..afae5a68ba90a2f53fa45ecf0d8a3c133f52bf65 100644 (file)
@@ -21,7 +21,7 @@ struct source {
     void *userdata;
 };
 
-struct source* source_new(struct core *core, const char *name, const struct pa_sample_spec *spec);
+struct source* source_new(struct core *core, const char *name, int fail, const struct pa_sample_spec *spec);
 void source_free(struct source *s);
 
 /* Pass a new memory block to all output streams */
index 47344ab42472953d0996a6e838ea13008508ac69..78768be0fb518f2f150749413baf1462ee5b1090 100644 (file)
--- a/src/todo
+++ b/src/todo
@@ -1,13 +1,19 @@
-- sync() function in native library
-- name registrar
-- native protocol/library
-- simple control protocol: kill client/input/output; set_volume
+- native library/protocol:
+       recording
+       sync() function
+       more functions
+- simple library
+- simple control protocol: 
+       kill client/input/output
+       set_volume
 - resampling
+- volume adjust on single sink input
+- fp volume scaling (both < and > 1)
 - esound protocol
 - config parser/cmdline
 - record testing
+
 -- 0.1
-- optimierung von rebuild_pollfds()
 - future cancellation
 - client-ui
 - clip cache