summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-09-16 22:07:41 +0000
committerLennart Poettering <lennart@poettering.net>2004-09-16 22:07:41 +0000
commitdaf3938a9e5b50c3e52c0ae889e4d02b548fa78a (patch)
tree8085694bc8fa63ecb9f6e02288ce961ff7cf5d04
parentf9e2058820c2a51994708ad11d1ed8e09b12b8b1 (diff)
add support for subscribing to autoload table changes
fix module-combine so that the sample rate of at least one streams is not changed from the original git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@206 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r--doc/todo5
-rw-r--r--polyp/autoload.c5
-rw-r--r--polyp/autoload.h1
-rw-r--r--polyp/module-combine.c42
-rw-r--r--polyp/polyplib-def.h6
-rw-r--r--polyp/pstream.c14
-rw-r--r--polyp/sample.c6
7 files changed, 51 insertions, 28 deletions
diff --git a/doc/todo b/doc/todo
index 675e8ca3..bcc78f51 100644
--- a/doc/todo
+++ b/doc/todo
@@ -1,9 +1,8 @@
*** $Id$ ***
*** 0.5 ***
-- more complete pactl
-- fix tcp/native
-- paman: add support for killing sink inputs, source outputs, clients
+- more complete pactl/parec
+- fix tcp/native in regard to latencies
- add client config file
- remove autospawn stuff in conf.c
diff --git a/polyp/autoload.c b/polyp/autoload.c
index 344d26e2..12cd1f91 100644
--- a/polyp/autoload.c
+++ b/polyp/autoload.c
@@ -34,9 +34,11 @@
#include "sound-file.h"
#include "log.h"
#include "scache.h"
+#include "subscribe.h"
static void entry_free(struct pa_autoload_entry *e) {
assert(e);
+ pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_REMOVE, PA_INVALID_INDEX);
pa_xfree(e->name);
pa_xfree(e->module);
pa_xfree(e->argument);
@@ -51,6 +53,7 @@ static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name)
return NULL;
e = pa_xmalloc(sizeof(struct pa_autoload_entry));
+ e->core = c;
e->name = pa_xstrdup(name);
e->module = e->argument = NULL;
e->in_action = 0;
@@ -61,6 +64,8 @@ static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name)
pa_hashmap_put(c->autoload_hashmap, e->name, e);
+ pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, PA_INVALID_INDEX);
+
return e;
}
diff --git a/polyp/autoload.h b/polyp/autoload.h
index cdf76239..f80b1f0d 100644
--- a/polyp/autoload.h
+++ b/polyp/autoload.h
@@ -25,6 +25,7 @@
#include "namereg.h"
struct pa_autoload_entry {
+ struct pa_core *core;
char *name;
enum pa_namereg_type type;
int in_action;
diff --git a/polyp/module-combine.c b/polyp/module-combine.c
index 8535e514..177d7d18 100644
--- a/polyp/module-combine.c
+++ b/polyp/module-combine.c
@@ -40,7 +40,7 @@
PA_MODULE_AUTHOR("Lennart Poettering")
PA_MODULE_DESCRIPTION("Combine multiple sinks to one")
PA_MODULE_VERSION(PACKAGE_VERSION)
-PA_MODULE_USAGE("sink_name=<name for the sink> master=<master sink> slave=<slave sinks> adjust_time")
+PA_MODULE_USAGE("sink_name=<name for the sink> master=<master sink> slave=<slave sinks> adjust_time=<seconds>")
#define DEFAULT_SINK_NAME "combined"
#define MEMBLOCKQ_MAXLENGTH (1024*170)
@@ -61,7 +61,7 @@ struct output {
struct pa_sink_input *sink_input;
size_t counter;
struct pa_memblockq *memblockq;
- pa_usec_t sink_latency;
+ pa_usec_t total_latency;
PA_LLIST_FIELDS(struct output);
};
@@ -89,38 +89,44 @@ static void update_usage(struct userdata *u) {
static void adjust_rates(struct userdata *u) {
struct output *o;
- pa_usec_t max = 0;
+ pa_usec_t max_sink_latency = 0, min_total_latency = (pa_usec_t) -1, target_latency;
uint32_t base_rate;
assert(u && u->sink);
for (o = u->outputs; o; o = o->next) {
- o->sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0;
+ uint32_t sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0;
+
+ o->total_latency = sink_latency + pa_sink_input_get_latency(o->sink_input);
+
+ if (sink_latency > max_sink_latency)
+ max_sink_latency = sink_latency;
- if (o->sink_latency > max)
- max = o->sink_latency;
+ if (o->total_latency < min_total_latency)
+ min_total_latency = o->total_latency;
}
- pa_log(__FILE__": [%s] maximum latency is %0.0f usec.\n", u->sink->name, (float) max);
+ assert(max_sink_latency > 0 && min_total_latency != (pa_usec_t) -1);
+
+ target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency;
+
+ pa_log(__FILE__": [%s] target latency is %0.0f usec.\n", u->sink->name, (float) target_latency);
base_rate = u->sink->sample_spec.rate;
for (o = u->outputs; o; o = o->next) {
- pa_usec_t l;
uint32_t r = base_rate;
- l = o->sink_latency + pa_sink_input_get_latency(o->sink_input);
-
- if (l < max)
- r -= (uint32_t) (((((double) max-l))/u->adjust_time)*r/ 1000000);
- else if (l > max)
- r += (uint32_t) (((((double) l-max))/u->adjust_time)*r/ 1000000);
+ if (o->total_latency < target_latency)
+ r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/ 1000000);
+ else if (o->total_latency > target_latency)
+ r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/ 1000000);
if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1))
pa_log(__FILE__": [%s] sample rates too different, not adjusting (%u vs. %u).\n", o->sink_input->name, base_rate, r);
- else
- pa_log(__FILE__": [%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.\n", o->sink_input->name, r, (double) r / base_rate, (float) l);
-
- pa_sink_input_set_rate(o->sink_input, r);
+ else {
+ pa_log(__FILE__": [%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.\n", o->sink_input->name, r, (double) r / base_rate, (float) o->total_latency);
+ pa_sink_input_set_rate(o->sink_input, r);
+ }
}
}
diff --git a/polyp/polyplib-def.h b/polyp/polyplib-def.h
index 29f5eb43..591d237d 100644
--- a/polyp/polyplib-def.h
+++ b/polyp/polyplib-def.h
@@ -108,7 +108,8 @@ enum pa_subscription_mask {
PA_SUBSCRIPTION_MASK_MODULE = 16, /**< Module events */
PA_SUBSCRIPTION_MASK_CLIENT = 32, /**< Client events */
PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64, /**< Sample cache events */
- PA_SUBSCRIPTION_MASK_SERVER = 128 /**< Other global server changes. \since 0.4 */
+ PA_SUBSCRIPTION_MASK_SERVER = 128, /**< Other global server changes. \since 0.4 */
+ PA_SUBSCRIPTION_MASK_AUTOLOAD = 256 /**< Autoload table events. \since 0.5 */
};
/** Subscription event types, as used by pa_context_subscribe() */
@@ -121,7 +122,8 @@ enum pa_subscription_event_type {
PA_SUBSCRIPTION_EVENT_CLIENT = 5, /**< Event type: Client */
PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 6, /**< Event type: Sample cache item */
PA_SUBSCRIPTION_EVENT_SERVER = 7, /**< Event type: Global server change, only occuring with PA_SUBSCRIPTION_EVENT_CHANGE. \since 0.4 */
- PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 7, /**< A mask to extract the event type from an event value */
+ PA_SUBSCRIPTION_EVENT_AUTOLOAD = 8, /**< Event type: Autoload table changes. \since 0.5 */
+ PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 15, /**< A mask to extract the event type from an event value */
PA_SUBSCRIPTION_EVENT_NEW = 0, /**< A new object was created */
PA_SUBSCRIPTION_EVENT_CHANGE = 16, /**< A property of the object was modified */
diff --git a/polyp/pstream.c b/polyp/pstream.c
index 4ee296ce..b0de9e8c 100644
--- a/polyp/pstream.c
+++ b/polyp/pstream.c
@@ -101,6 +101,10 @@ static void do_read(struct pa_pstream *p);
static void do_something(struct pa_pstream *p) {
assert(p);
+
+ if (p->dead)
+ return;
+
p->mainloop->defer_enable(p->defer_event, 0);
pa_pstream_ref(p);
@@ -213,8 +217,11 @@ static void pstream_free(struct pa_pstream *p) {
void pa_pstream_send_packet(struct pa_pstream*p, struct pa_packet *packet) {
struct item_info *i;
- assert(p && packet);
+ assert(p && packet && p->ref >= 1);
+ if (p->dead)
+ return;
+
/* pa_log(__FILE__": push-packet %p\n", packet); */
i = pa_xmalloc(sizeof(struct item_info));
@@ -227,8 +234,11 @@ void pa_pstream_send_packet(struct pa_pstream*p, struct pa_packet *packet) {
void pa_pstream_send_memblock(struct pa_pstream*p, uint32_t channel, uint32_t delta, const struct pa_memchunk *chunk) {
struct item_info *i;
- assert(p && channel != (uint32_t) -1 && chunk);
+ assert(p && channel != (uint32_t) -1 && chunk && p->ref >= 1);
+ if (p->dead)
+ return;
+
/* pa_log(__FILE__": push-memblock %p\n", chunk); */
i = pa_xmalloc(sizeof(struct item_info));
diff --git a/polyp/sample.c b/polyp/sample.c
index dfe98e3f..397e57a2 100644
--- a/polyp/sample.c
+++ b/polyp/sample.c
@@ -121,11 +121,11 @@ double pa_volume_to_dB(pa_volume_t v) {
}
void pa_bytes_snprint(char *s, size_t l, off_t v) {
- if (v >= 1024*1024*1024)
+ if (v >= (off_t) 1024*1024*1024)
snprintf(s, l, "%0.1f GB", (double) v/1024/1024/1024);
- else if (v >= 1024*1024)
+ else if (v >= (off_t) 1024*1024)
snprintf(s, l, "%0.1f MB", (double) v/1024/1024);
- else if (v >= 1024)
+ else if (v >= (off_t) 1024)
snprintf(s, l, "%0.1f KB", (double) v/1024);
else
snprintf(s, l, "%u B", (unsigned) v);