[pulseaudio-discuss] [PATCH 3/4] volume ramp: adding volume ramping to sink-input
Sangchul Lee
sangchul1011 at gmail.com
Thu Jul 7 18:57:52 UTC 2016
The original patch is
- https://review.tizen.org/git/?p=platform/upstream/pulseaudio.git;a=commit;h=98042248fd67ce0ab3807c5c472c0d5d8b0f99d3
- by Jaska Uimonen <jaska.uimonen <at> helsinki.fi>
Signed-off-by: Sangchul Lee <sc11.lee at samsung.com>
---
src/pulsecore/sink-input.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
src/pulsecore/sink-input.h | 12 +++++++++-
2 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index a7f6d55..50dc992 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -526,6 +526,11 @@ int pa_sink_input_new(
reset_callbacks(i);
i->userdata = NULL;
+ if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
+ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED,
data->sample_spec.channels);
+ else
+ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_NORM,
data->sample_spec.channels);
+
i->thread_info.state = i->state;
i->thread_info.attached = false;
pa_atomic_store(&i->thread_info.drained, 1);
@@ -542,6 +547,8 @@ int pa_sink_input_new(
i->thread_info.playing_for = 0;
i->thread_info.direct_outputs =
pa_hashmap_new(pa_idxset_trivial_hash_func,
pa_idxset_trivial_compare_func);
+ i->thread_info.ramp = i->ramp;
+
pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i),
NULL) == 0);
@@ -921,6 +928,8 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
slength /* in sink bytes */, pa
while (tchunk.length > 0) {
pa_memchunk wchunk;
bool nvfs = need_volume_factor_sink;
+ pa_cvolume target;
+ pa_bool_t tmp;
wchunk = tchunk;
pa_memblock_ref(wchunk.memblock);
@@ -957,6 +966,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
slength /* in sink bytes */, pa
pa_volume_memchunk(&wchunk,
&i->sink->sample_spec, &i->volume_factor_sink);
}
+ /* check for possible volume ramp */
+ if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
+ pa_memchunk_make_writable(&wchunk, 0);
+ pa_volume_ramp_memchunk(&wchunk,
&i->sink->sample_spec, &(i->thread_info.ramp));
+ } else if ((tmp =
pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
+ pa_memchunk_make_writable(&wchunk, 0);
+ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
+ pa_volume_memchunk(&wchunk,
&i->sink->sample_spec, &target);
+ }
+
pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
} else {
pa_memchunk rchunk;
@@ -973,6 +992,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
slength /* in sink bytes */, pa
pa_volume_memchunk(&rchunk,
&i->sink->sample_spec, &i->volume_factor_sink);
}
+ /* check for possible volume ramp */
+ if (pa_cvolume_ramp_active(&(i->thread_info.ramp))) {
+ pa_memchunk_make_writable(&rchunk, 0);
+ pa_volume_ramp_memchunk(&rchunk,
&i->sink->sample_spec, &(i->thread_info.ramp));
+ } else if
(pa_cvolume_ramp_target_active(&(i->thread_info.ramp))) {
+ pa_memchunk_make_writable(&rchunk, 0);
+
pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
+ pa_volume_memchunk(&rchunk,
&i->sink->sample_spec, &target);
+ }
+
pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
pa_memblock_unref(rchunk.memblock);
}
@@ -1337,6 +1366,31 @@ int
pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key)
{
return 0;
}
+/* Called from main thread */
+void pa_sink_input_set_volume_ramp(
+ pa_sink_input *i,
+ const pa_cvolume_ramp *ramp,
+ pa_bool_t send_msg,
+ pa_bool_t save) {
+
+ pa_sink_input_assert_ref(i);
+ pa_assert_ctl_context();
+ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+ pa_assert(ramp);
+
+ pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
+
+ pa_log_debug("setting volume ramp with target vol:%d and length:%ld",
+ i->ramp.ramps[0].target,
+ i->ramp.ramps[0].length);
+
+
+ /* This tells the sink that volume ramp changed */
+ if (send_msg)
+ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq,
PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
+ NULL, 0, NULL) == 0);
+}
+
/* Called from main context */
static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
pa_sink_input_assert_ref(i);
@@ -2015,6 +2069,12 @@ int pa_sink_input_process_msg(pa_msgobject *o,
int code, void *userdata, int64_t
}
return 0;
+ case PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP:
+ /* we have ongoing ramp where we take current start values */
+ pa_cvolume_ramp_start_from(&i->thread_info.ramp, &i->ramp);
+ i->thread_info.ramp = i->ramp;
+ return 0;
+
case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
if (i->thread_info.muted != i->muted) {
i->thread_info.muted = i->muted;
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index 8bbee4e..85a0e54 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -32,6 +32,7 @@
#include <pulsecore/client.h>
#include <pulsecore/sink.h>
#include <pulsecore/core.h>
+#include <pulsecore/mix.h>
typedef enum pa_sink_input_state {
PA_SINK_INPUT_INIT, /*< The stream is not active yet,
because pa_sink_input_put() has not been called yet */
@@ -58,7 +59,8 @@ typedef enum pa_sink_input_flags {
PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
- PA_SINK_INPUT_PASSTHROUGH = 2048
+ PA_SINK_INPUT_PASSTHROUGH = 2048,
+ PA_SINK_INPUT_START_RAMP_MUTED = 4096,
} pa_sink_input_flags_t;
struct pa_sink_input {
@@ -121,6 +123,9 @@ struct pa_sink_input {
* this.*/
bool save_sink:1, save_volume:1, save_muted:1;
+ /* for volume ramps */
+ pa_cvolume_ramp_int ramp;
+
pa_resample_method_t requested_resample_method, actual_resample_method;
/* Returns the chunk of audio data and drops it from the
@@ -249,6 +254,8 @@ struct pa_sink_input {
pa_usec_t requested_sink_latency;
pa_hashmap *direct_outputs;
+
+ pa_cvolume_ramp_int ramp;
} thread_info;
void *userdata;
@@ -265,6 +272,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_VOLUME_RAMP,
PA_SINK_INPUT_MESSAGE_MAX
};
@@ -368,11 +376,13 @@ void pa_sink_input_set_volume(pa_sink_input *i,
const pa_cvolume *volume, bool s
void pa_sink_input_add_volume_factor(pa_sink_input *i, const char
*key, const pa_cvolume *volume_factor);
int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume
*volume, bool absolute);
+void pa_sink_input_set_volume_ramp(pa_sink_input *i, const
pa_cvolume_ramp *ramp, pa_bool_t send_msg, pa_bool_t save);
void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
void pa_sink_input_set_property(pa_sink_input *i, const char *key,
const char *value);
void pa_sink_input_set_property_arbitrary(pa_sink_input *i, const
char *key, const uint8_t *value, size_t nbytes);
+
void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t
mode, pa_proplist *p);
pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
--
2.7.4
More information about the pulseaudio-discuss
mailing list