mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-31 22:25:33 -04:00
add name registrar
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@39 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
010378643e
commit
a74cd2a1bd
17 changed files with 354 additions and 26 deletions
|
|
@ -49,7 +49,10 @@ polypaudio_SOURCES = idxset.c idxset.h \
|
||||||
module.c module.h \
|
module.c module.h \
|
||||||
mainloop-signal.c mainloop-signal.h \
|
mainloop-signal.c mainloop-signal.h \
|
||||||
mainloop-api.c mainloop-api.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_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
polypaudio_INCLUDES = $(INCLTDL)
|
polypaudio_INCLUDES = $(INCLTDL)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "sink.h"
|
#include "sink.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
|
#include "namereg.h"
|
||||||
|
|
||||||
struct core* core_new(struct pa_mainloop_api *m) {
|
struct core* core_new(struct pa_mainloop_api *m) {
|
||||||
struct core* c;
|
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->default_source_index = c->default_sink_index = IDXSET_INVALID;
|
||||||
|
|
||||||
c->modules = NULL;
|
c->modules = NULL;
|
||||||
|
c->namereg = NULL;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
};
|
};
|
||||||
|
|
@ -47,6 +49,8 @@ void core_free(struct core *c) {
|
||||||
assert(idxset_isempty(c->sink_inputs));
|
assert(idxset_isempty(c->sink_inputs));
|
||||||
idxset_free(c->sink_inputs, NULL, NULL);
|
idxset_free(c->sink_inputs, NULL, NULL);
|
||||||
|
|
||||||
|
namereg_free(c);
|
||||||
|
|
||||||
free(c);
|
free(c);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define foocorehfoo
|
#define foocorehfoo
|
||||||
|
|
||||||
#include "idxset.h"
|
#include "idxset.h"
|
||||||
|
#include "hashset.h"
|
||||||
#include "mainloop-api.h"
|
#include "mainloop-api.h"
|
||||||
|
|
||||||
struct core {
|
struct core {
|
||||||
|
|
@ -9,6 +10,8 @@ struct core {
|
||||||
|
|
||||||
struct idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules;
|
struct idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules;
|
||||||
|
|
||||||
|
struct hashset *namereg;
|
||||||
|
|
||||||
uint32_t default_source_index, default_sink_index;
|
uint32_t default_source_index, default_sink_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
145
src/hashset.c
Normal file
145
src/hashset.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
16
src/hashset.h
Normal file
16
src/hashset.h
Normal file
|
|
@ -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
|
||||||
28
src/idxset.c
28
src/idxset.c
|
|
@ -15,29 +15,43 @@ struct idxset_entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct idxset {
|
struct idxset {
|
||||||
unsigned (*hash_func) (void *p);
|
unsigned (*hash_func) (const void *p);
|
||||||
int (*compare_func)(void *a, void *b);
|
int (*compare_func)(const void *a, const void *b);
|
||||||
|
|
||||||
unsigned hash_table_size, n_entries;
|
unsigned hash_table_size, n_entries;
|
||||||
struct idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail;
|
struct idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail;
|
||||||
uint32_t index, start_index, array_size;
|
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;
|
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;
|
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;
|
struct idxset *s;
|
||||||
|
|
||||||
s = malloc(sizeof(struct idxset));
|
s = malloc(sizeof(struct idxset));
|
||||||
assert(s);
|
assert(s);
|
||||||
s->hash_func = hash_func ? hash_func : trivial_hash_func;
|
s->hash_func = hash_func ? hash_func : idxset_trivial_hash_func;
|
||||||
s->compare_func = compare_func ? compare_func : trivial_compare_func;
|
s->compare_func = compare_func ? compare_func : idxset_trivial_compare_func;
|
||||||
s->hash_table_size = 1023;
|
s->hash_table_size = 1023;
|
||||||
s->hash_table = malloc(sizeof(struct idxset_entry*)*s->hash_table_size);
|
s->hash_table = malloc(sizeof(struct idxset_entry*)*s->hash_table_size);
|
||||||
assert(s->hash_table);
|
assert(s->hash_table);
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,15 @@
|
||||||
|
|
||||||
#define IDXSET_INVALID ((uint32_t) -1)
|
#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;
|
||||||
|
|
||||||
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);
|
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);
|
int idxset_put(struct idxset*s, void *p, uint32_t *index);
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ int module_init(struct core *c, struct module*m) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
u->source = source_new(c, "dsp", &u->sample_spec);
|
u->source = source_new(c, "dsp", 0, &u->sample_spec);
|
||||||
assert(u->source);
|
assert(u->source);
|
||||||
u->source->userdata = u;
|
u->source->userdata = u;
|
||||||
|
|
||||||
|
|
@ -293,7 +293,7 @@ int module_init(struct core *c, struct module*m) {
|
||||||
} else {
|
} else {
|
||||||
silence_memory(u->out_mmap, u->out_mmap_length, &u->sample_spec);
|
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);
|
assert(u->sink);
|
||||||
u->sink->get_latency = sink_get_latency_cb;
|
u->sink->get_latency = sink_get_latency_cb;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ int module_init(struct core *c, struct module*m) {
|
||||||
u->core = c;
|
u->core = c;
|
||||||
|
|
||||||
if (mode != O_RDONLY) {
|
if (mode != O_RDONLY) {
|
||||||
u->sink = sink_new(c, "dsp", &ss);
|
u->sink = sink_new(c, "dsp", 0, &ss);
|
||||||
assert(u->sink);
|
assert(u->sink);
|
||||||
u->sink->get_latency = sink_get_latency_cb;
|
u->sink->get_latency = sink_get_latency_cb;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
|
|
@ -188,7 +188,7 @@ int module_init(struct core *c, struct module*m) {
|
||||||
u->sink = NULL;
|
u->sink = NULL;
|
||||||
|
|
||||||
if (mode != O_WRONLY) {
|
if (mode != O_WRONLY) {
|
||||||
u->source = source_new(c, "dsp", &ss);
|
u->source = source_new(c, "dsp", 0, &ss);
|
||||||
assert(u->source);
|
assert(u->source);
|
||||||
u->source->userdata = u;
|
u->source->userdata = u;
|
||||||
} else
|
} else
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ int module_init(struct core *c, struct module*m) {
|
||||||
u->filename = strdup(p);
|
u->filename = strdup(p);
|
||||||
assert(u->filename);
|
assert(u->filename);
|
||||||
u->core = c;
|
u->core = c;
|
||||||
u->sink = sink_new(c, "fifo", &ss);
|
u->sink = sink_new(c, "fifo", 0, &ss);
|
||||||
assert(u->sink);
|
assert(u->sink);
|
||||||
u->sink->notify = notify_cb;
|
u->sink->notify = notify_cb;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
|
|
|
||||||
97
src/namereg.c
Normal file
97
src/namereg.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
17
src/namereg.h
Normal file
17
src/namereg.h
Normal file
|
|
@ -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
|
||||||
15
src/sink.c
15
src/sink.c
|
|
@ -7,10 +7,11 @@
|
||||||
#include "sinkinput.h"
|
#include "sinkinput.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "sample-util.h"
|
#include "sample-util.h"
|
||||||
|
#include "namereg.h"
|
||||||
|
|
||||||
#define MAX_MIX_CHANNELS 32
|
#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;
|
struct sink *s;
|
||||||
char *n = NULL;
|
char *n = NULL;
|
||||||
int r;
|
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));
|
s = malloc(sizeof(struct sink));
|
||||||
assert(s);
|
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->core = core;
|
||||||
s->sample_spec = *spec;
|
s->sample_spec = *spec;
|
||||||
s->inputs = idxset_new(NULL, NULL);
|
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);
|
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);
|
free(n);
|
||||||
|
|
||||||
s->volume = 0xFF;
|
s->volume = 0xFF;
|
||||||
|
|
@ -50,6 +57,8 @@ void sink_free(struct sink *s) {
|
||||||
struct sink_input *i, *j = NULL;
|
struct sink_input *i, *j = NULL;
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
namereg_unregister(s->core, s->name);
|
||||||
|
|
||||||
while ((i = idxset_first(s->inputs, NULL))) {
|
while ((i = idxset_first(s->inputs, NULL))) {
|
||||||
assert(i != j);
|
assert(i != j);
|
||||||
sink_input_kill(i);
|
sink_input_kill(i);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ struct sink {
|
||||||
void *userdata;
|
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);
|
void sink_free(struct sink* s);
|
||||||
|
|
||||||
int sink_render(struct sink*s, size_t length, struct memchunk *result);
|
int sink_render(struct sink*s, size_t length, struct memchunk *result);
|
||||||
|
|
|
||||||
12
src/source.c
12
src/source.c
|
|
@ -6,8 +6,9 @@
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "sourceoutput.h"
|
#include "sourceoutput.h"
|
||||||
#include "strbuf.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;
|
struct source *s;
|
||||||
int r;
|
int r;
|
||||||
assert(core && spec);
|
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));
|
s = malloc(sizeof(struct source));
|
||||||
assert(s);
|
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->core = core;
|
||||||
s->sample_spec = *spec;
|
s->sample_spec = *spec;
|
||||||
s->outputs = idxset_new(NULL, NULL);
|
s->outputs = idxset_new(NULL, NULL);
|
||||||
|
|
@ -35,6 +41,8 @@ void source_free(struct source *s) {
|
||||||
struct source_output *o, *j = NULL;
|
struct source_output *o, *j = NULL;
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
namereg_unregister(s->core, s->name);
|
||||||
|
|
||||||
while ((o = idxset_first(s->outputs, NULL))) {
|
while ((o = idxset_first(s->outputs, NULL))) {
|
||||||
assert(o != j);
|
assert(o != j);
|
||||||
source_output_kill(o);
|
source_output_kill(o);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ struct source {
|
||||||
void *userdata;
|
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);
|
void source_free(struct source *s);
|
||||||
|
|
||||||
/* Pass a new memory block to all output streams */
|
/* Pass a new memory block to all output streams */
|
||||||
|
|
|
||||||
16
src/todo
16
src/todo
|
|
@ -1,13 +1,19 @@
|
||||||
- sync() function in native library
|
- native library/protocol:
|
||||||
- name registrar
|
recording
|
||||||
- native protocol/library
|
sync() function
|
||||||
- simple control protocol: kill client/input/output; set_volume
|
more functions
|
||||||
|
- simple library
|
||||||
|
- simple control protocol:
|
||||||
|
kill client/input/output
|
||||||
|
set_volume
|
||||||
- resampling
|
- resampling
|
||||||
|
- volume adjust on single sink input
|
||||||
|
- fp volume scaling (both < and > 1)
|
||||||
- esound protocol
|
- esound protocol
|
||||||
- config parser/cmdline
|
- config parser/cmdline
|
||||||
- record testing
|
- record testing
|
||||||
|
|
||||||
-- 0.1
|
-- 0.1
|
||||||
- optimierung von rebuild_pollfds()
|
|
||||||
- future cancellation
|
- future cancellation
|
||||||
- client-ui
|
- client-ui
|
||||||
- clip cache
|
- clip cache
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue