1 From: Tanu Kaskinen <tanu.kaskinen@linux.intel.com>
2 Date: Mon, 7 Apr 2014 12:20:58 +0300
3 Subject: sink, source: Assign to reference_volume from only one place
5 Forcing all reference volume changes to go through
6 set_reference_volume_direct() makes it easier to check where the
7 reference volume is changed, and it also allows us to have only one
8 place where notifications for changed reference volume are sent.
10 Change-Id: I2e769b8a2b0d7031a02446dead8ca2e0c3402751
11 Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
13 src/pulsecore/sink-input.c | 23 ++++++++++-------------
14 src/pulsecore/sink.c | 30 ++++++++++++++++++++++++++----
15 src/pulsecore/sink.h | 7 +++++++
16 src/pulsecore/source-output.c | 23 ++++++++++-------------
17 src/pulsecore/source.c | 30 ++++++++++++++++++++++++++----
18 src/pulsecore/source.h | 7 +++++++
19 6 files changed, 86 insertions(+), 34 deletions(-)
21 diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
22 index d0509b3..6596eeb 100644
23 --- a/src/pulsecore/sink-input.c
24 +++ b/src/pulsecore/sink-input.c
25 @@ -1716,6 +1716,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
26 * their volume - this function does all that by using recursion. */
27 static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
28 pa_cvolume old_volume;
29 + pa_cvolume new_volume;
33 @@ -1787,25 +1788,21 @@ static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
34 * (sinks that use volume sharing should always have
35 * soft_volume of 0 dB) */
37 - old_volume = i->origin_sink->reference_volume;
39 - i->origin_sink->reference_volume = root_sink->reference_volume;
40 - pa_cvolume_remap(&i->origin_sink->reference_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
41 + new_volume = root_sink->reference_volume;
42 + pa_cvolume_remap(&new_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
43 + pa_sink_set_reference_volume_direct(i->origin_sink, &new_volume);
45 i->origin_sink->real_volume = root_sink->real_volume;
46 pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
48 pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
50 - /* Notify others about the changed sink volume. If you wonder whether
51 - * i->origin_sink->set_volume() should be called somewhere, that's not
52 - * the case, because sinks that use volume sharing shouldn't have any
53 - * internal volume that set_volume() would update. If you wonder
54 - * whether the thread_info variables should be synced, yes, they
55 - * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
57 - if (!pa_cvolume_equal(&i->origin_sink->reference_volume, &old_volume))
58 - pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, i->origin_sink->index);
59 + /* If you wonder whether i->origin_sink->set_volume() should be called
60 + * somewhere, that's not the case, because sinks that use volume
61 + * sharing shouldn't have any internal volume that set_volume() would
62 + * update. If you wonder whether the thread_info variables should be
63 + * synced, yes, they should, and it's done by the
64 + * PA_SINK_MESSAGE_FINISH_MOVE message handler. */
66 /* Recursively update origin sink inputs. */
67 PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
68 diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
69 index 11a6e77..e00dce5 100644
70 --- a/src/pulsecore/sink.c
71 +++ b/src/pulsecore/sink.c
72 @@ -2017,13 +2017,11 @@ static bool update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_ch
73 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
75 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
76 - s->reference_volume = volume;
77 + pa_sink_set_reference_volume_direct(s, &volume);
79 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
81 - if (reference_volume_changed)
82 - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
83 - else if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
84 + if (!reference_volume_changed && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
85 /* If the root sink's volume doesn't change, then there can't be any
86 * changes in the other sinks in the sink tree either.
88 @@ -3905,3 +3903,27 @@ done:
93 +/* Called from the main thread. */
94 +void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
95 + pa_cvolume old_volume;
96 + char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
97 + char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
102 + old_volume = s->reference_volume;
104 + if (pa_cvolume_equal(volume, &old_volume))
107 + s->reference_volume = *volume;
108 + pa_log_debug("The reference volume of sink %s changed from %s to %s.", s->name,
109 + pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
110 + s->flags & PA_SINK_DECIBEL_VOLUME),
111 + pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
112 + s->flags & PA_SINK_DECIBEL_VOLUME));
114 + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
116 diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
117 index 576f34b..41a439b 100644
118 --- a/src/pulsecore/sink.h
119 +++ b/src/pulsecore/sink.h
120 @@ -512,6 +512,13 @@ void pa_sink_invalidate_requested_latency(pa_sink *s, bool dynamic);
122 pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s);
124 +/* Called from the main thread, from sink-input.c only. The normal way to set
125 + * the sink reference volume is to call pa_sink_set_volume(), but the flat
126 + * volume logic in sink-input.c needs also a function that doesn't do all the
127 + * extra stuff that pa_sink_set_volume() does. This function simply sets
128 + * s->reference_volume and fires change notifications. */
129 +void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume);
131 /* Verify that we called in IO context (aka 'thread context), or that
132 * the sink is not yet set up, i.e. the thread not set up yet. See
133 * pa_assert_io_context() in thread-mq.h for more information. */
134 diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
135 index b12758a..169d98d 100644
136 --- a/src/pulsecore/source-output.c
137 +++ b/src/pulsecore/source-output.c
138 @@ -1263,6 +1263,7 @@ int pa_source_output_start_move(pa_source_output *o) {
139 * their volume - this function does all that by using recursion. */
140 static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) {
141 pa_cvolume old_volume;
142 + pa_cvolume new_volume;
146 @@ -1336,25 +1337,21 @@ static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) {
147 * (sources that use volume sharing should always have
148 * soft_volume of 0 dB) */
150 - old_volume = o->destination_source->reference_volume;
152 - o->destination_source->reference_volume = root_source->reference_volume;
153 - pa_cvolume_remap(&o->destination_source->reference_volume, &root_source->channel_map, &o->destination_source->channel_map);
154 + new_volume = root_source->reference_volume;
155 + pa_cvolume_remap(&new_volume, &root_source->channel_map, &o->destination_source->channel_map);
156 + pa_source_set_reference_volume_direct(o->destination_source, &new_volume);
158 o->destination_source->real_volume = root_source->real_volume;
159 pa_cvolume_remap(&o->destination_source->real_volume, &root_source->channel_map, &o->destination_source->channel_map);
161 pa_assert(pa_cvolume_is_norm(&o->destination_source->soft_volume));
163 - /* Notify others about the changed source volume. If you wonder whether
164 - * o->destination_source->set_volume() should be called somewhere, that's not
165 - * the case, because sources that use volume sharing shouldn't have any
166 - * internal volume that set_volume() would update. If you wonder
167 - * whether the thread_info variables should be synced, yes, they
168 - * should, and it's done by the PA_SOURCE_MESSAGE_FINISH_MOVE message
170 - if (!pa_cvolume_equal(&o->destination_source->reference_volume, &old_volume))
171 - pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, o->destination_source->index);
172 + /* If you wonder whether o->destination_source->set_volume() should be
173 + * called somewhere, that's not the case, because sources that use
174 + * volume sharing shouldn't have any internal volume that set_volume()
175 + * would update. If you wonder whether the thread_info variables should
176 + * be synced, yes, they should, and it's done by the
177 + * PA_SOURCE_MESSAGE_FINISH_MOVE message handler. */
179 /* Recursively update origin source outputs. */
180 PA_IDXSET_FOREACH(destination_source_output, o->destination_source->outputs, idx)
181 diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
182 index d39193f..f58bb44 100644
183 --- a/src/pulsecore/source.c
184 +++ b/src/pulsecore/source.c
185 @@ -1562,13 +1562,11 @@ static bool update_reference_volume(pa_source *s, const pa_cvolume *v, const pa_
186 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
188 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
189 - s->reference_volume = volume;
190 + pa_source_set_reference_volume_direct(s, &volume);
192 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
194 - if (reference_volume_changed)
195 - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
196 - else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
197 + if (!reference_volume_changed && !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
198 /* If the root source's volume doesn't change, then there can't be any
199 * changes in the other source in the source tree either.
201 @@ -2899,3 +2897,27 @@ done:
206 +/* Called from the main thread. */
207 +void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume) {
208 + pa_cvolume old_volume;
209 + char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
210 + char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
215 + old_volume = s->reference_volume;
217 + if (pa_cvolume_equal(volume, &old_volume))
220 + s->reference_volume = *volume;
221 + pa_log_debug("The reference volume of source %s changed from %s to %s.", s->name,
222 + pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
223 + s->flags & PA_SOURCE_DECIBEL_VOLUME),
224 + pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
225 + s->flags & PA_SOURCE_DECIBEL_VOLUME));
227 + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
229 diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
230 index 5c74a51..6318595 100644
231 --- a/src/pulsecore/source.h
232 +++ b/src/pulsecore/source.h
233 @@ -426,6 +426,13 @@ bool pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next);
234 void pa_source_invalidate_requested_latency(pa_source *s, bool dynamic);
235 pa_usec_t pa_source_get_latency_within_thread(pa_source *s);
237 +/* Called from the main thread, from source-output.c only. The normal way to
238 + * set the source reference volume is to call pa_source_set_volume(), but the
239 + * flat volume logic in source-output.c needs also a function that doesn't do
240 + * all the extra stuff that pa_source_set_volume() does. This function simply
241 + * sets s->reference_volume and fires change notifications. */
242 +void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume);
244 #define pa_source_assert_io_context(s) \
245 pa_assert(pa_thread_mq_get() || !PA_SOURCE_IS_LINKED((s)->state))