From 8eaa40b6f4cae749610770c85ba500f326d59b50 Mon Sep 17 00:00:00 2001 From: zbt Date: Thu, 16 Jul 2009 10:41:07 +0800 Subject: Add volume ramping feature - envelop fix --- src/pulsecore/envelope.c | 335 ++++++++++++++++++++++++++++++++++++++--------- src/pulsecore/envelope.h | 3 + 2 files changed, 273 insertions(+), 65 deletions(-) diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c index fd6a9487..0eca8115 100644 --- a/src/pulsecore/envelope.c +++ b/src/pulsecore/envelope.c @@ -177,7 +177,7 @@ static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) { pa_assert(i->j > 0); pa_assert(i->def->points_x[i->j-1] <= x); - pa_assert(x < i->def->points_x[i->j]); + pa_assert(x <= i->def->points_x[i->j]); return linear_interpolate_int(i->def->points_x[i->j-1], i->def->points_y.i[i->j-1], i->def->points_x[i->j], i->def->points_y.i[i->j], x); @@ -200,7 +200,7 @@ static float item_get_float(pa_envelope_item *i, pa_usec_t x) { pa_assert(i->j > 0); pa_assert(i->def->points_x[i->j-1] <= x); - pa_assert(x < i->def->points_x[i->j]); + pa_assert(x <= i->def->points_x[i->j]); return linear_interpolate_float(i->def->points_x[i->j-1], i->def->points_y.f[i->j-1], i->def->points_x[i->j], i->def->points_y.f[i->j], x); @@ -550,7 +550,7 @@ static int32_t linear_get_int(pa_envelope *e, int v) { e->points[v].cached_valid = TRUE; } - return e->points[v].y.i[e->points[v].n_current] + (e->points[v].cached_dy_i * (int32_t) (e->x - e->points[v].x[e->points[v].n_current])) / (int32_t) e->points[v].cached_dx; + return e->points[v].y.i[e->points[v].n_current] + ((float)e->points[v].cached_dy_i * (int32_t) (e->x - e->points[v].x[e->points[v].n_current])) / (int32_t) e->points[v].cached_dx; } static float linear_get_float(pa_envelope *e, int v) { @@ -597,34 +597,60 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { fs = pa_frame_size(&e->sample_spec); n = chunk->length; + pa_log_debug("Envelop position %d applying factor %d=%f, sample spec is %d, chunk's length is %d, fs is %d\n", e->x, linear_get_int(e, v), ((float) linear_get_int(e,v))/0x10000, e->sample_spec.format, n, fs); + switch (e->sample_spec.format) { case PA_SAMPLE_U8: { - uint8_t *t; + uint8_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (uint8_t*) p + n; - for (c = 0; c < e->sample_spec.channels; c++, t++) - *t = (uint8_t) (((factor * ((int16_t) *t - 0x80)) / 0x10000) + 0x80); + for (channel = 0, d = p; d < s; d++) { + int32_t t, hi, lo; + + hi = factor >> 16; + lo = factor & 0xFFFF; + + t = (int32_t) *d - 0x80; + t = ((t * lo) >> 16) + (t * hi); + t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F); + *d = (uint8_t) (t + 0x80); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } } break; } case PA_SAMPLE_ULAW: { - uint8_t *t; + uint8_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (uint8_t*) p + n; - for (c = 0; c < e->sample_spec.channels; c++, t++) { - int16_t k = st_ulaw2linear16(*t); - *t = (uint8_t) st_14linear2ulaw((int16_t) (((factor * k) / 0x10000) >> 2)); + for (channel = 0, d = p; d < s; d++) { + int32_t t, hi, lo; + + hi = factor >> 16; + lo = factor & 0xFFFF; + + t = (int32_t) st_ulaw2linear16(*d); + t = ((t * lo) >> 16) + (t * hi); + t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); + *d = (uint8_t) st_14linear2ulaw((int16_t) t >> 2); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); } } @@ -632,16 +658,27 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } case PA_SAMPLE_ALAW: { - uint8_t *t; + uint8_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (uint8_t*) p + n; - for (c = 0; c < e->sample_spec.channels; c++, t++) { - int16_t k = st_alaw2linear16(*t); - *t = (uint8_t) st_13linear2alaw((int16_t) (((factor * k) / 0x10000) >> 3)); + for (channel = 0, d = p; d < s; d++) { + int32_t t, hi, lo; + + hi = factor >> 16; + lo = factor & 0xFFFF; + + t = (int32_t) st_alaw2linear16(*d); + t = ((t * lo) >> 16) + (t * hi); + t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); + *d = (uint8_t) st_13linear2alaw((int16_t) t >> 3); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); } } @@ -649,31 +686,55 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } case PA_SAMPLE_S16NE: { - int16_t *t; + int16_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (int16_t*) p + n/sizeof(int16_t); - for (c = 0; c < e->sample_spec.channels; c++, t++) - *t = (int16_t) ((factor * *t) / 0x10000); + for (channel = 0, d = p; d < s; d++) { + int32_t t, hi, lo; + + hi = factor >> 16; + lo = factor & 0xFFFF; + + t = (int32_t)(*d); + t = ((t * lo) >> 16) + (t * hi); + t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); + *d = (int16_t) t; + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } } break; } case PA_SAMPLE_S16RE: { - int16_t *t; + int16_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (int16_t*) p + n/sizeof(int16_t); - for (c = 0; c < e->sample_spec.channels; c++, t++) { - int16_t r = (int16_t) ((factor * PA_INT16_SWAP(*t)) / 0x10000); - *t = PA_INT16_SWAP(r); + for (channel = 0, d = p; d < s; d++) { + int32_t t, hi, lo; + + hi = factor >> 16; + lo = factor & 0xFFFF; + + t = (int32_t) PA_INT16_SWAP(*d); + t = ((t * lo) >> 16) + (t * hi); + t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); + *d = PA_INT16_SWAP((int16_t) t); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); } } @@ -681,31 +742,49 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } case PA_SAMPLE_S32NE: { - int32_t *t; + int32_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (int32_t*) p + n/sizeof(int32_t); - for (c = 0; c < e->sample_spec.channels; c++, t++) - *t = (int32_t) (((int64_t) factor * (int64_t) *t) / 0x10000); + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t)(*d); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + *d = (int32_t) t; + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } } break; } case PA_SAMPLE_S32RE: { - int32_t *t; + int32_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); - for (t = p; n > 0; n -= fs) { - int32_t factor = linear_get_int(e, v); - unsigned c; - e->x += fs; + s = (int32_t*) p + n/sizeof(int32_t); - for (c = 0; c < e->sample_spec.channels; c++, t++) { - int32_t r = (int32_t) (((int64_t) factor * (int64_t) PA_INT32_SWAP(*t)) / 0x10000); - *t = PA_INT32_SWAP(r); + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t) PA_INT32_SWAP(*d); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + *d = PA_INT32_SWAP((int32_t) t); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); } } @@ -713,6 +792,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } case PA_SAMPLE_FLOAT32NE: { + /*Seems the FLOAT32NE part of pa_volume_memchunk not right, do not reuse here*/ float *t; for (t = p; n > 0; n -= fs) { @@ -728,6 +808,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } case PA_SAMPLE_FLOAT32RE: { + /*Seems the FLOAT32RE part of pa_volume_memchunk not right, do not reuse here*/ float *t; for (t = p; n > 0; n -= fs) { @@ -744,10 +825,101 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { break; } - case PA_SAMPLE_S24LE: - case PA_SAMPLE_S24BE: - case PA_SAMPLE_S24_32LE: - case PA_SAMPLE_S24_32BE: + case PA_SAMPLE_S24NE: { + uint8_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); + + s = (uint8_t*) p + n/3; + + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t)((int32_t) (PA_READ24NE(d) << 8)); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + PA_WRITE24NE(d, ((uint32_t) (int32_t) t) >> 8); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } + } + + break; + } + case PA_SAMPLE_S24RE: { + uint8_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); + + s = (uint8_t*) p + n/3; + + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t)((int32_t) (PA_READ24RE(d) << 8)); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + PA_WRITE24RE(d, ((uint32_t) (int32_t) t) >> 8); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } + } + + break; + } + case PA_SAMPLE_S24_32NE: { + uint32_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); + + s = (uint32_t*) p + n/sizeof(uint32_t); + + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t) ((int32_t) (*d << 8)); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + *d = ((uint32_t) ((int32_t) t)) >> 8; + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } + } + + break; + } + case PA_SAMPLE_S24_32RE: { + uint32_t *d, *s; + unsigned channel; + int32_t factor = linear_get_int(e, v); + + s = (uint32_t*) p + n/sizeof(uint32_t); + + for (channel = 0, d = p; d < s; d++) { + int64_t t; + + t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*d) << 8)); + t = (t * factor) >> 16; + t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); + *d = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8); + + if (PA_UNLIKELY(++channel >= e->sample_spec.channels)) { + channel = 0; + e->x += fs; + factor = linear_get_int(e, v); + } + } + break; + } /* FIXME */ pa_assert_not_reached(); @@ -757,8 +929,6 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { } pa_memblock_release(chunk->memblock); - - e->x += chunk->length; } else { /* When we have no envelope to apply we reset our origin */ e->x = 0; @@ -774,13 +944,48 @@ void pa_envelope_rewind(pa_envelope *e, size_t n_bytes) { envelope_begin_read(e, &v); - if (n_bytes < e->x) - e->x -= n_bytes; + if (e->x - n_bytes <= e->points[v].x[0]) + e->x = e->points[v].x[0]; else - e->x = 0; + e->x -= n_bytes; e->points[v].n_current = 0; e->points[v].cached_valid = FALSE; envelope_commit_read(e, v); } + +void pa_envelope_restart(pa_envelope* e) { + int v; + pa_assert(e); + + envelope_begin_read(e, &v); + e->x = e->points[v].x[0]; + envelope_commit_read(e, v); +} + +pa_bool_t pa_envelope_is_finished(pa_envelope* e) { + pa_assert(e); + + int v; + pa_bool_t finished; + + envelope_begin_read(e, &v); + finished = (e->x >= e->points[v].x[e->points[v].n_points-1]); + envelope_commit_read(e, v); + + return finished; +} + +int32_t pa_envelope_length(pa_envelope *e) { + pa_assert(e); + + int v; + size_t size; + + envelope_begin_read(e, &v); + size = e->points[v].x[e->points[v].n_points-1] - e->points[v].x[0]; + envelope_commit_read(e, v); + + return size; +} diff --git a/src/pulsecore/envelope.h b/src/pulsecore/envelope.h index 5296415a..4fa36579 100644 --- a/src/pulsecore/envelope.h +++ b/src/pulsecore/envelope.h @@ -49,5 +49,8 @@ pa_envelope_item *pa_envelope_replace(pa_envelope *e, pa_envelope_item *i, const void pa_envelope_remove(pa_envelope *e, pa_envelope_item *i); void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk); void pa_envelope_rewind(pa_envelope *e, size_t n_bytes); +void pa_envelope_restart(pa_envelope* e); +pa_bool_t pa_envelope_is_finished(pa_envelope* e); +int32_t pa_envelope_length(pa_envelope *e); #endif -- cgit From 5318eb35ef3f91836084382a4f3d5ef08d322554 Mon Sep 17 00:00:00 2001 From: zbt Date: Thu, 16 Jul 2009 10:41:34 +0800 Subject: Add volume ramping feature - sink-input modification --- src/pulsecore/sink-input.c | 351 +++++++++++++++++++++++++++++++++++++-------- src/pulsecore/sink-input.h | 21 +++ 2 files changed, 312 insertions(+), 60 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index a5f96351..2acaa08f 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "sink-input.h" @@ -47,6 +48,11 @@ static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject); static void sink_input_free(pa_object *o); +static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t); +static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t); +static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk); +static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes); +static void sink_input_release_envelope(pa_sink_input *i); pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) { pa_assert(data); @@ -301,6 +307,16 @@ int pa_sink_input_new( reset_callbacks(i); i->userdata = NULL; + /* Set Ramping info */ + i->thread_info.ramp_info.is_ramping = FALSE; + i->thread_info.ramp_info.envelope_dead = TRUE; + i->thread_info.ramp_info.envelope = NULL; + i->thread_info.ramp_info.item = NULL; + i->thread_info.ramp_info.envelope_dying = 0; + + pa_atomic_store(&i->before_ramping_v, 0); + pa_atomic_store(&i->before_ramping_m, 0); + i->thread_info.state = i->state; i->thread_info.attached = FALSE; pa_atomic_store(&i->thread_info.drained, 1); @@ -480,6 +496,12 @@ static void sink_input_free(pa_object *o) { pa_assert(!i->thread_info.attached); + if (i->thread_info.ramp_info.envelope) { + pa_log_debug ("Freeing envelope\n"); + pa_envelope_free(i->thread_info.ramp_info.envelope); + i->thread_info.ramp_info.envelope = NULL; + } + if (i->thread_info.render_memblockq) pa_memblockq_free(i->thread_info.render_memblockq); @@ -565,6 +587,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) { void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) { pa_bool_t do_volume_adj_here; pa_bool_t volume_is_norm; + pa_bool_t ramping; size_t block_size_max_sink, block_size_max_sink_input; size_t ilength; @@ -608,7 +631,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p * to adjust the volume *before* we resample. Otherwise we can do * it after and leave it for the sink code */ - do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map); + do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map) || i->thread_info.ramp_info.is_ramping; volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted; while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) { @@ -649,7 +672,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p wchunk.length = block_size_max_sink_input; /* It might be necessary to adjust the volume here */ - if (do_volume_adj_here && !volume_is_norm) { + if (do_volume_adj_here && !volume_is_norm && !i->thread_info.ramp_info.is_ramping) { pa_memchunk_make_writable(&wchunk, 0); if (i->thread_info.muted) @@ -691,6 +714,23 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p if (chunk->length > block_size_max_sink) chunk->length = block_size_max_sink; + ramping = i->thread_info.ramp_info.is_ramping; + if (ramping) + sink_input_volume_ramping(i, chunk); + + if (!i->thread_info.ramp_info.envelope_dead) { + i->thread_info.ramp_info.envelope_dying += chunk->length; + pa_log_debug("Envelope dying is %d, chunk length is %d, dead thresholder is %d\n", i->thread_info.ramp_info.envelope_dying, + chunk->length, + i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope)); + + if (i->thread_info.ramp_info.envelope_dying >= (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) { + pa_log_debug("RELEASE Envelop"); + i->thread_info.ramp_info.envelope_dead = TRUE; + sink_input_release_envelope(i); + } + } + /* Let's see if we had to apply the volume adjustment ourselves, * or if this can be done by the sink for us */ @@ -733,6 +773,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam if (nbytes > 0 && !i->thread_info.dont_rewind_render) { pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes); pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes); + sink_input_rewind_ramp_info(i, nbytes); } if (i->thread_info.rewrite_nbytes == (size_t) -1) { @@ -873,50 +914,8 @@ pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) { /* Called from main context */ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) { - pa_cvolume v; - - pa_sink_input_assert_ref(i); - pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - pa_assert(volume); - pa_assert(pa_cvolume_valid(volume)); - pa_assert(pa_cvolume_compatible(volume, &i->sample_spec)); - - if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) { - v = i->sink->reference_volume; - pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map); - volume = pa_sw_cvolume_multiply(&v, &v, volume); - } - - if (pa_cvolume_equal(volume, &i->virtual_volume)) - return; - - i->virtual_volume = *volume; - i->save_volume = save; - - if (i->sink->flags & PA_SINK_FLAT_VOLUME) { - pa_cvolume new_volume; - - /* We are in flat volume mode, so let's update all sink input - * volumes and update the flat volume of the sink */ - - pa_sink_update_flat_volume(i->sink, &new_volume); - pa_sink_set_volume(i->sink, &new_volume, FALSE, TRUE, FALSE, FALSE); - - } else { - - /* OK, we are in normal volume mode. The volume only affects - * ourselves */ - pa_sink_input_set_relative_volume(i, volume); - - /* Hooks have the ability to play games with i->soft_volume */ - pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i); - - /* Copy the new soft_volume to the thread_info struct */ - pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0); - } - - /* The virtual volume changed, let's tell people so */ - pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + /* test ramping -> return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 2000 * PA_USEC_PER_MSEC); */ + return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 0); } /* Called from main context */ @@ -985,18 +984,8 @@ void pa_sink_input_set_relative_volume(pa_sink_input *i, const pa_cvolume *v) { /* Called from main context */ void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) { - pa_assert(i); - pa_sink_input_assert_ref(i); - pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - - if (!i->muted == !mute) - return; - - i->muted = mute; - i->save_muted = save; - - pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0); - pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + /* test ramping -> return pa_sink_input_set_mute_with_ramping(i, mute, save, 2000 * PA_USEC_PER_MSEC); */ + return pa_sink_input_set_mute_with_ramping(i, mute, save, 0); } /* Called from main context */ @@ -1347,15 +1336,23 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t switch (code) { case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME: + if (pa_atomic_load(&i->before_ramping_v)) + i->thread_info.future_soft_volume = i->soft_volume; + if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) { - i->thread_info.soft_volume = i->soft_volume; + if (!pa_atomic_load(&i->before_ramping_v)) + i->thread_info.soft_volume = i->soft_volume; pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE); } return 0; case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE: + if (pa_atomic_load(&i->before_ramping_m)) + i->thread_info.future_muted = i->muted; + if (i->thread_info.muted != i->muted) { - i->thread_info.muted = i->muted; + if (!pa_atomic_load(&i->before_ramping_m)) + i->thread_info.muted = i->muted; pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE); } return 0; @@ -1403,6 +1400,26 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t *r = i->thread_info.requested_sink_latency; return 0; } + + case PA_SINK_INPUT_MESSAGE_SET_ENVELOPE: { + if (!i->thread_info.ramp_info.envelope) + i->thread_info.ramp_info.envelope = pa_envelope_new(&i->sink->sample_spec); + + if (i->thread_info.ramp_info.envelope && i->thread_info.ramp_info.item) { + pa_envelope_remove(i->thread_info.ramp_info.envelope, i->thread_info.ramp_info.item); + i->thread_info.ramp_info.item = NULL; + } + + i->thread_info.ramp_info.item = pa_envelope_add(i->thread_info.ramp_info.envelope, &i->using_def); + i->thread_info.ramp_info.is_ramping = TRUE; + i->thread_info.ramp_info.envelope_dead = FALSE; + i->thread_info.ramp_info.envelope_dying = 0; + + if (i->thread_info.ramp_info.envelope) + pa_envelope_restart(i->thread_info.ramp_info.envelope); + + return 0; + } } return -PA_ERR_NOTIMPLEMENTED; @@ -1550,3 +1567,217 @@ finish: if (pl) pa_proplist_free(pl); } + +/* Called from IO context */ +static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk) { + pa_assert(i); + pa_assert(chunk); + pa_assert(chunk->memblock); + pa_assert(i->thread_info.ramp_info.is_ramping); + + /* Volume is adjusted with ramping effect here */ + pa_envelope_apply(i->thread_info.ramp_info.envelope, chunk); + + if (pa_envelope_is_finished(i->thread_info.ramp_info.envelope)) { + i->thread_info.ramp_info.is_ramping = FALSE; + if (pa_atomic_load(&i->before_ramping_v)) { + i->thread_info.soft_volume = i->thread_info.future_soft_volume; + pa_atomic_store(&i->before_ramping_v, 0); + } + else if (pa_atomic_load(&i->before_ramping_m)) { + i->thread_info.muted = i->thread_info.future_muted; + pa_atomic_store(&i->before_ramping_m, 0); + } + } +} + +/* + * Called from main context + * This function should be called inside pa_sink_input_set_volume_with_ramping + * should be called after soft_volume of sink_input and sink are all adjusted + */ +static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t) { + + int32_t target_abs_vol, target_apply_vol, pre_apply_vol; + pa_assert(i); + + pa_log_debug("Sink input's soft volume is %d= %f ", pa_cvolume_avg(&i->soft_volume), pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume))); + + /* Calculation formula are target_abs_vol := i->soft_volume + * target_apply_vol := lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000) + * pre_apply_vol := ( previous_virtual_volume / target_virtual_volume ) * target_apply_vol + * + * Will do volume adjustment inside pa_sink_input_peek + */ + target_abs_vol = pa_cvolume_avg(&i->soft_volume); + target_apply_vol = (int32_t) lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000); + pre_apply_vol = (int32_t) ((pa_sw_volume_to_linear(pre_virtual_volume) / pa_sw_volume_to_linear(target_virtual_volume)) * target_apply_vol); + + i->using_def.n_points = 2; + i->using_def.points_x[0] = 0; + i->using_def.points_x[1] = t; + i->using_def.points_y.i[0] = pre_apply_vol; + i->using_def.points_y.i[1] = target_apply_vol; + i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000; + i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000; + + pa_log_debug("Volume Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0], + i->using_def.points_y.i[1], i->using_def.points_y.f[1]); + + pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0); +} + +/* Called from main context */ +static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t) { + + int32_t cur_vol; + pa_assert(i); + + i->using_def.n_points = 2; + i->using_def.points_x[0] = 0; + i->using_def.points_x[1] = t; + cur_vol = (int32_t) lrint( pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)) * 0x10000); + + if (mute) { + i->using_def.points_y.i[0] = cur_vol; + i->using_def.points_y.i[1] = 0; + } else { + i->using_def.points_y.i[0] = 0; + i->using_def.points_y.i[1] = cur_vol; + } + + i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000; + i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000; + + pa_log_debug("Mute Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0], + i->using_def.points_y.i[1], i->using_def.points_y.f[1]); + + pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0); +} + +/* Called from IO context */ +static void sink_input_release_envelope(pa_sink_input *i) { + pa_assert(i); + pa_assert(!i->thread_info.ramp_info.is_ramping); + pa_assert(i->thread_info.ramp_info.envelope_dead); + + pa_envelope_free(i->thread_info.ramp_info.envelope); + i->thread_info.ramp_info.envelope = NULL; + i->thread_info.ramp_info.item = NULL; +} + +/* Called from IO context */ +static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) { + pa_assert(i); + + if (!i->thread_info.ramp_info.envelope_dead) { + pa_assert(i->thread_info.ramp_info.envelope); + + int32_t envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope); + + if (i->thread_info.ramp_info.envelope_dying > envelope_length) { + if ((i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) { + pa_log_debug("Envelope Become Alive"); + pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes)); + i->thread_info.ramp_info.is_ramping = TRUE; + } + } else if (i->thread_info.ramp_info.envelope_dying < envelope_length) { + if ((i->thread_info.ramp_info.envelope_dying - nbytes) <= 0) { + pa_log_debug("Envelope Restart"); + pa_envelope_restart(i->thread_info.ramp_info.envelope); + } + else { + pa_log_debug("Envelope Simple Rewind"); + pa_envelope_rewind(i->thread_info.ramp_info.envelope, nbytes); + } + } + + i->thread_info.ramp_info.envelope_dying -= nbytes; + if (i->thread_info.ramp_info.envelope_dying <= 0) + i->thread_info.ramp_info.envelope_dying = 0; + } +} + +void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t t){ + pa_cvolume v; + pa_volume_t previous_virtual_volume, target_virtual_volume; + pa_sink_input_assert_ref(i); + + pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); + pa_assert(volume); + pa_assert(pa_cvolume_valid(volume)); + pa_assert(pa_cvolume_compatible(volume, &i->sample_spec)); + + if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) { + v = i->sink->reference_volume; + pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map); + volume = pa_sw_cvolume_multiply(&v, &v, volume); + } + + if (pa_cvolume_equal(volume, &i->virtual_volume)) + return; + + previous_virtual_volume = pa_cvolume_avg(&i->virtual_volume); + target_virtual_volume = pa_cvolume_avg(volume); + if (t > 0 && target_virtual_volume > 0) + pa_log_debug("SetVolumeWithRamping: Virtual Volume From %u=%f to %u=%f\n", previous_virtual_volume, pa_sw_volume_to_linear(previous_virtual_volume), + target_virtual_volume, pa_sw_volume_to_linear(target_virtual_volume)); + + i->virtual_volume = *volume; + i->save_volume = save; + + /* Set this flag before the following code modify i->thread_info.soft_volume */ + if (t > 0 && target_virtual_volume > 0) + pa_atomic_store(&i->before_ramping_v, 1); + + if (i->sink->flags & PA_SINK_FLAT_VOLUME) { + pa_cvolume new_volume; + + /* We are in flat volume mode, so let's update all sink input + * volumes and update the flat volume of the sink */ + + pa_sink_update_flat_volume(i->sink, &new_volume); + pa_sink_set_volume(i->sink, &new_volume, FALSE, TRUE, FALSE, FALSE); + + } else { + + /* OK, we are in normal volume mode. The volume only affects + * ourselves */ + pa_sink_input_set_relative_volume(i, volume); + + /* Hooks have the ability to play games with i->soft_volume */ + pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i); + + /* Copy the new soft_volume to the thread_info struct */ + pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0); + } + + if (t > 0 && target_virtual_volume > 0) + sink_input_set_ramping_info(i, previous_virtual_volume, target_virtual_volume, t); + + /* The virtual volume changed, let's tell people so */ + pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); +} + +void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){ + + pa_assert(i); + pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); + + if (!i->muted == !mute) + return; + + i->muted = mute; + i->save_muted = save; + /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */ + if (t > 0) + pa_atomic_store(&i->before_ramping_m, 1); + + pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0); + + if (t > 0) + sink_input_set_ramping_info_for_mute(i, mute, t); + + pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); +} diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 98144d41..036806fc 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -35,6 +35,7 @@ typedef struct pa_sink_input pa_sink_input; #include #include #include +#include typedef enum pa_sink_input_state { PA_SINK_INPUT_INIT, /*< The stream is not active yet, because pa_sink_put() has not been called yet */ @@ -212,8 +213,23 @@ struct pa_sink_input { pa_usec_t requested_sink_latency; pa_hashmap *direct_outputs; + + struct { + pa_bool_t is_ramping:1; + pa_bool_t envelope_dead:1; + int32_t envelope_dying; /* Increasing while envelop is not dead. Reduce it while process_rewind. */ + pa_envelope *envelope; + pa_envelope_item *item; + } ramp_info; + pa_cvolume future_soft_volume; + pa_bool_t future_muted; + } thread_info; + pa_atomic_t before_ramping_v; /* Indicates future volume */ + pa_atomic_t before_ramping_m; /* Indicates future mute */ + pa_envelope_def using_def; + void *userdata; }; @@ -228,6 +244,7 @@ enum { PA_SINK_INPUT_MESSAGE_SET_STATE, PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, + PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, PA_SINK_INPUT_MESSAGE_MAX }; @@ -359,4 +376,8 @@ pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret); /* To be used by sink.c only */ void pa_sink_input_set_relative_volume(pa_sink_input *i, const pa_cvolume *v); +/* Volume ramping*/ +void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t t); +void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t); + #endif -- cgit From 897ef86b7fbb87ef17d30c584e6cd93abfc342bc Mon Sep 17 00:00:00 2001 From: zbt Date: Thu, 16 Jul 2009 10:41:58 +0800 Subject: Add volume ramping feature - sink modification --- src/pulsecore/sink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index d8f3c7d1..29500718 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -1599,10 +1599,14 @@ static void sync_input_volumes_within_thread(pa_sink *s) { pa_sink_assert_ref(s); while ((i = PA_SINK_INPUT(pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))) { + if (pa_atomic_load(&i->before_ramping_v)) + i->thread_info.future_soft_volume = i->soft_volume; + if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) continue; - i->thread_info.soft_volume = i->soft_volume; + if (!pa_atomic_load(&i->before_ramping_v)) + i->thread_info.soft_volume = i->soft_volume; pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE); } } -- cgit From f202af17b717f5b383ac072f80a6c1327bc3143b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Nov 2009 22:55:14 +0100 Subject: ramping: minor cleanups --- src/pulsecore/sink-input.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 216edd41..177d330d 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -1813,6 +1813,7 @@ void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *v else volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume)); } else { + if (!pa_cvolume_compatible(volume, &i->sample_spec)) { v = i->volume; volume = pa_cvolume_scale(&v, pa_cvolume_max(volume)); @@ -1866,15 +1867,18 @@ void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *v void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){ - pa_assert(i); pa_sink_input_assert_ref(i); + pa_assert_ctl_context(); pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - if (!i->muted == !mute) + if (!i->muted == !mute) { + i->save_muted = i->save_muted || mute; return; + } i->muted = mute; i->save_muted = save; + /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */ if (t > 0) pa_atomic_store(&i->before_ramping_m, 1); @@ -1884,5 +1888,9 @@ void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bo if (t > 0) sink_input_set_ramping_info_for_mute(i, mute, t); + /* The mute status changed, let's tell people so */ + if (i->mute_changed) + i->mute_changed(i); + pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } -- cgit From dad36acea34f91cc1d4a7f8e4909369d2225525b Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Wed, 11 Nov 2009 17:24:57 +0000 Subject: device-manager: Update docs version -> 0.9.20 Third time is a charm... maybe. --- src/pulse/ext-device-manager.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pulse/ext-device-manager.h b/src/pulse/ext-device-manager.h index 8264b8f7..df0ab92f 100644 --- a/src/pulse/ext-device-manager.h +++ b/src/pulse/ext-device-manager.h @@ -39,7 +39,7 @@ typedef struct pa_ext_device_manager_role_priority_info { } pa_ext_device_manager_role_priority_info; /** Stores information about one device in the device database that is - * maintained by module-device-manager. \since 0.9.20 */ + * maintained by module-device-manager. \since 0.9.21 */ typedef struct pa_ext_device_manager_info { const char *name; /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */ const char *description; /**< The description of the device when it was last seen, if applicable and saved */ @@ -49,32 +49,32 @@ typedef struct pa_ext_device_manager_info { pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */ } pa_ext_device_manager_info; -/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.20 */ +/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.21 */ typedef void (*pa_ext_device_manager_test_cb_t)( pa_context *c, uint32_t version, void *userdata); -/** Test if this extension module is available in the server. \since 0.9.20 */ +/** Test if this extension module is available in the server. \since 0.9.21 */ pa_operation *pa_ext_device_manager_test( pa_context *c, pa_ext_device_manager_test_cb_t cb, void *userdata); -/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.20 */ +/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.21 */ typedef void (*pa_ext_device_manager_read_cb_t)( pa_context *c, const pa_ext_device_manager_info *info, int eol, void *userdata); -/** Read all entries from the device database. \since 0.9.20 */ +/** Read all entries from the device database. \since 0.9.21 */ pa_operation *pa_ext_device_manager_read( pa_context *c, pa_ext_device_manager_read_cb_t cb, void *userdata); -/** Sets the description for a device. \since 0.9.20 */ +/** Sets the description for a device. \since 0.9.21 */ pa_operation *pa_ext_device_manager_set_device_description( pa_context *c, const char* device, @@ -82,21 +82,21 @@ pa_operation *pa_ext_device_manager_set_device_description( pa_context_success_cb_t cb, void *userdata); -/** Delete entries from the device database. \since 0.9.20 */ +/** Delete entries from the device database. \since 0.9.21 */ pa_operation *pa_ext_device_manager_delete( pa_context *c, const char *const s[], pa_context_success_cb_t cb, void *userdata); -/** Enable the role-based device-priority routing mode. \since 0.9.20 */ +/** Enable the role-based device-priority routing mode. \since 0.9.21 */ pa_operation *pa_ext_device_manager_enable_role_device_priority_routing( pa_context *c, int enable, pa_context_success_cb_t cb, void *userdata); -/** Prefer a given device in the priority list. \since 0.9.20 */ +/** Prefer a given device in the priority list. \since 0.9.21 */ pa_operation *pa_ext_device_manager_reorder_devices_for_role( pa_context *c, const char* role, @@ -104,20 +104,20 @@ pa_operation *pa_ext_device_manager_reorder_devices_for_role( pa_context_success_cb_t cb, void *userdata); -/** Subscribe to changes in the device database. \since 0.9.20 */ +/** Subscribe to changes in the device database. \since 0.9.21 */ pa_operation *pa_ext_device_manager_subscribe( pa_context *c, int enable, pa_context_success_cb_t cb, void *userdata); -/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.20 */ +/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.21 */ typedef void (*pa_ext_device_manager_subscribe_cb_t)( pa_context *c, void *userdata); /** Set the subscription callback that is called when - * pa_ext_device_manager_subscribe() was called. \since 0.9.20 */ + * pa_ext_device_manager_subscribe() was called. \since 0.9.21 */ void pa_ext_device_manager_set_subscribe_cb( pa_context *c, pa_ext_device_manager_subscribe_cb_t cb, -- cgit From 14eaf245c63de8b4ec0f0b6845284e52d5f8bcd4 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sat, 14 Nov 2009 22:23:10 +0000 Subject: build-sys: Make sure all alsa path config files are installed While all alsa path configuration files were in EXTRA_DIST not all of them were in in alsapaths_DATA. Fixed by only defining the list in one place --- src/Makefile.am | 66 +++++++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index f0d5a5e8..9860bbed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,27 +109,12 @@ MODULE_LDFLAGS = -module -disable-static -avoid-version $(LDFLAGS_NOUNDEFINED) # Extra files # ################################### -EXTRA_DIST = \ - pulse/client.conf.in \ - pulse/version.h.in \ - daemon/daemon.conf.in \ - daemon/default.pa.in \ - daemon/system.pa.in \ - daemon/default.pa.win32 \ - depmod.py \ - daemon/esdcompat.in \ - daemon/start-pulseaudio-x11.in \ - daemon/start-pulseaudio-kde.in \ - utils/padsp \ - modules/module-defs.h.m4 \ - daemon/pulseaudio.desktop.in \ - daemon/pulseaudio-kde.desktop.in \ - map-file \ - daemon/pulseaudio-system.conf \ +ALSA_PROFILES = \ modules/alsa/mixer/profile-sets/default.conf \ modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \ - modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf \ - modules/alsa/mixer/profile-sets/90-pulseaudio.rules \ + modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf + +ALSA_PATHS = \ modules/alsa/mixer/paths/analog-input-aux.conf \ modules/alsa/mixer/paths/analog-input.conf \ modules/alsa/mixer/paths/analog-input.conf.common \ @@ -148,6 +133,27 @@ EXTRA_DIST = \ modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \ modules/alsa/mixer/paths/analog-output-mono.conf +EXTRA_DIST = \ + pulse/client.conf.in \ + pulse/version.h.in \ + daemon/daemon.conf.in \ + daemon/default.pa.in \ + daemon/system.pa.in \ + daemon/default.pa.win32 \ + depmod.py \ + daemon/esdcompat.in \ + daemon/start-pulseaudio-x11.in \ + daemon/start-pulseaudio-kde.in \ + utils/padsp \ + modules/module-defs.h.m4 \ + daemon/pulseaudio.desktop.in \ + daemon/pulseaudio-kde.desktop.in \ + map-file \ + daemon/pulseaudio-system.conf \ + modules/alsa/mixer/profile-sets/90-pulseaudio.rules + ${ALSA_PROFILES} \ + ${ALSA_PATHS} + pulseconf_DATA = \ default.pa \ system.pa \ @@ -1088,32 +1094,14 @@ modlibexec_LTLIBRARIES += \ module-alsa-source.la \ module-alsa-card.la -alsaprofilesets_DATA = \ - modules/alsa/mixer/profile-sets/default.conf \ - modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \ - modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf +alsaprofilesets_DATA = ${ALSA_PROFILES} if HAVE_UDEV udevrules_DATA = \ modules/alsa/mixer/profile-sets/90-pulseaudio.rules endif -alsapaths_DATA = \ - modules/alsa/mixer/paths/analog-input-aux.conf \ - modules/alsa/mixer/paths/analog-input.conf \ - modules/alsa/mixer/paths/analog-input.conf.common \ - modules/alsa/mixer/paths/analog-input-fm.conf \ - modules/alsa/mixer/paths/analog-input-linein.conf \ - modules/alsa/mixer/paths/analog-input-mic.conf \ - modules/alsa/mixer/paths/analog-input-mic.conf.common \ - modules/alsa/mixer/paths/analog-input-mic-line.conf \ - modules/alsa/mixer/paths/analog-input-tvtuner.conf \ - modules/alsa/mixer/paths/analog-input-video.conf \ - modules/alsa/mixer/paths/analog-output.conf \ - modules/alsa/mixer/paths/analog-output.conf.common \ - modules/alsa/mixer/paths/analog-output-headphones.conf \ - modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \ - modules/alsa/mixer/paths/analog-output-mono.conf +alsapaths_DATA = ${ALSA_PATHS} endif -- cgit From eb5562637beab22f3f906a116775cb98c752320f Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Mon, 16 Nov 2009 23:36:44 +0000 Subject: build-sys: Fix missing trailing slash in 14eaf2 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 9860bbed..b45908b3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -150,7 +150,7 @@ EXTRA_DIST = \ daemon/pulseaudio-kde.desktop.in \ map-file \ daemon/pulseaudio-system.conf \ - modules/alsa/mixer/profile-sets/90-pulseaudio.rules + modules/alsa/mixer/profile-sets/90-pulseaudio.rules \ ${ALSA_PROFILES} \ ${ALSA_PATHS} -- cgit From 9033140f18db820f3be9a6acae88a118d9154cf6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 18 Nov 2009 21:41:38 +0100 Subject: rygel: fix itemCount property for sources Fixes http://pulseaudio.org/ticket/721 --- src/modules/module-rygel-media-server.c | 45 +++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/modules/module-rygel-media-server.c b/src/modules/module-rygel-media-server.c index 4c02e958..82bcd14c 100644 --- a/src/modules/module-rygel-media-server.c +++ b/src/modules/module-rygel-media-server.c @@ -464,8 +464,18 @@ static char **child_array(struct userdata *u, const char *path, unsigned *n) { if (pa_streq(path, OBJECT_SINKS)) m = pa_idxset_size(u->core->sinks); - else + else { + unsigned k; + m = pa_idxset_size(u->core->sources); + k = pa_idxset_size(u->core->sinks); + + pa_assert(m >= k); + + /* Subtract the monitor sources from the numbers of + * sources. There is one monitor source for each sink */ + m -= k; + } array = pa_xnew(char*, m); *n = 0; @@ -473,14 +483,20 @@ static char **child_array(struct userdata *u, const char *path, unsigned *n) { if (pa_streq(path, OBJECT_SINKS)) { pa_sink *sink; - PA_IDXSET_FOREACH(sink, u->core->sinks, idx) + PA_IDXSET_FOREACH(sink, u->core->sinks, idx) { + pa_assert((*n) < m); array[(*n)++] = pa_sprintf_malloc(OBJECT_SINKS "/%u", sink->index); + } } else { pa_source *source; - PA_IDXSET_FOREACH(source, u->core->sources, idx) - if (!source->monitor_of) + PA_IDXSET_FOREACH(source, u->core->sources, idx) { + + if (!source->monitor_of) { + pa_assert((*n) < m); array[(*n)++] = pa_sprintf_malloc(OBJECT_SOURCES "/%u", source->index); + } + } } pa_assert((*n) <= m); @@ -529,16 +545,20 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag free_child_array(array, n); } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "ItemCount")) { + unsigned n, k; + + n = pa_idxset_size(u->core->sinks); + k = pa_idxset_size(u->core->sources); + pa_assert(k >= n); + pa_assert_se(r = dbus_message_new_method_return(m)); append_variant_unsigned(r, NULL, - pa_streq(path, OBJECT_SINKS) ? - pa_idxset_size(u->core->sinks) : - pa_idxset_size(u->core->sources)); + pa_streq(path, OBJECT_SINKS) ? n : k - n); } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaContainer1")) { DBusMessageIter iter, sub; char **array; - unsigned n; + unsigned n, k; pa_assert_se(r = dbus_message_new_method_return(m)); dbus_message_iter_init_append(r, &iter); @@ -550,10 +570,13 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag array = child_array(u, path, &n); append_property_dict_entry_object_array(r, &sub, "Items", (const char**) array, n); free_child_array(array, n); + + n = pa_idxset_size(u->core->sinks); + k = pa_idxset_size(u->core->sources); + pa_assert(k >= n); + append_property_dict_entry_unsigned(r, &sub, "ItemCount", - pa_streq(path, OBJECT_SINKS) ? - pa_idxset_size(u->core->sinks) : - pa_idxset_size(u->core->sources)); + pa_streq(path, OBJECT_SINKS) ? n : k - n); pa_assert_se(dbus_message_iter_close_container(&iter, &sub)); -- cgit From c6c933b4ec9eadc361471d4022f8833a930c241c Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Thu, 29 Oct 2009 18:44:04 -0700 Subject: module-equalizer-sink: (re)added output memblockq commented out timing debug statements --- src/modules/module-equalizer-sink.c | 80 ++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index 7c0ccd3a..c2dcbe3c 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -113,8 +113,11 @@ struct userdata { float **Xs; float ***Hs;//thread updatable copies of the freq response filters (magintude based) pa_aupdate **a_H; - pa_memchunk conv_buffer; pa_memblockq *input_q; + char *output_buffer; + size_t output_buffer_length; + size_t output_buffer_max_length; + pa_memblockq *output_q; pa_bool_t first_iteration; pa_dbus_protocol *dbus_protocol; @@ -489,18 +492,42 @@ static void dsp_logic( } #endif -static void process_samples(struct userdata *u, pa_memchunk *tchunk){ +static void flatten_to_memblockq(struct userdata *u){ + size_t mbs = pa_mempool_block_size_max(u->sink->core->mempool); + pa_memchunk tchunk; + char *dst; + size_t i = 0; + while(i < u->output_buffer_length){ + tchunk.index = 0; + tchunk.length = PA_MIN((u->output_buffer_length - i), mbs); + tchunk.memblock = pa_memblock_new(u->sink->core->mempool, tchunk.length); + //pa_log_debug("pushing %ld into the q", tchunk.length); + dst = pa_memblock_acquire(tchunk.memblock); + memcpy(dst, u->output_buffer + i, tchunk.length); + pa_memblock_release(tchunk.memblock); + pa_memblockq_push(u->output_q, &tchunk); + pa_memblock_unref(tchunk.memblock); + i += tchunk.length; + } +} + +static void process_samples(struct userdata *u){ size_t fs = pa_frame_size(&(u->sink->sample_spec)); - float *dst; unsigned a_i; float *H, X; size_t iterations, offset; pa_assert(u->samples_gathered >= u->window_size); iterations = (u->samples_gathered - u->overlap_size) / u->R; - tchunk->index = 0; - tchunk->length = iterations * u->R * fs; - tchunk->memblock = pa_memblock_new(u->sink->core->mempool, tchunk->length); - dst = ((float*) pa_memblock_acquire(tchunk->memblock)); + //make sure there is enough buffer memory allocated + if(iterations * u->R * fs > u->output_buffer_max_length){ + u->output_buffer_max_length = iterations * u->R * fs; + if(u->output_buffer){ + pa_xfree(u->output_buffer); + } + u->output_buffer = pa_xmalloc(u->output_buffer_max_length); + } + u->output_buffer_length = iterations * u->R * fs; + for(size_t iter = 0; iter < iterations; ++iter){ offset = iter * u->R * fs; for(size_t c = 0;c < u->channels; c++) { @@ -526,14 +553,14 @@ static void process_samples(struct userdata *u, pa_memchunk *tchunk){ u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i]; } } - pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (dst + c) + offset, fs, u->work_buffer, sizeof(float), u->R); + pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (((float *)u->output_buffer) + c) + offset, fs, u->work_buffer, sizeof(float), u->R); } if(u->first_iteration){ u->first_iteration = FALSE; } u->samples_gathered -= u->R; } - pa_memblock_release(tchunk->memblock); + flatten_to_memblockq(u); } static void input_buffer(struct userdata *u, pa_memchunk *in){ @@ -556,7 +583,8 @@ static void input_buffer(struct userdata *u, pa_memchunk *in){ /* Called from I/O thread context */ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) { struct userdata *u; - size_t fs, target_samples, mbs; + size_t fs, target_samples; + size_t mbs; //struct timeval start, end; pa_memchunk tchunk; pa_sink_input_assert_ref(i); @@ -564,13 +592,17 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk pa_assert(chunk); pa_assert(u->sink); fs = pa_frame_size(&(u->sink->sample_spec)); - nbytes = PA_MIN(nbytes, pa_mempool_block_size_max(u->sink->core->mempool)); - target_samples = PA_ROUND_UP(nbytes / fs, u->R); mbs = pa_mempool_block_size_max(u->sink->core->mempool); - //pa_log_debug("vanilla mbs = %ld",mbs); - mbs = PA_ROUND_DOWN(mbs / fs, u->R); - mbs = PA_MAX(mbs, u->R); - target_samples = PA_MAX(target_samples, mbs); + if(pa_memblockq_get_length(u->output_q) > 0){ + //pa_log_debug("qsize is %ld", pa_memblockq_get_length(u->output_q)); + goto END; + } + //nbytes = PA_MIN(nbytes, pa_mempool_block_size_max(u->sink->core->mempool)); + target_samples = PA_ROUND_UP(nbytes / fs, u->R); + ////pa_log_debug("vanilla mbs = %ld",mbs); + //mbs = PA_ROUND_DOWN(mbs / fs, u->R); + //mbs = PA_MAX(mbs, u->R); + //target_samples = PA_MAX(target_samples, mbs); //pa_log_debug("target samples: %ld", target_samples); if(u->first_iteration){ //allocate request_size @@ -594,7 +626,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk pa_assert(input_remaining > 0); while(pa_memblockq_peek(u->input_q, &tchunk) < 0){ //pa_sink_render(u->sink, input_remaining * fs, &tchunk); - pa_sink_render_full(u->sink, input_remaining * fs, &tchunk); + pa_sink_render_full(u->sink, PA_MIN(input_remaining * fs, mbs), &tchunk); pa_assert(tchunk.memblock); pa_memblockq_push(u->input_q, &tchunk); pa_memblock_unref(tchunk.memblock); @@ -619,11 +651,13 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk pa_assert(u->R < u->window_size); //pa_rtclock_get(&start); /* process a block */ - process_samples(u, chunk); + process_samples(u); //pa_rtclock_get(&end); //pa_log_debug("Took %0.6f seconds to process", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC); - +END: + pa_assert_se(pa_memblockq_peek(u->output_q, chunk) >= 0); pa_assert(chunk->memblock); + pa_memblockq_drop(u->output_q, chunk->length); //pa_log_debug("gave %ld", chunk->length/fs); //pa_log_debug("end pop"); return 0; @@ -1143,6 +1177,10 @@ int pa__init(pa_module*m) { u->sink->set_mute = sink_set_mute_cb; u->sink->userdata = u; u->input_q = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, fs, 1, 1, 0, &u->sink->silence); + u->output_q = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, fs, 1, 1, 0, NULL); + u->output_buffer = NULL; + u->output_buffer_length = 0; + u->output_buffer_max_length = 0; pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); //pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->R*fs, &ss)); @@ -1255,6 +1293,10 @@ void pa__done(pa_module*m) { if (u->sink) pa_sink_unref(u->sink); + if(u->output_buffer){ + pa_xfree(u->output_buffer); + } + pa_memblockq_free(u->output_q); pa_memblockq_free(u->input_q); fftwf_destroy_plan(u->inverse_plan); -- cgit From 1178f61280227a399708ea8e5cff9b4204181612 Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Wed, 11 Nov 2009 23:16:14 -0800 Subject: module-equalizer-sink: switch back to reference dsp implementation - cpu usage doesn't really change and there may be a bug in the vectorized version --- src/modules/module-equalizer-sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index c2dcbe3c..bbbeb068 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -340,7 +340,7 @@ static void sink_set_mute_cb(pa_sink *s) { pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted); } -#ifndef __SSE2__ +#if 1 //reference implementation static void dsp_logic( float * restrict dst,//used as a temp array too, needs to be fft_length! -- cgit From 493d8b2fb7915786578daeb9dba9c55b581fcce1 Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Wed, 11 Nov 2009 22:52:52 -0800 Subject: module-equalizer-sink: add latency of output_q and input_q to get latency calculation --- src/modules/module-equalizer-sink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index bbbeb068..0a2860b0 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -253,10 +253,11 @@ static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t of pa_sink_get_latency_within_thread(u->sink_input->sink) + /* Add the latency internal to our sink input on top */ - pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec); + pa_bytes_to_usec(pa_memblockq_get_length(u->output_q), &u->sink_input->sink->sample_spec) + + pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec) + + pa_bytes_to_usec(pa_memblockq_get_length(u->input_q), &u->sink_input->sink->sample_spec); // pa_bytes_to_usec(u->samples_gathered * fs, &u->sink->sample_spec); //+ pa_bytes_to_usec(u->latency * fs, ss) - //+ pa_bytes_to_usec(pa_memblockq_get_length(u->input_q), ss); return 0; } } -- cgit From b8acf5586f3f8e2af61b81569a53749f4afd090b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 17:48:04 +0100 Subject: daemon: complain if user passes too many arguments --- src/daemon/main.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/daemon/main.c b/src/daemon/main.c index 48911827..e6568364 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -537,6 +537,12 @@ int main(int argc, char *argv[]) { goto finish; case PA_CMD_DUMP_CONF: { + + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + s = pa_daemon_conf_dump(conf); fputs(s, stdout); pa_xfree(s); @@ -547,6 +553,11 @@ int main(int argc, char *argv[]) { case PA_CMD_DUMP_RESAMPLE_METHODS: { int i; + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + for (i = 0; i < PA_RESAMPLER_MAX; i++) if (pa_resample_method_supported(i)) printf("%s\n", pa_resample_method_to_string(i)); @@ -561,6 +572,12 @@ int main(int argc, char *argv[]) { goto finish; case PA_CMD_VERSION : + + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + printf(PACKAGE_NAME" "PACKAGE_VERSION"\n"); retval = 0; goto finish; @@ -568,6 +585,11 @@ int main(int argc, char *argv[]) { case PA_CMD_CHECK: { pid_t pid; + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) pa_log_info(_("Daemon not running")); else { @@ -580,6 +602,11 @@ int main(int argc, char *argv[]) { } case PA_CMD_KILL: + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0) pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno)); else @@ -589,6 +616,11 @@ int main(int argc, char *argv[]) { case PA_CMD_CLEANUP_SHM: + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + if (pa_shm_cleanup() >= 0) retval = 0; @@ -598,6 +630,11 @@ int main(int argc, char *argv[]) { pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START); } + if (d < argc) { + pa_log("Too many arguments.\n"); + goto finish; + } + if (getuid() == 0 && !conf->system_instance) pa_log_warn(_("This program is not intended to be run as root (unless --system is specified).")); #ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */ -- cgit From a3b5a944885ff92233aa02e390312fbc04671686 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 17:49:30 +0100 Subject: pulse: try to fix inaccuracy with uncork timing for streams that are created in corked state --- src/pulse/stream.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 29979625..04a4242c 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -376,6 +376,22 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t if (!s->smoother) return; + if (!s->timing_info_valid && + !aposteriori && + !force_start && + !force_stop && + s->context->version >= 13) { + + /* If the server supports STARTED and UNDERFLOW events we take + * them as indications when audio really starts/stops playing, + * if we don't have any timing info yet -- instead of trying + * to be smart and guessing the server time. Otherwise the + * unknown transport delay we don't know might add too much + * noise to our time calculations. */ + + return; + } + x = pa_rtclock_now(); if (s->timing_info_valid) { @@ -390,7 +406,6 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t else if (force_start || s->buffer_attr.prebuf == 0) pa_smoother_resume(s->smoother, x, TRUE); - /* Please note that we have no idea if playback actually started * if prebuf is non-zero! */ } -- cgit From f05ae357b6dee91b4d80c1c09bcf2bbf1a8802fa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 19:48:08 +0100 Subject: pulse: delay smoother update only when unpausing, not when pausing, since we don't want the timer to advance when we are supposedly already paused --- src/pulse/stream.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 04a4242c..4a44c31a 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -376,22 +376,6 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t if (!s->smoother) return; - if (!s->timing_info_valid && - !aposteriori && - !force_start && - !force_stop && - s->context->version >= 13) { - - /* If the server supports STARTED and UNDERFLOW events we take - * them as indications when audio really starts/stops playing, - * if we don't have any timing info yet -- instead of trying - * to be smart and guessing the server time. Otherwise the - * unknown transport delay we don't know might add too much - * noise to our time calculations. */ - - return; - } - x = pa_rtclock_now(); if (s->timing_info_valid) { @@ -403,8 +387,26 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t if (s->suspended || s->corked || force_stop) pa_smoother_pause(s->smoother, x); - else if (force_start || s->buffer_attr.prebuf == 0) + else if (force_start || s->buffer_attr.prebuf == 0) { + + if (!s->timing_info_valid && + !aposteriori && + !force_start && + !force_stop && + s->context->version >= 13) { + + /* If the server supports STARTED events we take them as + * indications when audio really starts/stops playing, if + * we don't have any timing info yet -- instead of trying + * to be smart and guessing the server time. Otherwise the + * unknown transport delay add too much noise to our time + * calculations. */ + + return; + } + pa_smoother_resume(s->smoother, x, TRUE); + } /* Please note that we have no idea if playback actually started * if prebuf is non-zero! */ -- cgit From ba95b1939d581bc6f647616bd12bd673370f3be5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 19:55:47 +0100 Subject: pulse: ask for timing updates both *before* and *after* triggering a stream state change so that in the STARTED/UNDERFLOW callbacks we accurate transport latency information --- src/pulse/stream.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 4a44c31a..4dea5670 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -1482,6 +1482,11 @@ pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *us PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); + /* Ask for a timing update before we cork/uncork to get the best + * accuracy for the transport latency suitable for the + * check_smoother_status() call in the started callback */ + request_auto_timing_update(s, TRUE); + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_command(s->context, PA_COMMAND_DRAIN_PLAYBACK_STREAM, &tag); @@ -1489,6 +1494,10 @@ pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *us pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + /* This might cause the read index to conitnue again, hence + * let's request a timing update */ + request_auto_timing_update(s, TRUE); + return o; } @@ -2037,6 +2046,11 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); + /* Ask for a timing update before we cork/uncork to get the best + * accuracy for the transport latency suitable for the + * check_smoother_status() call in the started callback */ + request_auto_timing_update(s, TRUE); + s->corked = b; o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); @@ -2052,8 +2066,8 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi check_smoother_status(s, FALSE, FALSE, FALSE); - /* This might cause the indexes to hang/start again, hence - * let's request a timing update */ + /* This might cause the indexes to hang/start again, hence let's + * request a timing update, after the cork/uncork, too */ request_auto_timing_update(s, TRUE); return o; @@ -2090,6 +2104,11 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); + /* Ask for a timing update *before* the flush, so that the + * transport usec is as up to date as possible when we get the + * underflow message and update the smoother status*/ + request_auto_timing_update(s, TRUE); + if (!(o = stream_send_simple_command(s, (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM), cb, userdata))) return NULL; @@ -2124,6 +2143,11 @@ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *us PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE); + /* Ask for a timing update before we cork/uncork to get the best + * accuracy for the transport latency suitable for the + * check_smoother_status() call in the started callback */ + request_auto_timing_update(s, TRUE); + if (!(o = stream_send_simple_command(s, PA_COMMAND_PREBUF_PLAYBACK_STREAM, cb, userdata))) return NULL; @@ -2145,6 +2169,11 @@ pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *u PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE); + /* Ask for a timing update before we cork/uncork to get the best + * accuracy for the transport latency suitable for the + * check_smoother_status() call in the started callback */ + request_auto_timing_update(s, TRUE); + if (!(o = stream_send_simple_command(s, PA_COMMAND_TRIGGER_PLAYBACK_STREAM, cb, userdata))) return NULL; @@ -2396,6 +2425,11 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->context->version >= 12, PA_ERR_NOTSUPPORTED); + /* Ask for a timing update before we cork/uncork to get the best + * accuracy for the transport latency suitable for the + * check_smoother_status() call in the started callback */ + request_auto_timing_update(s, TRUE); + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_command( -- cgit From bd3467ff2f982c87db4618cc6ac98780bef407cc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 20:00:26 +0100 Subject: alsa: fix log output when the audio device refuses to give us again the same period settings we had before --- src/modules/alsa/alsa-sink.c | 2 +- src/modules/alsa/alsa-source.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 856adb14..ed16c834 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -983,7 +983,7 @@ static int unsuspend(struct userdata *u) { buffer_size*u->frame_size != u->hwbuf_size) { pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu/%lu, New %lu/%lu)", (unsigned long) u->hwbuf_size, (unsigned long) u->fragment_size, - (unsigned long) (buffer_size*u->fragment_size), (unsigned long) (period_size*u->frame_size)); + (unsigned long) (buffer_size*u->frame_size), (unsigned long) (period_size*u->frame_size)); goto fail; } diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index e775b20c..157698e3 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -930,7 +930,7 @@ static int unsuspend(struct userdata *u) { buffer_size*u->frame_size != u->hwbuf_size) { pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu/%lu, New %lu/%lu)", (unsigned long) u->hwbuf_size, (unsigned long) u->fragment_size, - (unsigned long) (buffer_size*u->fragment_size), (unsigned long) (period_size*u->frame_size)); + (unsigned long) (buffer_size*u->frame_size), (unsigned long) (period_size*u->frame_size)); goto fail; } -- cgit From 6daf112ce0116e7edacd83c538e5c3099c90a774 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Nov 2009 20:27:03 +0100 Subject: alsa: fix minor sampling rate deviations before adjusting the buffer size --- src/modules/alsa/alsa-util.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index b8d13575..52f12599 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -259,6 +259,10 @@ int pa_alsa_set_hw_params( goto finish; } + /* We ignore very small sampling rate deviations */ + if (_ss.rate >= ss->rate*.95 && _ss.rate <= ss->rate*1.05) + _ss.rate = ss->rate; + if (require_exact_channel_number) { if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, _ss.channels)) < 0) { pa_log_debug("snd_pcm_hw_params_set_channels(%u) failed: %s", _ss.channels, pa_alsa_strerror(ret)); @@ -303,7 +307,7 @@ int pa_alsa_set_hw_params( if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { - pa_log_debug("Set buffer size first, period size second."); + pa_log_debug("Set buffer size first (to %lu samples), period size second (to %lu samples).", (unsigned long) _buffer_size, (unsigned long) _period_size); goto success; } @@ -311,7 +315,7 @@ int pa_alsa_set_hw_params( if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { - pa_log_debug("Set period size first, buffer size second."); + pa_log_debug("Set period size first (to %lu samples), buffer size second (to %lu samples).", (unsigned long) _period_size, (unsigned long) _buffer_size); goto success; } } @@ -322,7 +326,7 @@ int pa_alsa_set_hw_params( /* Third try: set only buffer size */ if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { - pa_log_debug("Set only buffer size second."); + pa_log_debug("Set only buffer size (to %lu samples).", (unsigned long) _buffer_size); goto success; } } @@ -333,7 +337,7 @@ int pa_alsa_set_hw_params( /* Fourth try: set only period size */ if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { - pa_log_debug("Set only period size second."); + pa_log_debug("Set only period size (to %lu samples).", (unsigned long) _period_size); goto success; } } @@ -374,9 +378,7 @@ success: goto finish; } - /* If the sample rate deviates too much, we need to resample */ - if (_ss.rate < ss->rate*.95 || _ss.rate > ss->rate*1.05) - ss->rate = _ss.rate; + ss->rate = _ss.rate; ss->channels = _ss.channels; ss->format = _ss.format; -- cgit From 70ba21e78a90b60f38ce524c49907b1f5daa2fba Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 20 Nov 2009 21:08:05 +0100 Subject: Move the platform-specific defines after the compiler has been found. Without this change, on OpenSolaris, it's possible that the compiler will be reported, by default, as failing to produce executables, since _XOPEN_SOURCE=600 requires a C99 compiler to compile even the simples of the programs. --- configure.ac | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 2bc068e6..a3a97a63 100644 --- a/configure.ac +++ b/configure.ac @@ -66,19 +66,6 @@ if type -p stow > /dev/null && test -d /usr/local/stow ; then ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}" fi -#### Platform hacks #### - -case $host in - *-*-solaris* ) - AC_DEFINE(_XOPEN_SOURCE, 600, Needed to get declarations for msg_control and msg_controllen on Solaris) - AC_DEFINE(__EXTENSIONS__, 1, Needed to get declarations for msg_control and msg_controllen on Solaris) - ;; - *-*-darwin* ) - AC_DEFINE([_POSIX_C_SOURCE], [200112L], [Needed to get clock_gettime on Mac OS X]) - AC_DEFINE([_DARWIN_C_SOURCE], [200112L], [Needed to get NSIG on Mac OS X]) - ;; -esac - AM_SILENT_RULES([yes]) #### Checks for programs. #### @@ -95,6 +82,19 @@ AM_PROG_CC_C_O AC_PROG_GCC_TRADITIONAL AC_USE_SYSTEM_EXTENSIONS +#### Platform hacks #### + +case $host in + *-*-solaris* ) + AC_DEFINE(_XOPEN_SOURCE, 600, Needed to get declarations for msg_control and msg_controllen on Solaris) + AC_DEFINE(__EXTENSIONS__, 1, Needed to get declarations for msg_control and msg_controllen on Solaris) + ;; + *-*-darwin* ) + AC_DEFINE([_POSIX_C_SOURCE], [200112L], [Needed to get clock_gettime on Mac OS X]) + AC_DEFINE([_DARWIN_C_SOURCE], [200112L], [Needed to get NSIG on Mac OS X]) + ;; +esac + # M4 AC_CHECK_PROGS([M4], gm4 m4, no) -- cgit From 71ebbfb6ef0a8c368b9c424c3be4fda2519a5770 Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 20 Nov 2009 21:22:24 +0100 Subject: Fix build on Solaris: pass the third parameter to pa_cloexec_open. --- src/modules/module-solaris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index 955997ba..396094ce 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -327,7 +327,7 @@ static int open_audio_device(struct userdata *u, pa_sample_spec *ss) { pa_assert(u); pa_assert(ss); - if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK)) < 0) { + if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK, 0)) < 0) { pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno)); return -1; } -- cgit From 09a58b6813c078a64cf61be4d2ba98e26b4c88b3 Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 20 Nov 2009 21:24:46 +0100 Subject: Don't declare the variable l if FIONREAD is not defined. This avoids two warnings due to FIONREAD not being defined. --- src/modules/module-pipe-sink.c | 3 ++- src/modules/module-pipe-source.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 10cc3415..f06d1ee6 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -101,9 +101,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_MESSAGE_GET_LATENCY: { size_t n = 0; - int l; #ifdef FIONREAD + int l; + if (ioctl(u->fd, FIONREAD, &l) >= 0 && l > 0) n = (size_t) l; #endif diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index de680933..c5eba43f 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -105,9 +105,10 @@ static int source_process_msg( case PA_SOURCE_MESSAGE_GET_LATENCY: { size_t n = 0; - int l; #ifdef FIONREAD + int l; + if (ioctl(u->fd, FIONREAD, &l) >= 0 && l > 0) n = (size_t) l; #endif -- cgit From 4923f3ca773662b2d147bc374995571b5dacdc7f Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 20 Nov 2009 21:25:33 +0100 Subject: Include sys/filio.h if present; this makes use of FIONREAD on Solaris. FIONREAD on OpenSolaris is declared in sys/filio.h. The RTP modules already rely on the presence of FIONREAD, and check for the header, so this brings the pipe source and sink modules on par with them. --- src/modules/module-pipe-sink.c | 4 ++++ src/modules/module-pipe-source.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index f06d1ee6..7a4e730f 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -34,6 +34,10 @@ #include #include +#ifdef HAVE_SYS_FILIO_H +#include +#endif + #include #include diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index c5eba43f..933f0294 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -34,6 +34,10 @@ #include #include +#ifdef HAVE_SYS_FILIO_H +#include +#endif + #include #include -- cgit From 5150a101efbf46d5235813e4bb6651a3a108bb78 Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 20 Nov 2009 21:37:16 +0100 Subject: Check for stow using AC_CHECK_PROG rather than type -p. The type -p check is not compatible with POSIX shells, and indeed fails when used with the FreeBSD 8 default shell. Instead the AC_CHECK_PROG macro is written properly to look for the command. --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a3a97a63..fdc66625 100644 --- a/configure.ac +++ b/configure.ac @@ -61,10 +61,12 @@ AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:4:0]) AC_CANONICAL_HOST AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.]) -if type -p stow > /dev/null && test -d /usr/local/stow ; then +AC_CHECK_PROG([STOW], [stow], [yes], [no]) + +AS_IF([test "x$STOW" = "xyes" && test -d /usr/local/stow], [ AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***]) ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}" -fi +]) AM_SILENT_RULES([yes]) -- cgit From 41853cc7c01d3b400e781bb9db8c09befd04685b Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Fri, 20 Nov 2009 14:56:07 -0800 Subject: added qpaeq script for GUI equalizer control to src/util --- src/utils/qpaeq.py | 546 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100755 src/utils/qpaeq.py diff --git a/src/utils/qpaeq.py b/src/utils/qpaeq.py new file mode 100755 index 00000000..dca0701d --- /dev/null +++ b/src/utils/qpaeq.py @@ -0,0 +1,546 @@ +#!/usr/bin/env python +# qpaeq is a equalizer interface for pulseaudio's equalizer sinks +# Copyright (C) 2009 Jason Newton . + + +import os,math,sys +import PyQt4,sip +from PyQt4 import QtGui,QtCore +from functools import partial + +import dbus.mainloop.qt +import dbus + +import signal +signal.signal(signal.SIGINT, signal.SIG_DFL) +SYNC_TIMEOUT = 4*1000 + +CORE_PATH = "/org/pulseaudio/core1" +CORE_IFACE = "org.PulseAudio.Core1" +def connect(): + if 'PULSE_DBUS_SERVER' in os.environ: + address = os.environ['PULSE_DBUS_SERVER'] + else: + bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. + server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') + address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') + return dbus.connection.Connection(address) + + +#TODO: signals: sink Filter changed, sink reconfigured (window size) (sink iface) +#TODO: manager signals: new sink, removed sink, new profile, removed profile +#TODO: add support for changing of window_size 1000-fft_size (adv option) +#TODO: reconnect support loop 1 second trying to reconnect +#TODO: just resample the filters for profiles when loading to different sizes +#TODO: add preamp +prop_iface='org.freedesktop.DBus.Properties' +eq_iface='org.PulseAudio.Ext.Equalizing1.Equalizer' +device_iface='org.PulseAudio.Core1.Device' +class QPaeq(QtGui.QWidget): + manager_path='/org/pulseaudio/equalizing1' + manager_iface='org.PulseAudio.Ext.Equalizing1.Manager' + core_iface='org.PulseAudio.Core1' + core_path='/org/pulseaudio/core1' + def __init__(self): + QtGui.QWidget.__init__(self) + self.setWindowTitle('qpaeq') + self.slider_widget=None + self.sink_name=None + self.filter_state=None + + self.create_layout() + + self.set_connection() + self.connect_to_sink(self.sinks[0]) + self.set_callbacks() + self.setMinimumSize(self.sizeHint()) + + def create_layout(self): + self.main_layout=QtGui.QVBoxLayout() + self.setLayout(self.main_layout) + toprow_layout=QtGui.QHBoxLayout() + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + #sizePolicy.setHeightForWidth(self.profile_box.sizePolicy().hasHeightForWidth()) + + toprow_layout.addWidget(QtGui.QLabel('Sink')) + self.sink_box = QtGui.QComboBox() + self.sink_box.setSizePolicy(sizePolicy) + self.sink_box.setDuplicatesEnabled(False) + self.sink_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + #self.sink_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + toprow_layout.addWidget(self.sink_box) + + toprow_layout.addWidget(QtGui.QLabel('Channel')) + self.channel_box = QtGui.QComboBox() + self.channel_box.setSizePolicy(sizePolicy) + toprow_layout.addWidget(self.channel_box) + + toprow_layout.addWidget(QtGui.QLabel('Preset')) + self.profile_box = QtGui.QComboBox() + self.profile_box.setSizePolicy(sizePolicy) + self.profile_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + #self.profile_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + toprow_layout.addWidget(self.profile_box) + + large_icon_size=self.style().pixelMetric(QtGui.QStyle.PM_LargeIconSize) + large_icon_size=QtCore.QSize(large_icon_size,large_icon_size) + save_profile=QtGui.QToolButton() + save_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DriveFDIcon)) + save_profile.setIconSize(large_icon_size) + save_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + save_profile.clicked.connect(self.save_profile) + remove_profile=QtGui.QToolButton() + remove_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_TrashIcon)) + remove_profile.setIconSize(large_icon_size) + remove_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + remove_profile.clicked.connect(self.remove_profile) + toprow_layout.addWidget(save_profile) + toprow_layout.addWidget(remove_profile) + + reset_button = QtGui.QPushButton('Reset') + reset_button.clicked.connect(self.reset) + toprow_layout.addStretch() + toprow_layout.addWidget(reset_button) + self.layout().addLayout(toprow_layout) + + self.profile_box.activated.connect(self.load_profile) + self.channel_box.activated.connect(self.select_channel) + def connect_to_sink(self,name): + #TODO: clear slots for profile buttons + + #flush any pending saves for other sinks + if self.filter_state is not None: + self.filter_state.flush_state() + sink=self.connection.get_object(object_path=name) + self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + self.sink=dbus.Interface(sink,dbus_interface=eq_iface) + self.filter_state=FilterState(sink) + #sample_rate,filter_rate,channels,channel) + + self.channel_box.clear() + self.channel_box.addItem('All',self.filter_state.channels) + for i in xrange(self.filter_state.channels): + self.channel_box.addItem('%d' %(i+1,),i) + self.setMinimumSize(self.sizeHint()) + + self.set_slider_widget(SliderArray(self.filter_state)) + + self.sink_name=name + #set the signal listener for this sink + core=self._get_core() + #temporary hack until signal filtering works properly + core.ListenForSignal('',[dbus.ObjectPath(self.sink_name),dbus.ObjectPath(self.manager_path)]) + #for x in ['FilterChanged']: + # core.ListenForSignal("%s.%s" %(self.eq_iface,x),[dbus.ObjectPath(self.sink_name)]) + #core.ListenForSignal(self.eq_iface,[dbus.ObjectPath(self.sink_name)]) + self.sink.connect_to_signal('FilterChanged',self.read_filter) + + def set_slider_widget(self,widget): + layout=self.layout() + if self.slider_widget is not None: + i=layout.indexOf(self.slider_widget) + layout.removeWidget(self.slider_widget) + self.slider_widget.deleteLater() + layout.insertWidget(i,self.slider_widget) + else: + layout.addWidget(widget) + self.slider_widget=widget + self.read_filter() + def _get_core(self): + core_obj=self.connection.get_object(object_path=self.core_path) + core=dbus.Interface(core_obj,dbus_interface=self.core_iface) + return core + def sink_added(self,sink): + #TODO: preserve selected sink + self.update_sinks() + def sink_removed(self,sink): + #TODO: preserve selected sink, try connecting to backup otherwise + if sink==self.sink_name: + #connect to new sink? + pass + self.update_sinks() + def save_profile(self): + #popup dialog box for name + current=self.profile_box.currentIndex() + profile,ok=QtGui.QInputDialog.getItem(self,'Preset Name','Preset',self.profiles,current) + if not ok or profile=='': + return + if profile in self.profiles: + mbox=QtGui.QMessageBox(self) + mbox.setText('%s preset already exists'%(profile,)) + mbox.setInformativeText('Do you want to save over it?') + mbox.setStandardButtons(mbox.Save|mbox.Discard|mbox.Cancel) + mbox.setDefaultButton(mbox.Save) + ret=mbox.exec_() + if ret!=mbox.Save: + return + self.sink.SaveProfile(self.filter_state.channel,dbus.String(profile)) + if self.filter_state.channel==self.filter_state.channels: + for x in range(1,self.filter_state.channels): + self.sink.LoadProfile(x,dbus.String(profile)) + def remove_profile(self): + #find active profile name, remove it + profile=self.profile_box.currentText() + manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) + manager.RemoveProfile(dbus.String(profile)) + def load_profile(self,x): + profile=self.profile_box.itemText(x) + self.filter_state.load_profile(profile) + def select_channel(self,x): + self.filter_state.channel = self.channel_box.itemData(x).toPyObject() + self._set_profile_name() + self.filter_state.readback() + + #TODO: add back in preamp! + #print frequencies + #main_layout.addLayout(self.create_slider(partial(self.update_coefficient,0), + # 'Preamp')[0] + #) + def set_connection(self): + self.connection=connect() + self.manager_obj=self.connection.get_object(object_path=self.manager_path) + manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) + self.sinks=manager_props.Get(self.manager_iface,'EqualizedSinks') + def set_callbacks(self): + manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) + manager.connect_to_signal('ProfilesChanged',self.update_profiles) + manager.connect_to_signal('SinkAdded',self.sink_added) + manager.connect_to_signal('SinkRemoved',self.sink_removed) + #self._get_core().ListenForSignal(self.manager_iface,[]) + #self._get_core().ListenForSignal(self.manager_iface,[dbus.ObjectPath(self.manager_path)]) + #core=self._get_core() + #for x in ['ProfilesChanged','SinkAdded','SinkRemoved']: + # core.ListenForSignal("%s.%s" %(self.manager_iface,x),[dbus.ObjectPath(self.manager_path)]) + self.update_profiles() + self.update_sinks() + def update_profiles(self): + #print 'update profiles called!' + manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) + self.profiles=manager_props.Get(self.manager_iface,'Profiles') + self.profile_box.blockSignals(True) + self.profile_box.clear() + self.profile_box.addItems(self.profiles) + self.profile_box.blockSignals(False) + self._set_profile_name() + def update_sinks(self): + self.sink_box.blockSignals(True) + self.sink_box.clear() + for x in self.sinks: + sink=self.connection.get_object(object_path=x) + sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + simple_name=sink_props.Get(device_iface,'Name') + self.sink_box.addItem(simple_name,x) + self.sink_box.blockSignals(False) + self.sink_box.setMinimumSize(self.sink_box.sizeHint()) + def read_filter(self): + #print self.filter_frequencies + self.filter_state.readback() + def reset(self): + coefs=dbus.Array([1/math.sqrt(2.0)]*(self.filter_state.filter_rate//2+1)) + preamp=1.0 + self.filter_state.set_filter(preamp,coefs) + def _set_profile_name(self): + self.profile_box.blockSignals(True) + profile_name=self.sink.BaseProfile(self.filter_state.channel) + if profile_name is not None: + i=self.profile_box.findText(profile_name) + if i>=0: + self.profile_box.setCurrentIndex(i) + self.profile_box.blockSignals(False) + + +class SliderArray(QtGui.QWidget): + def __init__(self,filter_state,parent=None): + super(SliderArray,self).__init__(parent) + #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') + #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + self.filter_state=filter_state + self.setLayout(QtGui.QHBoxLayout()) + self.sub_array=None + self.set_sub_array(SliderArraySub(self.filter_state)) + self.inhibit_resize=0 + def set_sub_array(self,widget): + if self.sub_array is not None: + self.layout().removeWidget(self.sub_array) + self.sub_array.disconnect_signals() + self.sub_array.deleteLater() + self.sub_array=widget + self.layout().addWidget(self.sub_array) + self.sub_array.connect_signals() + self.filter_state.readback() + def resizeEvent(self,event): + super(SliderArray,self).resizeEvent(event) + if self.inhibit_resize==0: + self.inhibit_resize+=1 + #self.add_sliders_to_fit() + t=QtCore.QTimer(self) + t.setSingleShot(True) + t.setInterval(0) + t.timeout.connect(partial(self.add_sliders_to_fit,event)) + t.start() + def add_sliders_to_fit(self,event): + if event.oldSize().width()>0 and event.size().width()>0: + i=len(self.filter_state.frequencies)*int(round(float(event.size().width())/event.oldSize().width())) + else: + i=len(self.filter_state.frequencies) + + t_w=self.size().width() + def evaluate(filter_state, target, variable): + base_freqs=self.filter_state.freq_proper(self.filter_state.DEFAULT_FREQUENCIES) + filter_state._set_frequency_values(subdivide(base_freqs,variable)) + new_widget=SliderArraySub(filter_state) + w=new_widget.sizeHint().width() + return w-target + def searcher(initial,evaluator): + i=initial + def d(e): return 1 if e>=0 else -1 + error=evaluator(i) + old_direction=d(error) + i-=old_direction + while True: + error=evaluator(i) + direction=d(error) + if direction!=old_direction: + k=i-1 + #while direction<0 and error!=0: + # k-=1 + # error=evaluator(i) + # direction=d(error) + return k, evaluator(k) + i-=direction + old_direction=direction + searcher(i,partial(evaluate,self.filter_state,t_w)) + self.set_sub_array(SliderArraySub(self.filter_state)) + self.inhibit_resize-=1 + +class SliderArraySub(QtGui.QWidget): + def __init__(self,filter_state,parent=None): + super(SliderArraySub,self).__init__(parent) + self.filter_state=filter_state + self.setLayout(QtGui.QGridLayout()) + self.slider=[None]*len(self.filter_state.frequencies) + self.label=[None]*len(self.slider) + #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') + #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + qt=QtCore.Qt + #self.layout().setHorizontalSpacing(1) + def add_slider(slider,label, c): + self.layout().addWidget(slider,0,c,qt.AlignHCenter) + self.layout().addWidget(label,1,c,qt.AlignHCenter) + self.layout().setColumnMinimumWidth(c,max(label.sizeHint().width(),slider.sizeHint().width())) + def create_slider(slider_label): + slider=QtGui.QSlider(QtCore.Qt.Vertical,self) + label=SliderLabel(slider_label,filter_state,self) + slider.setRange(-1000,2000) + slider.setSingleStep(1) + return (slider,label) + self.preamp_slider,self.preamp_label=create_slider('Preamp') + add_slider(self.preamp_slider,self.preamp_label,0) + for i,hz in enumerate(self.filter_state.frequencies): + slider,label=create_slider(self.hz2label(hz)) + self.slider[i]=slider + #slider.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('red',)) + self.label[i]=label + c=i+1 + add_slider(slider,label,i+1) + def hz2label(self, hz): + if hz==0: + label_text='DC' + elif hz==self.filter_state.sample_rate//2: + label_text='Coda' + else: + label_text=hz2str(hz) + return label_text + + def connect_signals(self): + def connect(writer,reader,slider,label): + slider.valueChanged.connect(writer) + self.filter_state.readFilter.connect(reader) + label_cb=partial(slider.setValue,0) + label.clicked.connect(label_cb) + return label_cb + + self.preamp_writer_cb=self.write_preamp + self.preamp_reader_cb=self.sync_preamp + self.preamp_label_cb=connect(self.preamp_writer_cb, + self.preamp_reader_cb, + self.preamp_slider, + self.preamp_label) + self.writer_callbacks=[None]*len(self.slider) + self.reader_callbacks=[None]*len(self.slider) + self.label_callbacks=[None]*len(self.label) + for i in range(len(self.slider)): + self.writer_callbacks[i]=partial(self.write_coefficient,i) + self.reader_callbacks[i]=partial(self.sync_coefficient,i) + self.label_callbacks[i]=connect(self.writer_callbacks[i], + self.reader_callbacks[i], + self.slider[i], + self.label[i]) + def disconnect_signals(self): + def disconnect(writer,reader,label_cb,slider,label): + slider.valueChanged.disconnect(writer) + self.filter_state.readFilter.disconnect(reader) + label.clicked.disconnect(label_cb) + disconnect(self.preamp_writer_cb, self.preamp_reader_cb, + self.preamp_label_cb, self.preamp_slider, self.preamp_label) + for i in range(len(self.slider)): + disconnect(self.writer_callbacks[i], + self.reader_callbacks[i], + self.label_callbacks[i], + self.slider[i], + self.label[i]) + + def write_preamp(self, v): + self.filter_state.preamp=self.slider2coef(v) + self.filter_state.seed() + def sync_preamp(self): + self.preamp_slider.blockSignals(True) + self.preamp_slider.setValue(self.coef2slider(self.filter_state.preamp)) + self.preamp_slider.blockSignals(False) + + + def write_coefficient(self,i,v): + self.filter_state.coefficients[i]=self.slider2coef(v)/math.sqrt(2.0) + self.filter_state.seed() + def sync_coefficient(self,i): + slider=self.slider[i] + slider.blockSignals(True) + slider.setValue(self.coef2slider(math.sqrt(2.0)*self.filter_state.coefficients[i])) + slider.blockSignals(False) + @staticmethod + def slider2coef(x): + return (1.0+(x/1000.0)) + @staticmethod + def coef2slider(x): + return int((x-1.0)*1000) +outline='border-width: 1px; border-style: solid; border-color: %s;' + +class SliderLabel(QtGui.QLabel): + clicked=QtCore.pyqtSignal() + def __init__(self,label_text,filter_state,parent=None): + super(SliderLabel,self).__init__(parent) + self.setStyleSheet('font-size: 7pt; font-family: monospace;') + self.setText(label_text) + self.setMinimumSize(self.sizeHint()) + def mouseDoubleClickEvent(self, event): + self.clicked.emit() + super(SliderLabel,self).mouseDoubleClickEvent(event) + +#until there are server side state savings, do it in the client but try and avoid +#simulaneous broadcasting situations +class FilterState(QtCore.QObject): + #DEFAULT_FREQUENCIES=map(float,[25,50,75,100,150,200,300,400,500,800,1e3,1.5e3,3e3,5e3,7e3,10e3,15e3,20e3]) + DEFAULT_FREQUENCIES=[31.75,63.5,125,250,500,1e3,2e3,4e3,8e3,16e3] + readFilter=QtCore.pyqtSignal() + def __init__(self,sink): + super(FilterState,self).__init__() + self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + self.sink=dbus.Interface(sink,dbus_interface=eq_iface) + self.sample_rate=self.get_eq_attr('SampleRate') + self.filter_rate=self.get_eq_attr('FilterSampleRate') + self.channels=self.get_eq_attr('NChannels') + self.channel=self.channels + self.set_frequency_values(self.DEFAULT_FREQUENCIES) + self.sync_timer=QtCore.QTimer() + self.sync_timer.setSingleShot(True) + self.sync_timer.timeout.connect(self.save_state) + + def get_eq_attr(self,attr): + return self.sink_props.Get(eq_iface,attr) + def freq_proper(self,xs): + return [0]+xs+[self.sample_rate//2] + def _set_frequency_values(self,freqs): + self.frequencies=freqs + #print 'base',self.frequencies + self.filter_frequencies=map(lambda x: int(round(x)), \ + self.translate_rates(self.filter_rate,self.sample_rate, + self.frequencies) \ + ) + self.coefficients=[0.0]*len(self.frequencies) + self.preamp=1.0 + def set_frequency_values(self,freqs): + self._set_frequency_values(self.freq_proper(freqs)) + @staticmethod + def translate_rates(dst,src,rates): + return list(map(lambda x: x*dst/src,rates)) + def seed(self): + self.sink.SeedFilter(self.channel,self.filter_frequencies,self.coefficients,self.preamp) + self.sync_timer.start(SYNC_TIMEOUT) + def readback(self): + coefs,preamp=self.sink.FilterAtPoints(self.channel,self.filter_frequencies) + self.coefficients=coefs + self.preamp=preamp + self.readFilter.emit() + def set_filter(self,preamp,coefs): + self.sink.SetFilter(self.channel,dbus.Array(coefs),self.preamp) + self.sync_timer.start(SYNC_TIMEOUT) + def save_state(self): + print 'saving state' + self.sink.SaveState() + def load_profile(self,profile): + self.sink.LoadProfile(self.channel,dbus.String(profile)) + self.sync_timer.start(SYNC_TIMEOUT) + def flush_state(self): + if self.sync_timer.isActive(): + self.sync_timer.stop() + self.save_state() + + +def safe_log(k,b): + i=0 + while k//b!=0: + i+=1 + k=k//b + return i +def hz2str(hz): + p=safe_log(hz,10.0) + if p<3: + return '%dHz' %(hz,) + elif hz%1000==0: + return '%dKHz' %(hz/(10.0**3),) + else: + return '%.1fKHz' %(hz/(10.0**3),) + +def subdivide(xs, t_points): + while len(xs) Date: Sat, 21 Nov 2009 00:02:33 +0100 Subject: freebsd: fix atomic ops implementations Stole from http://www.freebsd.org/cgi/cvsweb.cgi/ports/audio/pulseaudio/files/patch-src_pulsecore_atomic.h?rev=1.6 --- src/pulsecore/atomic.h | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 119c445b..51d08210 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -180,6 +180,110 @@ static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, v return r == old_p; } +#elif defined(__FreeBSD__) + +#include +#include +#include +#include + +#if __FreeBSD_version < 600000 +#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) +#define atomic_load_acq_64 atomic_load_acq_long +#endif +static inline u_int atomic_fetchadd_int(volatile u_int *p, u_int v) { + __asm __volatile( + " " __XSTRING(MPLOCKED) " " + " xaddl %0, %1 ; " + "# atomic_fetchadd_int" + : "+r" (v), + "=m" (*p) + : "m" (*p)); + + return (v); +} +#elif defined(__sparc64__) +#define atomic_load_acq_64 atomic_load_acq_long +#define atomic_fetchadd_int atomic_add_int +#elif defined(__ia64__) +#define atomic_load_acq_64 atomic_load_acq_long +static inline uint32_t +atomic_fetchadd_int(volatile uint32_t *p, uint32_t v) { + uint32_t value; + + do { + value = *p; + } while (!atomic_cmpset_32(p, value, value + v)); + return (value); +} +#endif +#endif + +typedef struct pa_atomic { + volatile unsigned long value; +} pa_atomic_t; + +#define PA_ATOMIC_INIT(v) { .value = (v) } + +static inline int pa_atomic_load(const pa_atomic_t *a) { + return (int) atomic_load_acq_int((unsigned int *) &a->value); +} + +static inline void pa_atomic_store(pa_atomic_t *a, int i) { + atomic_store_rel_int((unsigned int *) &a->value, i); +} + +static inline int pa_atomic_add(pa_atomic_t *a, int i) { + return atomic_fetchadd_int((unsigned int *) &a->value, i); +} + +static inline int pa_atomic_sub(pa_atomic_t *a, int i) { + return atomic_fetchadd_int((unsigned int *) &a->value, -(i)); +} + +static inline int pa_atomic_inc(pa_atomic_t *a) { + return atomic_fetchadd_int((unsigned int *) &a->value, 1); +} + +static inline int pa_atomic_dec(pa_atomic_t *a) { + return atomic_fetchadd_int((unsigned int *) &a->value, -1); +} + +static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { + return atomic_cmpset_int((unsigned int *) &a->value, old_i, new_i); +} + +typedef struct pa_atomic_ptr { + volatile unsigned long value; +} pa_atomic_ptr_t; + +#define PA_ATOMIC_PTR_INIT(v) { .value = (unsigned long) (v) } + +static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) { +#ifdef atomic_load_acq_64 + return (void*) atomic_load_acq_ptr((unsigned long *) &a->value); +#else + return (void*) atomic_load_acq_ptr((unsigned int *) &a->value); +#endif +} + +static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) { +#ifdef atomic_load_acq_64 + atomic_store_rel_ptr(&a->value, (unsigned long) p); +#else + atomic_store_rel_ptr((unsigned int *) &a->value, (unsigned int) p); +#endif +} + +static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) { +#ifdef atomic_load_acq_64 + return atomic_cmpset_ptr(&a->value, (unsigned long) old_p, (unsigned long) new_p); +#else + return atomic_cmpset_ptr((unsigned int *) &a->value, (unsigned int) old_p, (unsigned int) new_p); +#endif +} + #elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) #warn "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC." -- cgit From 77c6b696560f460e74af85d069863e8337e99d33 Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Fri, 20 Nov 2009 15:07:47 -0800 Subject: remove .py extension from qpaeq --- src/utils/qpaeq | 546 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/qpaeq.py | 546 ----------------------------------------------------- 2 files changed, 546 insertions(+), 546 deletions(-) create mode 100755 src/utils/qpaeq delete mode 100755 src/utils/qpaeq.py diff --git a/src/utils/qpaeq b/src/utils/qpaeq new file mode 100755 index 00000000..dca0701d --- /dev/null +++ b/src/utils/qpaeq @@ -0,0 +1,546 @@ +#!/usr/bin/env python +# qpaeq is a equalizer interface for pulseaudio's equalizer sinks +# Copyright (C) 2009 Jason Newton . + + +import os,math,sys +import PyQt4,sip +from PyQt4 import QtGui,QtCore +from functools import partial + +import dbus.mainloop.qt +import dbus + +import signal +signal.signal(signal.SIGINT, signal.SIG_DFL) +SYNC_TIMEOUT = 4*1000 + +CORE_PATH = "/org/pulseaudio/core1" +CORE_IFACE = "org.PulseAudio.Core1" +def connect(): + if 'PULSE_DBUS_SERVER' in os.environ: + address = os.environ['PULSE_DBUS_SERVER'] + else: + bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. + server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') + address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') + return dbus.connection.Connection(address) + + +#TODO: signals: sink Filter changed, sink reconfigured (window size) (sink iface) +#TODO: manager signals: new sink, removed sink, new profile, removed profile +#TODO: add support for changing of window_size 1000-fft_size (adv option) +#TODO: reconnect support loop 1 second trying to reconnect +#TODO: just resample the filters for profiles when loading to different sizes +#TODO: add preamp +prop_iface='org.freedesktop.DBus.Properties' +eq_iface='org.PulseAudio.Ext.Equalizing1.Equalizer' +device_iface='org.PulseAudio.Core1.Device' +class QPaeq(QtGui.QWidget): + manager_path='/org/pulseaudio/equalizing1' + manager_iface='org.PulseAudio.Ext.Equalizing1.Manager' + core_iface='org.PulseAudio.Core1' + core_path='/org/pulseaudio/core1' + def __init__(self): + QtGui.QWidget.__init__(self) + self.setWindowTitle('qpaeq') + self.slider_widget=None + self.sink_name=None + self.filter_state=None + + self.create_layout() + + self.set_connection() + self.connect_to_sink(self.sinks[0]) + self.set_callbacks() + self.setMinimumSize(self.sizeHint()) + + def create_layout(self): + self.main_layout=QtGui.QVBoxLayout() + self.setLayout(self.main_layout) + toprow_layout=QtGui.QHBoxLayout() + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + #sizePolicy.setHeightForWidth(self.profile_box.sizePolicy().hasHeightForWidth()) + + toprow_layout.addWidget(QtGui.QLabel('Sink')) + self.sink_box = QtGui.QComboBox() + self.sink_box.setSizePolicy(sizePolicy) + self.sink_box.setDuplicatesEnabled(False) + self.sink_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + #self.sink_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + toprow_layout.addWidget(self.sink_box) + + toprow_layout.addWidget(QtGui.QLabel('Channel')) + self.channel_box = QtGui.QComboBox() + self.channel_box.setSizePolicy(sizePolicy) + toprow_layout.addWidget(self.channel_box) + + toprow_layout.addWidget(QtGui.QLabel('Preset')) + self.profile_box = QtGui.QComboBox() + self.profile_box.setSizePolicy(sizePolicy) + self.profile_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + #self.profile_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + toprow_layout.addWidget(self.profile_box) + + large_icon_size=self.style().pixelMetric(QtGui.QStyle.PM_LargeIconSize) + large_icon_size=QtCore.QSize(large_icon_size,large_icon_size) + save_profile=QtGui.QToolButton() + save_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DriveFDIcon)) + save_profile.setIconSize(large_icon_size) + save_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + save_profile.clicked.connect(self.save_profile) + remove_profile=QtGui.QToolButton() + remove_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_TrashIcon)) + remove_profile.setIconSize(large_icon_size) + remove_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + remove_profile.clicked.connect(self.remove_profile) + toprow_layout.addWidget(save_profile) + toprow_layout.addWidget(remove_profile) + + reset_button = QtGui.QPushButton('Reset') + reset_button.clicked.connect(self.reset) + toprow_layout.addStretch() + toprow_layout.addWidget(reset_button) + self.layout().addLayout(toprow_layout) + + self.profile_box.activated.connect(self.load_profile) + self.channel_box.activated.connect(self.select_channel) + def connect_to_sink(self,name): + #TODO: clear slots for profile buttons + + #flush any pending saves for other sinks + if self.filter_state is not None: + self.filter_state.flush_state() + sink=self.connection.get_object(object_path=name) + self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + self.sink=dbus.Interface(sink,dbus_interface=eq_iface) + self.filter_state=FilterState(sink) + #sample_rate,filter_rate,channels,channel) + + self.channel_box.clear() + self.channel_box.addItem('All',self.filter_state.channels) + for i in xrange(self.filter_state.channels): + self.channel_box.addItem('%d' %(i+1,),i) + self.setMinimumSize(self.sizeHint()) + + self.set_slider_widget(SliderArray(self.filter_state)) + + self.sink_name=name + #set the signal listener for this sink + core=self._get_core() + #temporary hack until signal filtering works properly + core.ListenForSignal('',[dbus.ObjectPath(self.sink_name),dbus.ObjectPath(self.manager_path)]) + #for x in ['FilterChanged']: + # core.ListenForSignal("%s.%s" %(self.eq_iface,x),[dbus.ObjectPath(self.sink_name)]) + #core.ListenForSignal(self.eq_iface,[dbus.ObjectPath(self.sink_name)]) + self.sink.connect_to_signal('FilterChanged',self.read_filter) + + def set_slider_widget(self,widget): + layout=self.layout() + if self.slider_widget is not None: + i=layout.indexOf(self.slider_widget) + layout.removeWidget(self.slider_widget) + self.slider_widget.deleteLater() + layout.insertWidget(i,self.slider_widget) + else: + layout.addWidget(widget) + self.slider_widget=widget + self.read_filter() + def _get_core(self): + core_obj=self.connection.get_object(object_path=self.core_path) + core=dbus.Interface(core_obj,dbus_interface=self.core_iface) + return core + def sink_added(self,sink): + #TODO: preserve selected sink + self.update_sinks() + def sink_removed(self,sink): + #TODO: preserve selected sink, try connecting to backup otherwise + if sink==self.sink_name: + #connect to new sink? + pass + self.update_sinks() + def save_profile(self): + #popup dialog box for name + current=self.profile_box.currentIndex() + profile,ok=QtGui.QInputDialog.getItem(self,'Preset Name','Preset',self.profiles,current) + if not ok or profile=='': + return + if profile in self.profiles: + mbox=QtGui.QMessageBox(self) + mbox.setText('%s preset already exists'%(profile,)) + mbox.setInformativeText('Do you want to save over it?') + mbox.setStandardButtons(mbox.Save|mbox.Discard|mbox.Cancel) + mbox.setDefaultButton(mbox.Save) + ret=mbox.exec_() + if ret!=mbox.Save: + return + self.sink.SaveProfile(self.filter_state.channel,dbus.String(profile)) + if self.filter_state.channel==self.filter_state.channels: + for x in range(1,self.filter_state.channels): + self.sink.LoadProfile(x,dbus.String(profile)) + def remove_profile(self): + #find active profile name, remove it + profile=self.profile_box.currentText() + manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) + manager.RemoveProfile(dbus.String(profile)) + def load_profile(self,x): + profile=self.profile_box.itemText(x) + self.filter_state.load_profile(profile) + def select_channel(self,x): + self.filter_state.channel = self.channel_box.itemData(x).toPyObject() + self._set_profile_name() + self.filter_state.readback() + + #TODO: add back in preamp! + #print frequencies + #main_layout.addLayout(self.create_slider(partial(self.update_coefficient,0), + # 'Preamp')[0] + #) + def set_connection(self): + self.connection=connect() + self.manager_obj=self.connection.get_object(object_path=self.manager_path) + manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) + self.sinks=manager_props.Get(self.manager_iface,'EqualizedSinks') + def set_callbacks(self): + manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) + manager.connect_to_signal('ProfilesChanged',self.update_profiles) + manager.connect_to_signal('SinkAdded',self.sink_added) + manager.connect_to_signal('SinkRemoved',self.sink_removed) + #self._get_core().ListenForSignal(self.manager_iface,[]) + #self._get_core().ListenForSignal(self.manager_iface,[dbus.ObjectPath(self.manager_path)]) + #core=self._get_core() + #for x in ['ProfilesChanged','SinkAdded','SinkRemoved']: + # core.ListenForSignal("%s.%s" %(self.manager_iface,x),[dbus.ObjectPath(self.manager_path)]) + self.update_profiles() + self.update_sinks() + def update_profiles(self): + #print 'update profiles called!' + manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) + self.profiles=manager_props.Get(self.manager_iface,'Profiles') + self.profile_box.blockSignals(True) + self.profile_box.clear() + self.profile_box.addItems(self.profiles) + self.profile_box.blockSignals(False) + self._set_profile_name() + def update_sinks(self): + self.sink_box.blockSignals(True) + self.sink_box.clear() + for x in self.sinks: + sink=self.connection.get_object(object_path=x) + sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + simple_name=sink_props.Get(device_iface,'Name') + self.sink_box.addItem(simple_name,x) + self.sink_box.blockSignals(False) + self.sink_box.setMinimumSize(self.sink_box.sizeHint()) + def read_filter(self): + #print self.filter_frequencies + self.filter_state.readback() + def reset(self): + coefs=dbus.Array([1/math.sqrt(2.0)]*(self.filter_state.filter_rate//2+1)) + preamp=1.0 + self.filter_state.set_filter(preamp,coefs) + def _set_profile_name(self): + self.profile_box.blockSignals(True) + profile_name=self.sink.BaseProfile(self.filter_state.channel) + if profile_name is not None: + i=self.profile_box.findText(profile_name) + if i>=0: + self.profile_box.setCurrentIndex(i) + self.profile_box.blockSignals(False) + + +class SliderArray(QtGui.QWidget): + def __init__(self,filter_state,parent=None): + super(SliderArray,self).__init__(parent) + #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') + #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + self.filter_state=filter_state + self.setLayout(QtGui.QHBoxLayout()) + self.sub_array=None + self.set_sub_array(SliderArraySub(self.filter_state)) + self.inhibit_resize=0 + def set_sub_array(self,widget): + if self.sub_array is not None: + self.layout().removeWidget(self.sub_array) + self.sub_array.disconnect_signals() + self.sub_array.deleteLater() + self.sub_array=widget + self.layout().addWidget(self.sub_array) + self.sub_array.connect_signals() + self.filter_state.readback() + def resizeEvent(self,event): + super(SliderArray,self).resizeEvent(event) + if self.inhibit_resize==0: + self.inhibit_resize+=1 + #self.add_sliders_to_fit() + t=QtCore.QTimer(self) + t.setSingleShot(True) + t.setInterval(0) + t.timeout.connect(partial(self.add_sliders_to_fit,event)) + t.start() + def add_sliders_to_fit(self,event): + if event.oldSize().width()>0 and event.size().width()>0: + i=len(self.filter_state.frequencies)*int(round(float(event.size().width())/event.oldSize().width())) + else: + i=len(self.filter_state.frequencies) + + t_w=self.size().width() + def evaluate(filter_state, target, variable): + base_freqs=self.filter_state.freq_proper(self.filter_state.DEFAULT_FREQUENCIES) + filter_state._set_frequency_values(subdivide(base_freqs,variable)) + new_widget=SliderArraySub(filter_state) + w=new_widget.sizeHint().width() + return w-target + def searcher(initial,evaluator): + i=initial + def d(e): return 1 if e>=0 else -1 + error=evaluator(i) + old_direction=d(error) + i-=old_direction + while True: + error=evaluator(i) + direction=d(error) + if direction!=old_direction: + k=i-1 + #while direction<0 and error!=0: + # k-=1 + # error=evaluator(i) + # direction=d(error) + return k, evaluator(k) + i-=direction + old_direction=direction + searcher(i,partial(evaluate,self.filter_state,t_w)) + self.set_sub_array(SliderArraySub(self.filter_state)) + self.inhibit_resize-=1 + +class SliderArraySub(QtGui.QWidget): + def __init__(self,filter_state,parent=None): + super(SliderArraySub,self).__init__(parent) + self.filter_state=filter_state + self.setLayout(QtGui.QGridLayout()) + self.slider=[None]*len(self.filter_state.frequencies) + self.label=[None]*len(self.slider) + #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') + #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + qt=QtCore.Qt + #self.layout().setHorizontalSpacing(1) + def add_slider(slider,label, c): + self.layout().addWidget(slider,0,c,qt.AlignHCenter) + self.layout().addWidget(label,1,c,qt.AlignHCenter) + self.layout().setColumnMinimumWidth(c,max(label.sizeHint().width(),slider.sizeHint().width())) + def create_slider(slider_label): + slider=QtGui.QSlider(QtCore.Qt.Vertical,self) + label=SliderLabel(slider_label,filter_state,self) + slider.setRange(-1000,2000) + slider.setSingleStep(1) + return (slider,label) + self.preamp_slider,self.preamp_label=create_slider('Preamp') + add_slider(self.preamp_slider,self.preamp_label,0) + for i,hz in enumerate(self.filter_state.frequencies): + slider,label=create_slider(self.hz2label(hz)) + self.slider[i]=slider + #slider.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('red',)) + self.label[i]=label + c=i+1 + add_slider(slider,label,i+1) + def hz2label(self, hz): + if hz==0: + label_text='DC' + elif hz==self.filter_state.sample_rate//2: + label_text='Coda' + else: + label_text=hz2str(hz) + return label_text + + def connect_signals(self): + def connect(writer,reader,slider,label): + slider.valueChanged.connect(writer) + self.filter_state.readFilter.connect(reader) + label_cb=partial(slider.setValue,0) + label.clicked.connect(label_cb) + return label_cb + + self.preamp_writer_cb=self.write_preamp + self.preamp_reader_cb=self.sync_preamp + self.preamp_label_cb=connect(self.preamp_writer_cb, + self.preamp_reader_cb, + self.preamp_slider, + self.preamp_label) + self.writer_callbacks=[None]*len(self.slider) + self.reader_callbacks=[None]*len(self.slider) + self.label_callbacks=[None]*len(self.label) + for i in range(len(self.slider)): + self.writer_callbacks[i]=partial(self.write_coefficient,i) + self.reader_callbacks[i]=partial(self.sync_coefficient,i) + self.label_callbacks[i]=connect(self.writer_callbacks[i], + self.reader_callbacks[i], + self.slider[i], + self.label[i]) + def disconnect_signals(self): + def disconnect(writer,reader,label_cb,slider,label): + slider.valueChanged.disconnect(writer) + self.filter_state.readFilter.disconnect(reader) + label.clicked.disconnect(label_cb) + disconnect(self.preamp_writer_cb, self.preamp_reader_cb, + self.preamp_label_cb, self.preamp_slider, self.preamp_label) + for i in range(len(self.slider)): + disconnect(self.writer_callbacks[i], + self.reader_callbacks[i], + self.label_callbacks[i], + self.slider[i], + self.label[i]) + + def write_preamp(self, v): + self.filter_state.preamp=self.slider2coef(v) + self.filter_state.seed() + def sync_preamp(self): + self.preamp_slider.blockSignals(True) + self.preamp_slider.setValue(self.coef2slider(self.filter_state.preamp)) + self.preamp_slider.blockSignals(False) + + + def write_coefficient(self,i,v): + self.filter_state.coefficients[i]=self.slider2coef(v)/math.sqrt(2.0) + self.filter_state.seed() + def sync_coefficient(self,i): + slider=self.slider[i] + slider.blockSignals(True) + slider.setValue(self.coef2slider(math.sqrt(2.0)*self.filter_state.coefficients[i])) + slider.blockSignals(False) + @staticmethod + def slider2coef(x): + return (1.0+(x/1000.0)) + @staticmethod + def coef2slider(x): + return int((x-1.0)*1000) +outline='border-width: 1px; border-style: solid; border-color: %s;' + +class SliderLabel(QtGui.QLabel): + clicked=QtCore.pyqtSignal() + def __init__(self,label_text,filter_state,parent=None): + super(SliderLabel,self).__init__(parent) + self.setStyleSheet('font-size: 7pt; font-family: monospace;') + self.setText(label_text) + self.setMinimumSize(self.sizeHint()) + def mouseDoubleClickEvent(self, event): + self.clicked.emit() + super(SliderLabel,self).mouseDoubleClickEvent(event) + +#until there are server side state savings, do it in the client but try and avoid +#simulaneous broadcasting situations +class FilterState(QtCore.QObject): + #DEFAULT_FREQUENCIES=map(float,[25,50,75,100,150,200,300,400,500,800,1e3,1.5e3,3e3,5e3,7e3,10e3,15e3,20e3]) + DEFAULT_FREQUENCIES=[31.75,63.5,125,250,500,1e3,2e3,4e3,8e3,16e3] + readFilter=QtCore.pyqtSignal() + def __init__(self,sink): + super(FilterState,self).__init__() + self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) + self.sink=dbus.Interface(sink,dbus_interface=eq_iface) + self.sample_rate=self.get_eq_attr('SampleRate') + self.filter_rate=self.get_eq_attr('FilterSampleRate') + self.channels=self.get_eq_attr('NChannels') + self.channel=self.channels + self.set_frequency_values(self.DEFAULT_FREQUENCIES) + self.sync_timer=QtCore.QTimer() + self.sync_timer.setSingleShot(True) + self.sync_timer.timeout.connect(self.save_state) + + def get_eq_attr(self,attr): + return self.sink_props.Get(eq_iface,attr) + def freq_proper(self,xs): + return [0]+xs+[self.sample_rate//2] + def _set_frequency_values(self,freqs): + self.frequencies=freqs + #print 'base',self.frequencies + self.filter_frequencies=map(lambda x: int(round(x)), \ + self.translate_rates(self.filter_rate,self.sample_rate, + self.frequencies) \ + ) + self.coefficients=[0.0]*len(self.frequencies) + self.preamp=1.0 + def set_frequency_values(self,freqs): + self._set_frequency_values(self.freq_proper(freqs)) + @staticmethod + def translate_rates(dst,src,rates): + return list(map(lambda x: x*dst/src,rates)) + def seed(self): + self.sink.SeedFilter(self.channel,self.filter_frequencies,self.coefficients,self.preamp) + self.sync_timer.start(SYNC_TIMEOUT) + def readback(self): + coefs,preamp=self.sink.FilterAtPoints(self.channel,self.filter_frequencies) + self.coefficients=coefs + self.preamp=preamp + self.readFilter.emit() + def set_filter(self,preamp,coefs): + self.sink.SetFilter(self.channel,dbus.Array(coefs),self.preamp) + self.sync_timer.start(SYNC_TIMEOUT) + def save_state(self): + print 'saving state' + self.sink.SaveState() + def load_profile(self,profile): + self.sink.LoadProfile(self.channel,dbus.String(profile)) + self.sync_timer.start(SYNC_TIMEOUT) + def flush_state(self): + if self.sync_timer.isActive(): + self.sync_timer.stop() + self.save_state() + + +def safe_log(k,b): + i=0 + while k//b!=0: + i+=1 + k=k//b + return i +def hz2str(hz): + p=safe_log(hz,10.0) + if p<3: + return '%dHz' %(hz,) + elif hz%1000==0: + return '%dKHz' %(hz/(10.0**3),) + else: + return '%.1fKHz' %(hz/(10.0**3),) + +def subdivide(xs, t_points): + while len(xs). - - -import os,math,sys -import PyQt4,sip -from PyQt4 import QtGui,QtCore -from functools import partial - -import dbus.mainloop.qt -import dbus - -import signal -signal.signal(signal.SIGINT, signal.SIG_DFL) -SYNC_TIMEOUT = 4*1000 - -CORE_PATH = "/org/pulseaudio/core1" -CORE_IFACE = "org.PulseAudio.Core1" -def connect(): - if 'PULSE_DBUS_SERVER' in os.environ: - address = os.environ['PULSE_DBUS_SERVER'] - else: - bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. - server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') - address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') - return dbus.connection.Connection(address) - - -#TODO: signals: sink Filter changed, sink reconfigured (window size) (sink iface) -#TODO: manager signals: new sink, removed sink, new profile, removed profile -#TODO: add support for changing of window_size 1000-fft_size (adv option) -#TODO: reconnect support loop 1 second trying to reconnect -#TODO: just resample the filters for profiles when loading to different sizes -#TODO: add preamp -prop_iface='org.freedesktop.DBus.Properties' -eq_iface='org.PulseAudio.Ext.Equalizing1.Equalizer' -device_iface='org.PulseAudio.Core1.Device' -class QPaeq(QtGui.QWidget): - manager_path='/org/pulseaudio/equalizing1' - manager_iface='org.PulseAudio.Ext.Equalizing1.Manager' - core_iface='org.PulseAudio.Core1' - core_path='/org/pulseaudio/core1' - def __init__(self): - QtGui.QWidget.__init__(self) - self.setWindowTitle('qpaeq') - self.slider_widget=None - self.sink_name=None - self.filter_state=None - - self.create_layout() - - self.set_connection() - self.connect_to_sink(self.sinks[0]) - self.set_callbacks() - self.setMinimumSize(self.sizeHint()) - - def create_layout(self): - self.main_layout=QtGui.QVBoxLayout() - self.setLayout(self.main_layout) - toprow_layout=QtGui.QHBoxLayout() - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - #sizePolicy.setHeightForWidth(self.profile_box.sizePolicy().hasHeightForWidth()) - - toprow_layout.addWidget(QtGui.QLabel('Sink')) - self.sink_box = QtGui.QComboBox() - self.sink_box.setSizePolicy(sizePolicy) - self.sink_box.setDuplicatesEnabled(False) - self.sink_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) - #self.sink_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - toprow_layout.addWidget(self.sink_box) - - toprow_layout.addWidget(QtGui.QLabel('Channel')) - self.channel_box = QtGui.QComboBox() - self.channel_box.setSizePolicy(sizePolicy) - toprow_layout.addWidget(self.channel_box) - - toprow_layout.addWidget(QtGui.QLabel('Preset')) - self.profile_box = QtGui.QComboBox() - self.profile_box.setSizePolicy(sizePolicy) - self.profile_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) - #self.profile_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - toprow_layout.addWidget(self.profile_box) - - large_icon_size=self.style().pixelMetric(QtGui.QStyle.PM_LargeIconSize) - large_icon_size=QtCore.QSize(large_icon_size,large_icon_size) - save_profile=QtGui.QToolButton() - save_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DriveFDIcon)) - save_profile.setIconSize(large_icon_size) - save_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) - save_profile.clicked.connect(self.save_profile) - remove_profile=QtGui.QToolButton() - remove_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_TrashIcon)) - remove_profile.setIconSize(large_icon_size) - remove_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) - remove_profile.clicked.connect(self.remove_profile) - toprow_layout.addWidget(save_profile) - toprow_layout.addWidget(remove_profile) - - reset_button = QtGui.QPushButton('Reset') - reset_button.clicked.connect(self.reset) - toprow_layout.addStretch() - toprow_layout.addWidget(reset_button) - self.layout().addLayout(toprow_layout) - - self.profile_box.activated.connect(self.load_profile) - self.channel_box.activated.connect(self.select_channel) - def connect_to_sink(self,name): - #TODO: clear slots for profile buttons - - #flush any pending saves for other sinks - if self.filter_state is not None: - self.filter_state.flush_state() - sink=self.connection.get_object(object_path=name) - self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) - self.sink=dbus.Interface(sink,dbus_interface=eq_iface) - self.filter_state=FilterState(sink) - #sample_rate,filter_rate,channels,channel) - - self.channel_box.clear() - self.channel_box.addItem('All',self.filter_state.channels) - for i in xrange(self.filter_state.channels): - self.channel_box.addItem('%d' %(i+1,),i) - self.setMinimumSize(self.sizeHint()) - - self.set_slider_widget(SliderArray(self.filter_state)) - - self.sink_name=name - #set the signal listener for this sink - core=self._get_core() - #temporary hack until signal filtering works properly - core.ListenForSignal('',[dbus.ObjectPath(self.sink_name),dbus.ObjectPath(self.manager_path)]) - #for x in ['FilterChanged']: - # core.ListenForSignal("%s.%s" %(self.eq_iface,x),[dbus.ObjectPath(self.sink_name)]) - #core.ListenForSignal(self.eq_iface,[dbus.ObjectPath(self.sink_name)]) - self.sink.connect_to_signal('FilterChanged',self.read_filter) - - def set_slider_widget(self,widget): - layout=self.layout() - if self.slider_widget is not None: - i=layout.indexOf(self.slider_widget) - layout.removeWidget(self.slider_widget) - self.slider_widget.deleteLater() - layout.insertWidget(i,self.slider_widget) - else: - layout.addWidget(widget) - self.slider_widget=widget - self.read_filter() - def _get_core(self): - core_obj=self.connection.get_object(object_path=self.core_path) - core=dbus.Interface(core_obj,dbus_interface=self.core_iface) - return core - def sink_added(self,sink): - #TODO: preserve selected sink - self.update_sinks() - def sink_removed(self,sink): - #TODO: preserve selected sink, try connecting to backup otherwise - if sink==self.sink_name: - #connect to new sink? - pass - self.update_sinks() - def save_profile(self): - #popup dialog box for name - current=self.profile_box.currentIndex() - profile,ok=QtGui.QInputDialog.getItem(self,'Preset Name','Preset',self.profiles,current) - if not ok or profile=='': - return - if profile in self.profiles: - mbox=QtGui.QMessageBox(self) - mbox.setText('%s preset already exists'%(profile,)) - mbox.setInformativeText('Do you want to save over it?') - mbox.setStandardButtons(mbox.Save|mbox.Discard|mbox.Cancel) - mbox.setDefaultButton(mbox.Save) - ret=mbox.exec_() - if ret!=mbox.Save: - return - self.sink.SaveProfile(self.filter_state.channel,dbus.String(profile)) - if self.filter_state.channel==self.filter_state.channels: - for x in range(1,self.filter_state.channels): - self.sink.LoadProfile(x,dbus.String(profile)) - def remove_profile(self): - #find active profile name, remove it - profile=self.profile_box.currentText() - manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) - manager.RemoveProfile(dbus.String(profile)) - def load_profile(self,x): - profile=self.profile_box.itemText(x) - self.filter_state.load_profile(profile) - def select_channel(self,x): - self.filter_state.channel = self.channel_box.itemData(x).toPyObject() - self._set_profile_name() - self.filter_state.readback() - - #TODO: add back in preamp! - #print frequencies - #main_layout.addLayout(self.create_slider(partial(self.update_coefficient,0), - # 'Preamp')[0] - #) - def set_connection(self): - self.connection=connect() - self.manager_obj=self.connection.get_object(object_path=self.manager_path) - manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) - self.sinks=manager_props.Get(self.manager_iface,'EqualizedSinks') - def set_callbacks(self): - manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface) - manager.connect_to_signal('ProfilesChanged',self.update_profiles) - manager.connect_to_signal('SinkAdded',self.sink_added) - manager.connect_to_signal('SinkRemoved',self.sink_removed) - #self._get_core().ListenForSignal(self.manager_iface,[]) - #self._get_core().ListenForSignal(self.manager_iface,[dbus.ObjectPath(self.manager_path)]) - #core=self._get_core() - #for x in ['ProfilesChanged','SinkAdded','SinkRemoved']: - # core.ListenForSignal("%s.%s" %(self.manager_iface,x),[dbus.ObjectPath(self.manager_path)]) - self.update_profiles() - self.update_sinks() - def update_profiles(self): - #print 'update profiles called!' - manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface) - self.profiles=manager_props.Get(self.manager_iface,'Profiles') - self.profile_box.blockSignals(True) - self.profile_box.clear() - self.profile_box.addItems(self.profiles) - self.profile_box.blockSignals(False) - self._set_profile_name() - def update_sinks(self): - self.sink_box.blockSignals(True) - self.sink_box.clear() - for x in self.sinks: - sink=self.connection.get_object(object_path=x) - sink_props=dbus.Interface(sink,dbus_interface=prop_iface) - simple_name=sink_props.Get(device_iface,'Name') - self.sink_box.addItem(simple_name,x) - self.sink_box.blockSignals(False) - self.sink_box.setMinimumSize(self.sink_box.sizeHint()) - def read_filter(self): - #print self.filter_frequencies - self.filter_state.readback() - def reset(self): - coefs=dbus.Array([1/math.sqrt(2.0)]*(self.filter_state.filter_rate//2+1)) - preamp=1.0 - self.filter_state.set_filter(preamp,coefs) - def _set_profile_name(self): - self.profile_box.blockSignals(True) - profile_name=self.sink.BaseProfile(self.filter_state.channel) - if profile_name is not None: - i=self.profile_box.findText(profile_name) - if i>=0: - self.profile_box.setCurrentIndex(i) - self.profile_box.blockSignals(False) - - -class SliderArray(QtGui.QWidget): - def __init__(self,filter_state,parent=None): - super(SliderArray,self).__init__(parent) - #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') - #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) - self.filter_state=filter_state - self.setLayout(QtGui.QHBoxLayout()) - self.sub_array=None - self.set_sub_array(SliderArraySub(self.filter_state)) - self.inhibit_resize=0 - def set_sub_array(self,widget): - if self.sub_array is not None: - self.layout().removeWidget(self.sub_array) - self.sub_array.disconnect_signals() - self.sub_array.deleteLater() - self.sub_array=widget - self.layout().addWidget(self.sub_array) - self.sub_array.connect_signals() - self.filter_state.readback() - def resizeEvent(self,event): - super(SliderArray,self).resizeEvent(event) - if self.inhibit_resize==0: - self.inhibit_resize+=1 - #self.add_sliders_to_fit() - t=QtCore.QTimer(self) - t.setSingleShot(True) - t.setInterval(0) - t.timeout.connect(partial(self.add_sliders_to_fit,event)) - t.start() - def add_sliders_to_fit(self,event): - if event.oldSize().width()>0 and event.size().width()>0: - i=len(self.filter_state.frequencies)*int(round(float(event.size().width())/event.oldSize().width())) - else: - i=len(self.filter_state.frequencies) - - t_w=self.size().width() - def evaluate(filter_state, target, variable): - base_freqs=self.filter_state.freq_proper(self.filter_state.DEFAULT_FREQUENCIES) - filter_state._set_frequency_values(subdivide(base_freqs,variable)) - new_widget=SliderArraySub(filter_state) - w=new_widget.sizeHint().width() - return w-target - def searcher(initial,evaluator): - i=initial - def d(e): return 1 if e>=0 else -1 - error=evaluator(i) - old_direction=d(error) - i-=old_direction - while True: - error=evaluator(i) - direction=d(error) - if direction!=old_direction: - k=i-1 - #while direction<0 and error!=0: - # k-=1 - # error=evaluator(i) - # direction=d(error) - return k, evaluator(k) - i-=direction - old_direction=direction - searcher(i,partial(evaluate,self.filter_state,t_w)) - self.set_sub_array(SliderArraySub(self.filter_state)) - self.inhibit_resize-=1 - -class SliderArraySub(QtGui.QWidget): - def __init__(self,filter_state,parent=None): - super(SliderArraySub,self).__init__(parent) - self.filter_state=filter_state - self.setLayout(QtGui.QGridLayout()) - self.slider=[None]*len(self.filter_state.frequencies) - self.label=[None]*len(self.slider) - #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') - #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) - qt=QtCore.Qt - #self.layout().setHorizontalSpacing(1) - def add_slider(slider,label, c): - self.layout().addWidget(slider,0,c,qt.AlignHCenter) - self.layout().addWidget(label,1,c,qt.AlignHCenter) - self.layout().setColumnMinimumWidth(c,max(label.sizeHint().width(),slider.sizeHint().width())) - def create_slider(slider_label): - slider=QtGui.QSlider(QtCore.Qt.Vertical,self) - label=SliderLabel(slider_label,filter_state,self) - slider.setRange(-1000,2000) - slider.setSingleStep(1) - return (slider,label) - self.preamp_slider,self.preamp_label=create_slider('Preamp') - add_slider(self.preamp_slider,self.preamp_label,0) - for i,hz in enumerate(self.filter_state.frequencies): - slider,label=create_slider(self.hz2label(hz)) - self.slider[i]=slider - #slider.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('red',)) - self.label[i]=label - c=i+1 - add_slider(slider,label,i+1) - def hz2label(self, hz): - if hz==0: - label_text='DC' - elif hz==self.filter_state.sample_rate//2: - label_text='Coda' - else: - label_text=hz2str(hz) - return label_text - - def connect_signals(self): - def connect(writer,reader,slider,label): - slider.valueChanged.connect(writer) - self.filter_state.readFilter.connect(reader) - label_cb=partial(slider.setValue,0) - label.clicked.connect(label_cb) - return label_cb - - self.preamp_writer_cb=self.write_preamp - self.preamp_reader_cb=self.sync_preamp - self.preamp_label_cb=connect(self.preamp_writer_cb, - self.preamp_reader_cb, - self.preamp_slider, - self.preamp_label) - self.writer_callbacks=[None]*len(self.slider) - self.reader_callbacks=[None]*len(self.slider) - self.label_callbacks=[None]*len(self.label) - for i in range(len(self.slider)): - self.writer_callbacks[i]=partial(self.write_coefficient,i) - self.reader_callbacks[i]=partial(self.sync_coefficient,i) - self.label_callbacks[i]=connect(self.writer_callbacks[i], - self.reader_callbacks[i], - self.slider[i], - self.label[i]) - def disconnect_signals(self): - def disconnect(writer,reader,label_cb,slider,label): - slider.valueChanged.disconnect(writer) - self.filter_state.readFilter.disconnect(reader) - label.clicked.disconnect(label_cb) - disconnect(self.preamp_writer_cb, self.preamp_reader_cb, - self.preamp_label_cb, self.preamp_slider, self.preamp_label) - for i in range(len(self.slider)): - disconnect(self.writer_callbacks[i], - self.reader_callbacks[i], - self.label_callbacks[i], - self.slider[i], - self.label[i]) - - def write_preamp(self, v): - self.filter_state.preamp=self.slider2coef(v) - self.filter_state.seed() - def sync_preamp(self): - self.preamp_slider.blockSignals(True) - self.preamp_slider.setValue(self.coef2slider(self.filter_state.preamp)) - self.preamp_slider.blockSignals(False) - - - def write_coefficient(self,i,v): - self.filter_state.coefficients[i]=self.slider2coef(v)/math.sqrt(2.0) - self.filter_state.seed() - def sync_coefficient(self,i): - slider=self.slider[i] - slider.blockSignals(True) - slider.setValue(self.coef2slider(math.sqrt(2.0)*self.filter_state.coefficients[i])) - slider.blockSignals(False) - @staticmethod - def slider2coef(x): - return (1.0+(x/1000.0)) - @staticmethod - def coef2slider(x): - return int((x-1.0)*1000) -outline='border-width: 1px; border-style: solid; border-color: %s;' - -class SliderLabel(QtGui.QLabel): - clicked=QtCore.pyqtSignal() - def __init__(self,label_text,filter_state,parent=None): - super(SliderLabel,self).__init__(parent) - self.setStyleSheet('font-size: 7pt; font-family: monospace;') - self.setText(label_text) - self.setMinimumSize(self.sizeHint()) - def mouseDoubleClickEvent(self, event): - self.clicked.emit() - super(SliderLabel,self).mouseDoubleClickEvent(event) - -#until there are server side state savings, do it in the client but try and avoid -#simulaneous broadcasting situations -class FilterState(QtCore.QObject): - #DEFAULT_FREQUENCIES=map(float,[25,50,75,100,150,200,300,400,500,800,1e3,1.5e3,3e3,5e3,7e3,10e3,15e3,20e3]) - DEFAULT_FREQUENCIES=[31.75,63.5,125,250,500,1e3,2e3,4e3,8e3,16e3] - readFilter=QtCore.pyqtSignal() - def __init__(self,sink): - super(FilterState,self).__init__() - self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface) - self.sink=dbus.Interface(sink,dbus_interface=eq_iface) - self.sample_rate=self.get_eq_attr('SampleRate') - self.filter_rate=self.get_eq_attr('FilterSampleRate') - self.channels=self.get_eq_attr('NChannels') - self.channel=self.channels - self.set_frequency_values(self.DEFAULT_FREQUENCIES) - self.sync_timer=QtCore.QTimer() - self.sync_timer.setSingleShot(True) - self.sync_timer.timeout.connect(self.save_state) - - def get_eq_attr(self,attr): - return self.sink_props.Get(eq_iface,attr) - def freq_proper(self,xs): - return [0]+xs+[self.sample_rate//2] - def _set_frequency_values(self,freqs): - self.frequencies=freqs - #print 'base',self.frequencies - self.filter_frequencies=map(lambda x: int(round(x)), \ - self.translate_rates(self.filter_rate,self.sample_rate, - self.frequencies) \ - ) - self.coefficients=[0.0]*len(self.frequencies) - self.preamp=1.0 - def set_frequency_values(self,freqs): - self._set_frequency_values(self.freq_proper(freqs)) - @staticmethod - def translate_rates(dst,src,rates): - return list(map(lambda x: x*dst/src,rates)) - def seed(self): - self.sink.SeedFilter(self.channel,self.filter_frequencies,self.coefficients,self.preamp) - self.sync_timer.start(SYNC_TIMEOUT) - def readback(self): - coefs,preamp=self.sink.FilterAtPoints(self.channel,self.filter_frequencies) - self.coefficients=coefs - self.preamp=preamp - self.readFilter.emit() - def set_filter(self,preamp,coefs): - self.sink.SetFilter(self.channel,dbus.Array(coefs),self.preamp) - self.sync_timer.start(SYNC_TIMEOUT) - def save_state(self): - print 'saving state' - self.sink.SaveState() - def load_profile(self,profile): - self.sink.LoadProfile(self.channel,dbus.String(profile)) - self.sync_timer.start(SYNC_TIMEOUT) - def flush_state(self): - if self.sync_timer.isActive(): - self.sync_timer.stop() - self.save_state() - - -def safe_log(k,b): - i=0 - while k//b!=0: - i+=1 - k=k//b - return i -def hz2str(hz): - p=safe_log(hz,10.0) - if p<3: - return '%dHz' %(hz,) - elif hz%1000==0: - return '%dKHz' %(hz/(10.0**3),) - else: - return '%.1fKHz' %(hz/(10.0**3),) - -def subdivide(xs, t_points): - while len(xs) Date: Sat, 21 Nov 2009 00:17:33 +0100 Subject: Simplify handling of NetBSD atomic ops discovery. Instead of having a parameter to enable/disable them (which was also ignored by the source code side), simply identify NetBSD 5 (when the atomic ops were implemented the first time) in a $host switch and ignore checking for libatomic_ops. --- configure.ac | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/configure.ac b/configure.ac index fdc66625..7c527663 100644 --- a/configure.ac +++ b/configure.ac @@ -166,27 +166,12 @@ AC_ARG_ENABLE([atomic-arm-memory-barrier], esac ],) -AC_ARG_ENABLE([netbsd-atomic-ops], - AS_HELP_STRING([--enable-netbsd-atomic-ops],[Use the native NetBSD atomic_ops implementation]), - [ - case "${enableval}" in - yes) atomic_netbsd_helpers=yes ;; - no) atomic_netbsd_helpers=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-netbsd-atomic-ops) ;; - esac - ], - [atomic_netbsd_helpers=auto]) - AC_MSG_CHECKING([target operating system]) case $host in *-*-linux*) AC_MSG_RESULT([linux]) pulse_target_os=linux ;; - *-*-netbsd*) - AC_MSG_RESULT([netbsd]) - pulse_target_os=netbsd - ;; *) AC_MSG_RESULT([unknown]) pulse_target_os=unknown @@ -210,7 +195,7 @@ if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then else # HW specific atomic ops stuff AC_MSG_CHECKING([architecture for native atomic operations]) - case $host_cpu in + case $host in arm*) AC_MSG_RESULT([arm]) AC_MSG_CHECKING([whether we can use Linux kernel helpers]) @@ -246,14 +231,12 @@ else ]) fi ;; + *-netbsdelf5*) + AC_MSG_RESULT([yes]) + need_libatomic_ops=no + ;; *) - if test "x$pulse_target_os" = "xnetbsd" && test "x$atomic_netbsd_helpers" = "xyes"; then - AC_MSG_RESULT([yes]) - AC_DEFINE_UNQUOTED(NETBSD_ATOMIC_OPS, 1, [netbsd implementation]) - need_libatomic_ops=no - else - AC_MSG_RESULT([unknown]) - fi + AC_MSG_RESULT([unknown]) ;; esac fi -- cgit From 2caf59d49f9879831f93a181dc9c03841287cdd2 Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Sat, 21 Nov 2009 00:27:35 +0100 Subject: Since now we have FreeBSD atomic operations, don't require libatomic_ops. This lets the original configure script to pass on FreeBSD. --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index 7c527663..dfbd9bc0 100644 --- a/configure.ac +++ b/configure.ac @@ -235,6 +235,10 @@ else AC_MSG_RESULT([yes]) need_libatomic_ops=no ;; + *-freebsd*) + AC_MSG_RESULT([yes]) + need_libatomic_ops=no + ;; *) AC_MSG_RESULT([unknown]) ;; -- cgit From d963998676397e14cfd0fa04e98cdca21abed4ef Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Sat, 21 Nov 2009 00:30:46 +0100 Subject: Rename all the signal parameters and variables to something more explicit. Without this change, on FreeBSD you'll be bothered by tons of warnings about overshadowing signal(2). --- src/modules/dbus/iface-card.c | 30 ++-- src/modules/dbus/iface-client.c | 16 +- src/modules/dbus/iface-core.c | 272 ++++++++++++++++---------------- src/modules/dbus/iface-device.c | 72 ++++----- src/modules/dbus/iface-module.c | 16 +- src/modules/dbus/iface-sample.c | 16 +- src/modules/dbus/iface-stream.c | 100 ++++++------ src/modules/dbus/module-dbus-protocol.c | 14 +- src/modules/module-stream-restore.c | 50 +++--- src/pulsecore/protocol-dbus.c | 32 ++-- 10 files changed, 309 insertions(+), 309 deletions(-) diff --git a/src/modules/dbus/iface-card.c b/src/modules/dbus/iface-card.c index 1714df36..d99c8b95 100644 --- a/src/modules/dbus/iface-card.c +++ b/src/modules/dbus/iface-card.c @@ -452,7 +452,7 @@ static void handle_get_profile_by_name(DBusConnection *conn, DBusMessage *msg, v static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_card *c = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(core); pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CARD); @@ -472,14 +472,14 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 c->active_profile = c->card->active_profile; object_path = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name)); - pa_assert_se(signal = dbus_message_new_signal(c->path, - PA_DBUSIFACE_CARD_INTERFACE, - signals[SIGNAL_ACTIVE_PROFILE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(c->path, + PA_DBUSIFACE_CARD_INTERFACE, + signals[SIGNAL_ACTIVE_PROFILE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } if (!pa_proplist_equal(c->proplist, c->card->proplist)) { @@ -487,15 +487,15 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_proplist_update(c->proplist, PA_UPDATE_SET, c->card->proplist); - pa_assert_se(signal = dbus_message_new_signal(c->path, - PA_DBUSIFACE_CARD_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(c->path, + PA_DBUSIFACE_CARD_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, c->proplist); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } diff --git a/src/modules/dbus/iface-client.c b/src/modules/dbus/iface-client.c index 546370f9..31924487 100644 --- a/src/modules/dbus/iface-client.c +++ b/src/modules/dbus/iface-client.c @@ -391,7 +391,7 @@ static void handle_remove_properties(DBusConnection *conn, DBusMessage *msg, voi static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_client *c = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(core); pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CLIENT); @@ -410,15 +410,15 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_proplist_update(c->proplist, PA_UPDATE_SET, c->client->proplist); - pa_assert_se(signal = dbus_message_new_signal(c->path, - PA_DBUSIFACE_CLIENT_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(c->path, + PA_DBUSIFACE_CLIENT_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, c->proplist); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 169e8e55..497b59b5 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1488,7 +1488,7 @@ static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata) static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_core *c = userdata; - const char *signal; + const char *signal_str; char **objects = NULL; int n_objects; @@ -1497,11 +1497,11 @@ static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, voi pa_assert(c); pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &signal, + DBUS_TYPE_STRING, &signal_str, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, DBUS_TYPE_INVALID)); - pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL, objects, n_objects); + pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL, objects, n_objects); pa_dbus_send_empty_reply(conn, msg); @@ -1510,15 +1510,15 @@ static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, voi static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_core *c = userdata; - const char *signal; + const char *signal_str; pa_assert(conn); pa_assert(msg); pa_assert(c); - pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &signal, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &signal_str, DBUS_TYPE_INVALID)); - pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL); + pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL); pa_dbus_send_empty_reply(conn, msg); } @@ -1531,7 +1531,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_dbusiface_sample *sample_iface = NULL; pa_dbusiface_module *module_iface = NULL; pa_dbusiface_client *client_iface = NULL; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; const char *object_path = NULL; pa_sink *new_fallback_sink = NULL; pa_source *new_fallback_source = NULL; @@ -1552,21 +1552,21 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 && (device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { object_path = pa_dbusiface_device_get_path(device_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } else if (!new_fallback_sink) { - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SINK_UNSET].name))); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UNSET].name))); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } @@ -1579,21 +1579,21 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 && (device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { object_path = pa_dbusiface_device_get_path(device_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } else if (!new_fallback_source) { - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SOURCE_UNSET].name))); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UNSET].name))); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } break; @@ -1612,10 +1612,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_CARD].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_CARD].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx)))) @@ -1623,10 +1623,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_CARD_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_CARD_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_card_free(card_iface); } @@ -1647,28 +1647,28 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_SINK].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SINK].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; if (c->fallback_sink && pa_streq(c->fallback_sink->name, sink->name)) { /* We have got default sink change event, but at that point * the D-Bus sink object wasn't created yet. Now that the * object is created, let's send the fallback sink change * signal. */ - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1678,10 +1678,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_SINK_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SINK_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device_iface); } @@ -1702,28 +1702,28 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_SOURCE].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SOURCE].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; if (c->fallback_source && pa_streq(c->fallback_source->name, source->name)) { /* We have got default source change event, but at that * point the D-Bus source object wasn't created yet. Now * that the object is created, let's send the fallback * source change signal. */ - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1733,10 +1733,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_SOURCE_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SOURCE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device_iface); } @@ -1756,10 +1756,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx)))) @@ -1767,10 +1767,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream_iface); } @@ -1790,10 +1790,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_RECORD_STREAM].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_RECORD_STREAM].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx)))) @@ -1801,10 +1801,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_RECORD_STREAM_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_RECORD_STREAM_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream_iface); } @@ -1824,10 +1824,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_SAMPLE].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SAMPLE].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx)))) @@ -1835,10 +1835,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_SAMPLE_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SAMPLE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_sample_free(sample_iface); } @@ -1858,10 +1858,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_MODULE].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_MODULE].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx)))) @@ -1869,10 +1869,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_MODULE_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_MODULE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_module_free(module_iface); } @@ -1892,10 +1892,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_CLIENT].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_CLIENT].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { if (!(client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx)))) @@ -1903,37 +1903,37 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client_iface); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_CLIENT_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_CLIENT_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_client_free(client_iface); } break; } - if (signal) { - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); + if (signal_msg) { + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } } static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data, void *slot_data) { pa_dbusiface_core *c = slot_data; const char *ext_name = call_data; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_NEW_EXTENSION].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_EXTENSION].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); return PA_HOOK_OK; } @@ -1941,18 +1941,18 @@ static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_data, void *slot_data) { pa_dbusiface_core *c = slot_data; const char *ext_name = call_data; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, - PA_DBUS_CORE_INTERFACE, - signals[SIGNAL_EXTENSION_REMOVED].name))); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_EXTENSION_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(c->dbus_protocol, signal); - dbus_message_unref(signal); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); return PA_HOOK_OK; } diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c index 3a747a44..bb91d71f 100644 --- a/src/modules/dbus/iface-device.c +++ b/src/modules/dbus/iface-device.c @@ -1063,7 +1063,7 @@ static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void * static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_device *d = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; const pa_cvolume *new_volume = NULL; pa_bool_t new_mute = FALSE; pa_sink_state_t new_sink_state = 0; @@ -1099,16 +1099,16 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t for (i = 0; i < d->volume.channels; ++i) volume[i] = d->volume.values[i]; - pa_assert_se(signal = dbus_message_new_signal(d->path, - PA_DBUSIFACE_DEVICE_INTERFACE, - signals[SIGNAL_VOLUME_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, + pa_assert_se(signal_msg = dbus_message_new_signal(d->path, + PA_DBUSIFACE_DEVICE_INTERFACE, + signals[SIGNAL_VOLUME_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, d->volume.channels, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(d->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } new_mute = (d->type == DEVICE_TYPE_SINK) ? pa_sink_get_mute(d->sink, FALSE) : pa_source_get_mute(d->source, FALSE); @@ -1116,14 +1116,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t if (d->mute != new_mute) { d->mute = new_mute; - pa_assert_se(signal = dbus_message_new_signal(d->path, - PA_DBUSIFACE_DEVICE_INTERFACE, - signals[SIGNAL_MUTE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_BOOLEAN, &d->mute, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(d->path, + PA_DBUSIFACE_DEVICE_INTERFACE, + signals[SIGNAL_MUTE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &d->mute, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(d->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } if (d->type == DEVICE_TYPE_SINK) @@ -1142,14 +1142,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t state = (d->type == DEVICE_TYPE_SINK) ? d->sink_state : d->source_state; - pa_assert_se(signal = dbus_message_new_signal(d->path, - PA_DBUSIFACE_DEVICE_INTERFACE, - signals[SIGNAL_STATE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(d->path, + PA_DBUSIFACE_DEVICE_INTERFACE, + signals[SIGNAL_STATE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(d->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } new_active_port = (d->type == DEVICE_TYPE_SINK) ? d->sink->active_port : d->source->active_port; @@ -1160,14 +1160,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t d->active_port = new_active_port; object_path = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name)); - pa_assert_se(signal = dbus_message_new_signal(d->path, - PA_DBUSIFACE_DEVICE_INTERFACE, - signals[SIGNAL_ACTIVE_PORT_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(d->path, + PA_DBUSIFACE_DEVICE_INTERFACE, + signals[SIGNAL_ACTIVE_PORT_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(d->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } new_proplist = (d->type == DEVICE_TYPE_SINK) ? d->sink->proplist : d->source->proplist; @@ -1177,15 +1177,15 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t pa_proplist_update(d->proplist, PA_UPDATE_SET, new_proplist); - pa_assert_se(signal = dbus_message_new_signal(d->path, - PA_DBUSIFACE_DEVICE_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(d->path, + PA_DBUSIFACE_DEVICE_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, d->proplist); - pa_dbus_protocol_send_signal(d->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } diff --git a/src/modules/dbus/iface-module.c b/src/modules/dbus/iface-module.c index e8aea50f..9973166c 100644 --- a/src/modules/dbus/iface-module.c +++ b/src/modules/dbus/iface-module.c @@ -268,7 +268,7 @@ static void handle_unload(DBusConnection *conn, DBusMessage *msg, void *userdata static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_module *m = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(core); pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_MODULE); @@ -287,15 +287,15 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_proplist_update(m->proplist, PA_UPDATE_SET, m->module->proplist); - pa_assert_se(signal = dbus_message_new_signal(m->path, - PA_DBUSIFACE_MODULE_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(m->path, + PA_DBUSIFACE_MODULE_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, m->proplist); - pa_dbus_protocol_send_signal(m->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(m->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c index b0542a60..c1fa193c 100644 --- a/src/modules/dbus/iface-sample.c +++ b/src/modules/dbus/iface-sample.c @@ -450,7 +450,7 @@ static void handle_remove(DBusConnection *conn, DBusMessage *msg, void *userdata static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_sample *s = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; pa_assert(c); pa_assert(s); @@ -468,15 +468,15 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t pa_proplist_update(s->proplist, PA_UPDATE_SET, s->sample->proplist); - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_SAMPLE_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_SAMPLE_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, s->proplist); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c index 04a45e6c..0255be4b 100644 --- a/src/modules/dbus/iface-stream.c +++ b/src/modules/dbus/iface-stream.c @@ -632,7 +632,7 @@ static void handle_kill(DBusConnection *conn, DBusMessage *msg, void *userdata) static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_stream *s = userdata; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; const char *new_device_path = NULL; uint32_t new_sample_rate = 0; pa_proplist *new_proplist = NULL; @@ -662,14 +662,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t new_device_path = pa_dbusiface_core_get_sink_path(s->core, new_sink); - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_DEVICE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_DEVICE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } else { pa_source *new_source = s->source_output->source; @@ -680,14 +680,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t new_device_path = pa_dbusiface_core_get_source_path(s->core, new_source); - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_DEVICE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_DEVICE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } @@ -696,14 +696,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t if (s->sample_rate != new_sample_rate) { s->sample_rate = new_sample_rate; - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_SAMPLE_RATE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_UINT32, &s->sample_rate, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_SAMPLE_RATE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &s->sample_rate, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } if (s->type == STREAM_TYPE_PLAYBACK) { @@ -721,16 +721,16 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t for (i = 0; i < s->volume.channels; ++i) volume[i] = s->volume.values[i]; - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_VOLUME_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_VOLUME_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, s->volume.channels, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } new_mute = pa_sink_input_get_mute(s->sink_input); @@ -738,14 +738,14 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t if (s->mute != new_mute) { s->mute = new_mute; - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_MUTE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_BOOLEAN, &s->mute, DBUS_TYPE_INVALID)); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_MUTE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &s->mute, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } @@ -756,21 +756,21 @@ static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t pa_proplist_update(s->proplist, PA_UPDATE_SET, new_proplist); - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_PROPERTY_LIST_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_dbus_append_proplist(&msg_iter, s->proplist); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); - signal = NULL; + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); + signal_msg = NULL; } } static pa_hook_result_t send_event_cb(void *hook_data, void *call_data, void *slot_data) { pa_dbusiface_stream *s = slot_data; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; DBusMessageIter msg_iter; const char *name = NULL; pa_proplist *property_list = NULL; @@ -796,15 +796,15 @@ static pa_hook_result_t send_event_cb(void *hook_data, void *call_data, void *sl property_list = data->data; } - pa_assert_se(signal = dbus_message_new_signal(s->path, - PA_DBUSIFACE_STREAM_INTERFACE, - signals[SIGNAL_STREAM_EVENT].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(s->path, + PA_DBUSIFACE_STREAM_INTERFACE, + signals[SIGNAL_STREAM_EVENT].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_assert_se(dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name)); pa_dbus_append_proplist(&msg_iter, property_list); - pa_dbus_protocol_send_signal(s->dbus_protocol, signal); - dbus_message_unref(signal); + pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); return PA_HOOK_OK; } diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c index 11064c33..acc6ca04 100644 --- a/src/modules/dbus/module-dbus-protocol.c +++ b/src/modules/dbus/module-dbus-protocol.c @@ -126,7 +126,7 @@ static void client_kill_cb(pa_client *c) { /* Called from pa_client_send_event(). */ static void client_send_event_cb(pa_client *c, const char *name, pa_proplist *data) { struct connection *conn = NULL; - DBusMessage *signal = NULL; + DBusMessage *signal_msg = NULL; DBusMessageIter msg_iter; pa_assert(c); @@ -136,15 +136,15 @@ static void client_send_event_cb(pa_client *c, const char *name, pa_proplist *da conn = c->userdata; - pa_assert_se(signal = dbus_message_new_signal(pa_dbusiface_core_get_client_path(conn->server->userdata->core_iface, c), - PA_DBUSIFACE_CLIENT_INTERFACE, - "ClientEvent")); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(pa_dbusiface_core_get_client_path(conn->server->userdata->core_iface, c), + PA_DBUSIFACE_CLIENT_INTERFACE, + "ClientEvent")); + dbus_message_iter_init_append(signal_msg, &msg_iter); pa_assert_se(dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name)); pa_dbus_append_proplist(&msg_iter, data); - pa_assert_se(dbus_connection_send(pa_dbus_wrap_connection_get(conn->wrap_conn), signal, NULL)); - dbus_message_unref(signal); + pa_assert_se(dbus_connection_send(pa_dbus_wrap_connection_get(conn->wrap_conn), signal_msg, NULL)); + dbus_message_unref(signal_msg); } /* Called by D-Bus at the authentication phase. */ diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 788f458b..02c312e3 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -433,29 +433,29 @@ static void append_volume_variant(DBusMessageIter *iter, struct entry *e) { } static void send_new_entry_signal(struct dbus_entry *entry) { - DBusMessage *signal; + DBusMessage *signal_msg; pa_assert(entry); - pa_assert_se(signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_NEW_ENTRY].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal); - dbus_message_unref(signal); + pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_NEW_ENTRY].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } static void send_entry_removed_signal(struct dbus_entry *entry) { - DBusMessage *signal; + DBusMessage *signal_msg; pa_assert(entry); - pa_assert_se(signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_ENTRY_REMOVED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal); - dbus_message_unref(signal); + pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_ENTRY_REMOVED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } static void send_device_updated_signal(struct dbus_entry *de, struct entry *e) { - DBusMessage *signal; + DBusMessage *signal_msg; const char *device; pa_assert(de); @@ -463,28 +463,28 @@ static void send_device_updated_signal(struct dbus_entry *de, struct entry *e) { device = e->device_valid ? e->device : ""; - pa_assert_se(signal = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_DEVICE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal); - dbus_message_unref(signal); + pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_DEVICE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } static void send_volume_updated_signal(struct dbus_entry *de, struct entry *e) { - DBusMessage *signal; + DBusMessage *signal_msg; DBusMessageIter msg_iter; pa_assert(de); pa_assert(e); - pa_assert_se(signal = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_VOLUME_UPDATED].name)); - dbus_message_iter_init_append(signal, &msg_iter); + pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_VOLUME_UPDATED].name)); + dbus_message_iter_init_append(signal_msg, &msg_iter); append_volume(&msg_iter, e); - pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal); - dbus_message_unref(signal); + pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } static void send_mute_updated_signal(struct dbus_entry *de, struct entry *e) { - DBusMessage *signal; + DBusMessage *signal_msg; dbus_bool_t muted; pa_assert(de); @@ -494,10 +494,10 @@ static void send_mute_updated_signal(struct dbus_entry *de, struct entry *e) { muted = e->muted; - pa_assert_se(signal = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_MUTE_UPDATED].name)); - pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_BOOLEAN, &muted, DBUS_TYPE_INVALID)); - pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal); - dbus_message_unref(signal); + pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_MUTE_UPDATED].name)); + pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &muted, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg); + dbus_message_unref(signal_msg); } static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) { diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c index 5c1127be..e427bb19 100644 --- a/src/pulsecore/protocol-dbus.c +++ b/src/pulsecore/protocol-dbus.c @@ -958,7 +958,7 @@ pa_client *pa_dbus_protocol_get_client(pa_dbus_protocol *p, DBusConnection *conn void pa_dbus_protocol_add_signal_listener( pa_dbus_protocol *p, DBusConnection *conn, - const char *signal, + const char *signal_name, char **objects, unsigned n_objects) { struct connection_entry *conn_entry; @@ -978,18 +978,18 @@ void pa_dbus_protocol_add_signal_listener( while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL))) pa_xfree(object_path); - if (signal) { + if (signal_name) { conn_entry->listening_for_all_signals = FALSE; /* Replace the old object list with a new one. */ - if ((object_set = pa_hashmap_remove(conn_entry->listening_signals, signal))) + if ((object_set = pa_hashmap_remove(conn_entry->listening_signals, signal_name))) pa_idxset_free(object_set, free_listened_object_name_cb, NULL); object_set = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); for (i = 0; i < n_objects; ++i) pa_idxset_put(object_set, pa_xstrdup(objects[i]), NULL); - pa_hashmap_put(conn_entry->listening_signals, signal, object_set); + pa_hashmap_put(conn_entry->listening_signals, signal_name, object_set); } else { conn_entry->listening_for_all_signals = TRUE; @@ -1004,7 +1004,7 @@ void pa_dbus_protocol_add_signal_listener( } } -void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection *conn, const char *signal) { +void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection *conn, const char *signal_name) { struct connection_entry *conn_entry; pa_idxset *object_set; @@ -1013,8 +1013,8 @@ void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection pa_assert_se((conn_entry = pa_hashmap_get(p->connections, conn))); - if (signal) { - if ((object_set = pa_hashmap_get(conn_entry->listening_signals, signal))) + if (signal_name) { + if ((object_set = pa_hashmap_get(conn_entry->listening_signals, signal_name))) pa_idxset_free(object_set, free_listened_object_name_cb, NULL); } else { @@ -1030,7 +1030,7 @@ void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection } } -void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal) { +void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal_name) { struct connection_entry *conn_entry; void *state = NULL; pa_idxset *object_set; @@ -1038,24 +1038,24 @@ void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal) { char *signal_string; pa_assert(p); - pa_assert(signal); - pa_assert(dbus_message_get_type(signal) == DBUS_MESSAGE_TYPE_SIGNAL); - pa_assert_se(dbus_message_get_interface(signal)); - pa_assert_se(dbus_message_get_member(signal)); + pa_assert(signal_name); + pa_assert(dbus_message_get_type(signal_name) == DBUS_MESSAGE_TYPE_SIGNAL); + pa_assert_se(dbus_message_get_interface(signal_name)); + pa_assert_se(dbus_message_get_member(signal_name)); - signal_string = pa_sprintf_malloc("%s.%s", dbus_message_get_interface(signal), dbus_message_get_member(signal)); + signal_string = pa_sprintf_malloc("%s.%s", dbus_message_get_interface(signal_name), dbus_message_get_member(signal_name)); PA_HASHMAP_FOREACH(conn_entry, p->connections, state) { if ((conn_entry->listening_for_all_signals /* Case 1: listening for all signals */ - && (pa_idxset_get_by_data(conn_entry->all_signals_objects, dbus_message_get_path(signal), NULL) + && (pa_idxset_get_by_data(conn_entry->all_signals_objects, dbus_message_get_path(signal_name), NULL) || pa_idxset_isempty(conn_entry->all_signals_objects))) || (!conn_entry->listening_for_all_signals /* Case 2: not listening for all signals */ && (object_set = pa_hashmap_get(conn_entry->listening_signals, signal_string)) - && (pa_idxset_get_by_data(object_set, dbus_message_get_path(signal), NULL) + && (pa_idxset_get_by_data(object_set, dbus_message_get_path(signal_name), NULL) || pa_idxset_isempty(object_set)))) { - pa_assert_se(signal_copy = dbus_message_copy(signal)); + pa_assert_se(signal_copy = dbus_message_copy(signal_name)); pa_assert_se(dbus_connection_send(conn_entry->connection, signal_copy, NULL)); dbus_message_unref(signal_copy); } -- cgit From 62278b4b94212c5ab2f3041cac8b68e6c2bd35fe Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Sat, 21 Nov 2009 00:47:44 +0100 Subject: Avoid using devname as a variable name. On FreeBSD, devname() is a system function, and was overshadowed. --- src/modules/module-device-manager.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index 3991043d..8d61ff4c 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -1032,27 +1032,27 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio if ((e = read_entry(u, name))) { uint32_t idx; - char *devname; + char *device_name; uint32_t found_index = PA_INVALID_INDEX; - if ((devname = get_name(name, "sink:"))) { + if ((device_name = get_name(name, "sink:"))) { pa_sink* s; PA_IDXSET_FOREACH(s, u->core->sinks, idx) { - if (strcmp(s->name, devname) == 0) { + if (strcmp(s->name, device_name) == 0) { found_index = s->index; break; } } - pa_xfree(devname); - } else if ((devname = get_name(name, "source:"))) { + pa_xfree(device_name); + } else if ((device_name = get_name(name, "source:"))) { pa_source* s; PA_IDXSET_FOREACH(s, u->core->sources, idx) { - if (strcmp(s->name, devname) == 0) { + if (strcmp(s->name, device_name) == 0) { found_index = s->index; break; } } - pa_xfree(devname); + pa_xfree(device_name); } pa_tagstruct_puts(reply, name); -- cgit From fe0b393f7ac2f50131d187cc31a74ced52c15bd1 Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Sat, 21 Nov 2009 00:53:00 +0100 Subject: Simplify Makefile.am handling of ALSA-related files. Instead of declaring extra variables for the ALSA profiles and PATHS, and using EXTRA_DIST for the udev rule, use the dist_ prefix when declaring them for conditional installation. This relies on the fact that automake *is* smart enough to know that there exist *no* conditional dist, and will always distribute all of them. --- src/Makefile.am | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index b45908b3..5db6b39c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,30 +109,6 @@ MODULE_LDFLAGS = -module -disable-static -avoid-version $(LDFLAGS_NOUNDEFINED) # Extra files # ################################### -ALSA_PROFILES = \ - modules/alsa/mixer/profile-sets/default.conf \ - modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \ - modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf - -ALSA_PATHS = \ - modules/alsa/mixer/paths/analog-input-aux.conf \ - modules/alsa/mixer/paths/analog-input.conf \ - modules/alsa/mixer/paths/analog-input.conf.common \ - modules/alsa/mixer/paths/analog-input-fm.conf \ - modules/alsa/mixer/paths/analog-input-linein.conf \ - modules/alsa/mixer/paths/analog-input-mic.conf \ - modules/alsa/mixer/paths/analog-input-mic.conf.common \ - modules/alsa/mixer/paths/analog-input-mic-line.conf \ - modules/alsa/mixer/paths/analog-input-tvtuner.conf \ - modules/alsa/mixer/paths/analog-input-video.conf \ - modules/alsa/mixer/paths/analog-output.conf \ - modules/alsa/mixer/paths/analog-output-speaker.conf \ - modules/alsa/mixer/paths/analog-output.conf.common \ - modules/alsa/mixer/paths/analog-output-headphones.conf \ - modules/alsa/mixer/paths/analog-output-headphones-2.conf \ - modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \ - modules/alsa/mixer/paths/analog-output-mono.conf - EXTRA_DIST = \ pulse/client.conf.in \ pulse/version.h.in \ @@ -149,10 +125,7 @@ EXTRA_DIST = \ daemon/pulseaudio.desktop.in \ daemon/pulseaudio-kde.desktop.in \ map-file \ - daemon/pulseaudio-system.conf \ - modules/alsa/mixer/profile-sets/90-pulseaudio.rules \ - ${ALSA_PROFILES} \ - ${ALSA_PATHS} + daemon/pulseaudio-system.conf pulseconf_DATA = \ default.pa \ @@ -1094,14 +1067,34 @@ modlibexec_LTLIBRARIES += \ module-alsa-source.la \ module-alsa-card.la -alsaprofilesets_DATA = ${ALSA_PROFILES} +dist_alsaprofilesets_DATA = \ + modules/alsa/mixer/profile-sets/default.conf \ + modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \ + modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf if HAVE_UDEV -udevrules_DATA = \ +dist_udevrules_DATA = \ modules/alsa/mixer/profile-sets/90-pulseaudio.rules endif -alsapaths_DATA = ${ALSA_PATHS} +dist_alsapaths_DATA = \ + modules/alsa/mixer/paths/analog-input-aux.conf \ + modules/alsa/mixer/paths/analog-input.conf \ + modules/alsa/mixer/paths/analog-input.conf.common \ + modules/alsa/mixer/paths/analog-input-fm.conf \ + modules/alsa/mixer/paths/analog-input-linein.conf \ + modules/alsa/mixer/paths/analog-input-mic.conf \ + modules/alsa/mixer/paths/analog-input-mic.conf.common \ + modules/alsa/mixer/paths/analog-input-mic-line.conf \ + modules/alsa/mixer/paths/analog-input-tvtuner.conf \ + modules/alsa/mixer/paths/analog-input-video.conf \ + modules/alsa/mixer/paths/analog-output.conf \ + modules/alsa/mixer/paths/analog-output-speaker.conf \ + modules/alsa/mixer/paths/analog-output.conf.common \ + modules/alsa/mixer/paths/analog-output-headphones.conf \ + modules/alsa/mixer/paths/analog-output-headphones-2.conf \ + modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \ + modules/alsa/mixer/paths/analog-output-mono.conf endif -- cgit From f69e81f226e1f165bfe7d792b3c7895a55d43983 Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Fri, 20 Nov 2009 15:34:02 -0800 Subject: Makefile.am: added qpaeq to installed scripts --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index b45908b3..fc8803ce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1192,6 +1192,7 @@ endif if HAVE_FFTW modlibexec_LTLIBRARIES += \ module-equalizer-sink.la +bin_SCRIPTS += utils/qpaeq endif # These are generated by an M4 script -- cgit From 4eb65a0a46bd880faf620db3dff94f82f966bd61 Mon Sep 17 00:00:00 2001 From: Jason Newton Date: Fri, 20 Nov 2009 15:18:59 -0800 Subject: src/utils/qpaeq: added more friendly error messages to common errors --- src/utils/qpaeq | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/utils/qpaeq b/src/utils/qpaeq index dca0701d..a8a9fda8 100755 --- a/src/utils/qpaeq +++ b/src/utils/qpaeq @@ -17,12 +17,20 @@ import os,math,sys -import PyQt4,sip -from PyQt4 import QtGui,QtCore -from functools import partial +try: + import PyQt4,sip + from PyQt4 import QtGui,QtCore + import dbus.mainloop.qt + import dbus +except ImportError,e: + print 'There was an error importing need libraries' + print 'Make sure you haveqt4 and dbus forthon installed' + print 'The error that occured was' + print '\t%s' %(str(e)) + import sys + sys.exit(-1) -import dbus.mainloop.qt -import dbus +from functools import partial import signal signal.signal(signal.SIGINT, signal.SIG_DFL) @@ -31,13 +39,19 @@ SYNC_TIMEOUT = 4*1000 CORE_PATH = "/org/pulseaudio/core1" CORE_IFACE = "org.PulseAudio.Core1" def connect(): - if 'PULSE_DBUS_SERVER' in os.environ: - address = os.environ['PULSE_DBUS_SERVER'] - else: - bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. - server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') - address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') - return dbus.connection.Connection(address) + try: + if 'PULSE_DBUS_SERVER' in os.environ: + address = os.environ['PULSE_DBUS_SERVER'] + else: + bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. + server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') + address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') + return dbus.connection.Connection(address) + except Exception,e: + print 'There was an error connecting to pulseaudio, please make sure you have the pulseaudio dbus' + print 'and equalizer modules loaded, exiting...' + import sys + sys.exit(-1) #TODO: signals: sink Filter changed, sink reconfigured (window size) (sink iface) -- cgit From 5aa5c6c196b23acabca3e2c8a6724cb08485acdc Mon Sep 17 00:00:00 2001 From: Joe Marcus Clarke Date: Sat, 21 Nov 2009 01:13:35 +0100 Subject: freebsd: implement pa_get_binary_name Stolen from http://www.freebsd.org/cgi/cvsweb.cgi/ports/audio/pulseaudio/files/patch-src_pulse_util.c?rev=1.1 and fixed for indentation. --- src/pulse/util.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pulse/util.c b/src/pulse/util.c index 9440f5de..ca766dab 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -189,7 +189,18 @@ char *pa_get_binary_name(char *s, size_t l) { return s; } } +#endif +#ifdef __FreeBSD__ + { + char *rp; + + if ((rp = pa_readlink("/proc/curproc/file"))) { + pa_strlcpy(s, pa_path_get_filename(rp), l); + pa_xfree(rp); + return s; + } + } #endif #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME) -- cgit