From 1be39e4fa5b8f6a2d995593a4c1fd66eeafd6328 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 27 Jan 2009 03:05:40 +0100 Subject: allow samples to be played with 'default' (i.e. unspecified) volume. --- src/pulse/scache.c | 8 ++++++++ src/pulse/scache.h | 4 ++-- src/pulsecore/cli-text.c | 6 +++--- src/pulsecore/core-scache.c | 30 +++++++++++++++++++++--------- src/pulsecore/core-scache.h | 1 + src/pulsecore/protocol-native.c | 9 ++++++++- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/pulse/scache.c b/src/pulse/scache.c index fd3b9876..c96c42ad 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -188,6 +188,10 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char t = pa_tagstruct_command(c, PA_COMMAND_PLAY_SAMPLE, &tag); pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, dev); + + if (volume == (pa_volume_t) -1 && c->version < 15) + volume = PA_VOLUME_NORM; + pa_tagstruct_putu32(t, volume); pa_tagstruct_puts(t, name); @@ -225,6 +229,10 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na t = pa_tagstruct_command(c, PA_COMMAND_PLAY_SAMPLE, &tag); pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, dev); + + if (volume == (pa_volume_t) -1 && c->version < 15) + volume = PA_VOLUME_NORM; + pa_tagstruct_putu32(t, volume); pa_tagstruct_puts(t, name); pa_tagstruct_put_proplist(t, p); diff --git a/src/pulse/scache.h b/src/pulse/scache.h index 69e813c6..79fcfbc5 100644 --- a/src/pulse/scache.h +++ b/src/pulse/scache.h @@ -101,7 +101,7 @@ pa_operation* pa_context_play_sample( pa_context *c /**< Context */, const char *name /**< Name of the sample to play */, const char *dev /**< Sink to play this sample on */, - pa_volume_t volume /**< Volume to play this sample with */ , + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here (pa_volume_t) -1 which will leave the decision about the volume to the server side which is a good idea. */ , pa_context_success_cb_t cb /**< Call this function after successfully starting playback, or NULL */, void *userdata /**< Userdata to pass to the callback */); @@ -113,7 +113,7 @@ pa_operation* pa_context_play_sample_with_proplist( pa_context *c /**< Context */, const char *name /**< Name of the sample to play */, const char *dev /**< Sink to play this sample on */, - pa_volume_t volume /**< Volume to play this sample with */ , + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here (pa_volume_t) -1 which will leave the decision about the volume to the server side which is a good idea. */ , pa_proplist *proplist /**< Property list for this sound. The property list of the cached entry will be merged into this property list */, pa_context_play_sample_cb_t cb /**< Call this function after successfully starting playback, or NULL */, void *userdata /**< Userdata to pass to the callback */); diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index e87abe04..c74ca5df 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -588,9 +588,9 @@ char *pa_scache_list_to_string(pa_core *c) { cmn ? cmn : "", (long unsigned)(e->memchunk.memblock ? e->memchunk.length : 0), l, - pa_cvolume_snprint(cv, sizeof(cv), &e->volume), - pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &e->volume), - e->memchunk.memblock ? pa_cvolume_get_balance(&e->volume, &e->channel_map) : 0.0f, + e->volume_is_set ? pa_cvolume_snprint(cv, sizeof(cv), &e->volume) : "n/a", + e->volume_is_set ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &e->volume) : "n/a", + (e->memchunk.memblock && e->volume_is_set) ? pa_cvolume_get_balance(&e->volume, &e->channel_map) : 0.0f, pa_yes_no(e->lazy), e->filename ? e->filename : "n/a"); diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index 0f34c9d1..6d2ae932 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -137,6 +137,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { pa_sample_spec_init(&e->sample_spec); pa_channel_map_init(&e->channel_map); pa_cvolume_init(&e->volume); + e->volume_is_set = FALSE; pa_proplist_sets(e->proplist, PA_PROP_MEDIA_ROLE, "event"); @@ -175,6 +176,7 @@ int pa_scache_add_item( pa_sample_spec_init(&e->sample_spec); pa_channel_map_init(&e->channel_map); pa_cvolume_init(&e->volume); + e->volume_is_set = FALSE; if (ss) { e->sample_spec = *ss; @@ -308,6 +310,7 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t pa_scache_entry *e; pa_cvolume r; pa_proplist *merged; + pa_bool_t pass_volume; pa_assert(c); pa_assert(name); @@ -324,10 +327,12 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - if (pa_cvolume_valid(&e->volume)) - pa_cvolume_remap(&e->volume, &old_channel_map, &e->channel_map); - else - pa_cvolume_reset(&e->volume, e->sample_spec.channels); + if (e->volume_is_set) { + if (pa_cvolume_valid(&e->volume)) + pa_cvolume_remap(&e->volume, &old_channel_map, &e->channel_map); + else + pa_cvolume_reset(&e->volume, e->sample_spec.channels); + } } if (!e->memchunk.memblock) @@ -335,19 +340,26 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name); - pa_cvolume_set(&r, e->volume.channels, volume); - pa_sw_cvolume_multiply(&r, &r, &e->volume); + pass_volume = TRUE; - merged = pa_proplist_new(); + if (e->volume_is_set && volume != (pa_volume_t) -1) { + pa_cvolume_set(&r, e->sample_spec.channels, volume); + pa_sw_cvolume_multiply(&r, &r, &e->volume); + } else if (e->volume_is_set) + r = e->volume; + else if (volume != (pa_volume_t) -1) + pa_cvolume_set(&r, e->sample_spec.channels, volume); + else + pass_volume = FALSE; + merged = pa_proplist_new(); pa_proplist_setf(merged, PA_PROP_MEDIA_NAME, "Sample %s", name); - pa_proplist_update(merged, PA_UPDATE_REPLACE, e->proplist); if (p) pa_proplist_update(merged, PA_UPDATE_REPLACE, p); - if (pa_play_memchunk(sink, &e->sample_spec, &e->channel_map, &e->memchunk, &r, merged, sink_input_idx) < 0) { + if (pa_play_memchunk(sink, &e->sample_spec, &e->channel_map, &e->memchunk, pass_volume ? &r : NULL, merged, sink_input_idx) < 0) { pa_proplist_free(merged); return -1; } diff --git a/src/pulsecore/core-scache.h b/src/pulsecore/core-scache.h index ba65a964..a75f8aca 100644 --- a/src/pulsecore/core-scache.h +++ b/src/pulsecore/core-scache.h @@ -36,6 +36,7 @@ typedef struct pa_scache_entry { char *name; pa_cvolume volume; + pa_bool_t volume_is_set; pa_sample_spec sample_spec; pa_channel_map channel_map; pa_memchunk memchunk; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 7ddc010c..3896dff6 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2840,6 +2840,7 @@ static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct * static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_scache_entry *e) { pa_sample_spec fixed_ss; + pa_cvolume v; pa_assert(t); pa_assert(e); @@ -2851,7 +2852,13 @@ static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); - pa_tagstruct_put_cvolume(t, &e->volume); + + if (e->volume_is_set) + v = e->volume; + else + pa_cvolume_init(&v); + + pa_tagstruct_put_cvolume(t, &v); pa_tagstruct_put_usec(t, e->memchunk.memblock ? pa_bytes_to_usec(e->memchunk.length, &e->sample_spec) : 0); pa_tagstruct_put_sample_spec(t, &fixed_ss); pa_tagstruct_put_channel_map(t, &e->channel_map); -- cgit