1 --- a/src/pulsecore/sink-input.c 2016-04-12 16:50:41.311964935 +0200
2 +++ b/src/pulsecore/sink-input.c 2016-04-12 17:22:40.420961732 +0200
7 + if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
8 + pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED, data->sample_spec.channels);
10 + pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_NORM, data->sample_spec.channels);
12 i->thread_info.state = i->state;
13 i->thread_info.attached = false;
14 pa_atomic_store(&i->thread_info.drained, 1);
16 i->thread_info.playing_for = 0;
17 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
19 + i->thread_info.ramp = i->ramp;
21 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
22 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
25 while (tchunk.length > 0) {
27 bool nvfs = need_volume_factor_sink;
32 pa_memblock_ref(wchunk.memblock);
34 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
37 + /* check for possible volume ramp */
38 + if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
39 + pa_memchunk_make_writable(&wchunk, 0);
40 + pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
41 + } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
42 + pa_memchunk_make_writable(&wchunk, 0);
43 + pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
44 + pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
47 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
51 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
54 + /* check for possible volume ramp */
55 + if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
56 + pa_memchunk_make_writable(&wchunk, 0);
57 + pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
58 + } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
59 + pa_memchunk_make_writable(&wchunk, 0);
60 + pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
61 + pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
64 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
65 pa_memblock_unref(rchunk.memblock);
67 @@ -1338,6 +1367,31 @@
71 +/* Called from main thread */
72 +void pa_sink_input_set_volume_ramp(
74 + const pa_cvolume_ramp *ramp,
78 + pa_sink_input_assert_ref(i);
79 + pa_assert_ctl_context();
80 + pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
83 + pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
85 + pa_log_debug("setting volume ramp with target vol:%d and length:%ld",
86 + i->ramp.ramps[0].target,
87 + i->ramp.ramps[0].length);
90 + /* This tells the sink that volume ramp changed */
92 + pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
93 + NULL, 0, NULL) == 0);
96 /* Called from main context */
97 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
98 pa_sink_input_assert_ref(i);
99 @@ -1929,6 +1983,12 @@
103 + case PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP:
104 + /* we have ongoing ramp where we take current start values */
105 + pa_cvolume_ramp_start_from(&i->thread_info.ramp, &i->ramp);
106 + i->thread_info.ramp = i->ramp;
109 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
110 if (i->thread_info.muted != i->muted) {
111 i->thread_info.muted = i->muted;
112 --- a/src/pulsecore/sink-input.h 2016-04-12 16:50:46.712964926 +0200
113 +++ b/src/pulsecore/sink-input.h 2016-04-12 17:30:24.289960958 +0200
115 PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
116 PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
117 PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
118 - PA_SINK_INPUT_PASSTHROUGH = 2048
119 + PA_SINK_INPUT_PASSTHROUGH = 2048,
120 + PA_SINK_INPUT_START_RAMP_MUTED = 4096,
121 } pa_sink_input_flags_t;
123 struct pa_sink_input {
126 bool save_sink:1, save_volume:1, save_muted:1;
128 + /* for volume ramps */
129 + pa_cvolume_ramp_int ramp;
131 pa_resample_method_t requested_resample_method, actual_resample_method;
133 /* Returns the chunk of audio data and drops it from the
135 pa_usec_t requested_sink_latency;
137 pa_hashmap *direct_outputs;
139 + pa_cvolume_ramp_int ramp;
144 PA_SINK_INPUT_MESSAGE_SET_STATE,
145 PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,
146 PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,
147 + PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
148 PA_SINK_INPUT_MESSAGE_MAX
153 void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
155 +void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg, bool save);
157 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
159 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);