2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
29 #include <pulse/introspect.h>
30 #include <pulse/format.h>
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/timeval.h>
34 #include <pulse/util.h>
35 #include <pulse/rtclock.h>
36 #include <pulse/internal.h>
38 #include <pulsecore/i18n.h>
39 #include <pulsecore/sink-input.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-util.h>
42 #include <pulsecore/sample-util.h>
43 #include <pulsecore/mix.h>
44 #include <pulsecore/core-subscribe.h>
45 #include <pulsecore/log.h>
46 #include <pulsecore/macro.h>
47 #include <pulsecore/play-memblockq.h>
48 #include <pulsecore/flist.h>
52 #define MAX_MIX_CHANNELS 32
53 #define MIX_BUFFER_LENGTH (pa_page_size())
54 #define ABSOLUTE_MIN_LATENCY (500)
55 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
56 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
58 PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject);
60 struct pa_sink_volume_change {
64 PA_LLIST_FIELDS(pa_sink_volume_change);
67 struct sink_message_set_port {
72 static void sink_free(pa_object *s);
74 static void pa_sink_volume_change_push(pa_sink *s);
75 static void pa_sink_volume_change_flush(pa_sink *s);
76 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes);
78 pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
82 data->proplist = pa_proplist_new();
83 data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
88 void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name) {
92 data->name = pa_xstrdup(name);
95 void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec) {
98 if ((data->sample_spec_is_set = !!spec))
99 data->sample_spec = *spec;
102 void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map) {
105 if ((data->channel_map_is_set = !!map))
106 data->channel_map = *map;
109 void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate) {
112 data->alternate_sample_rate_is_set = true;
113 data->alternate_sample_rate = alternate_sample_rate;
116 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
119 if ((data->volume_is_set = !!volume))
120 data->volume = *volume;
123 void pa_sink_new_data_set_muted(pa_sink_new_data *data, bool mute) {
126 data->muted_is_set = true;
130 void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) {
133 pa_xfree(data->active_port);
134 data->active_port = pa_xstrdup(port);
137 void pa_sink_new_data_done(pa_sink_new_data *data) {
140 pa_proplist_free(data->proplist);
143 pa_hashmap_free(data->ports);
145 pa_xfree(data->name);
146 pa_xfree(data->active_port);
149 /* Called from main context */
150 static void reset_callbacks(pa_sink *s) {
154 s->get_volume = NULL;
155 s->set_volume = NULL;
156 s->write_volume = NULL;
159 s->request_rewind = NULL;
160 s->update_requested_latency = NULL;
162 s->get_formats = NULL;
163 s->set_formats = NULL;
164 s->update_rate = NULL;
167 /* Called from main context */
168 pa_sink* pa_sink_new(
170 pa_sink_new_data *data,
171 pa_sink_flags_t flags) {
175 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
176 pa_source_new_data source_data;
182 pa_assert(data->name);
183 pa_assert_ctl_context();
185 s = pa_msgobject_new(pa_sink);
187 if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SINK, s, data->namereg_fail))) {
188 pa_log_debug("Failed to register name %s.", data->name);
193 pa_sink_new_data_set_name(data, name);
195 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW], data) < 0) {
197 pa_namereg_unregister(core, name);
201 /* FIXME, need to free s here on failure */
203 pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
204 pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
206 pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
208 if (!data->channel_map_is_set)
209 pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
211 pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
212 pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
214 /* FIXME: There should probably be a general function for checking whether
215 * the sink volume is allowed to be set, like there is for sink inputs. */
216 pa_assert(!data->volume_is_set || !(flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
218 if (!data->volume_is_set) {
219 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
220 data->save_volume = false;
223 pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
224 pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
226 if (!data->muted_is_set)
230 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
232 pa_device_init_description(data->proplist, data->card);
233 pa_device_init_icon(data->proplist, true);
234 pa_device_init_intended_roles(data->proplist);
236 if (!data->active_port) {
237 pa_device_port *p = pa_device_port_find_best(data->ports);
239 pa_sink_new_data_set_port(data, p->name);
242 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
244 pa_namereg_unregister(core, name);
248 s->parent.parent.free = sink_free;
249 s->parent.process_msg = pa_sink_process_msg;
252 s->state = PA_SINK_INIT;
255 s->suspend_cause = data->suspend_cause;
256 pa_sink_set_mixer_dirty(s, false);
257 s->name = pa_xstrdup(name);
258 s->proplist = pa_proplist_copy(data->proplist);
259 s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
260 s->module = data->module;
261 s->card = data->card;
263 s->priority = pa_device_init_priority(s->proplist);
265 s->sample_spec = data->sample_spec;
266 s->channel_map = data->channel_map;
267 s->default_sample_rate = s->sample_spec.rate;
269 if (data->alternate_sample_rate_is_set)
270 s->alternate_sample_rate = data->alternate_sample_rate;
272 s->alternate_sample_rate = s->core->alternate_sample_rate;
274 if (s->sample_spec.rate == s->alternate_sample_rate) {
275 pa_log_warn("Default and alternate sample rates are the same.");
276 s->alternate_sample_rate = 0;
279 s->inputs = pa_idxset_new(NULL, NULL);
281 s->input_to_master = NULL;
283 s->reference_volume = s->real_volume = data->volume;
284 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
285 s->base_volume = PA_VOLUME_NORM;
286 s->n_volume_steps = PA_VOLUME_NORM+1;
287 s->muted = data->muted;
288 s->refresh_volume = s->refresh_muted = false;
295 /* As a minor optimization we just steal the list instead of
297 s->ports = data->ports;
300 s->active_port = NULL;
301 s->save_port = false;
303 if (data->active_port)
304 if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
305 s->save_port = data->save_port;
307 /* Hopefully the active port has already been assigned in the previous call
308 to pa_device_port_find_best, but better safe than sorry */
310 s->active_port = pa_device_port_find_best(s->ports);
313 s->port_latency_offset = s->active_port->latency_offset;
315 s->port_latency_offset = 0;
317 s->save_volume = data->save_volume;
318 s->save_muted = data->save_muted;
320 pa_silence_memchunk_get(
321 &core->silence_cache,
327 s->thread_info.rtpoll = NULL;
328 s->thread_info.inputs = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
329 (pa_free_cb_t) pa_sink_input_unref);
330 s->thread_info.soft_volume = s->soft_volume;
331 s->thread_info.soft_muted = s->muted;
332 s->thread_info.state = s->state;
333 s->thread_info.rewind_nbytes = 0;
334 s->thread_info.rewind_requested = false;
335 s->thread_info.max_rewind = 0;
336 s->thread_info.max_request = 0;
337 s->thread_info.requested_latency_valid = false;
338 s->thread_info.requested_latency = 0;
339 s->thread_info.min_latency = ABSOLUTE_MIN_LATENCY;
340 s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
341 s->thread_info.fixed_latency = flags & PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
343 PA_LLIST_HEAD_INIT(pa_sink_volume_change, s->thread_info.volume_changes);
344 s->thread_info.volume_changes_tail = NULL;
345 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
346 s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
347 s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
348 s->thread_info.port_latency_offset = s->port_latency_offset;
350 /* FIXME: This should probably be moved to pa_sink_put() */
351 pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
354 pa_assert_se(pa_idxset_put(s->card->sinks, s, NULL) >= 0);
356 pt = pa_proplist_to_string_sep(s->proplist, "\n ");
357 pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n %s",
360 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
361 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
365 pa_source_new_data_init(&source_data);
366 pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
367 pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
368 pa_source_new_data_set_alternate_sample_rate(&source_data, s->alternate_sample_rate);
369 source_data.name = pa_sprintf_malloc("%s.monitor", name);
370 source_data.driver = data->driver;
371 source_data.module = data->module;
372 source_data.card = data->card;
374 dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
375 pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor of %s", dn ? dn : s->name);
376 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
378 s->monitor_source = pa_source_new(core, &source_data,
379 ((flags & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
380 ((flags & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
382 pa_source_new_data_done(&source_data);
384 if (!s->monitor_source) {
390 s->monitor_source->monitor_of = s;
392 pa_source_set_latency_range(s->monitor_source, s->thread_info.min_latency, s->thread_info.max_latency);
393 pa_source_set_fixed_latency(s->monitor_source, s->thread_info.fixed_latency);
394 pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
399 /* Called from main context */
400 static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
403 pa_sink_state_t original_state;
406 pa_assert_ctl_context();
408 if (s->state == state)
411 original_state = s->state;
414 (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
415 (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);
418 if ((ret = s->set_state(s, state)) < 0)
422 if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
425 s->set_state(s, original_state);
432 if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the appropriate events */
433 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
434 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
437 if (suspend_change) {
441 /* We're suspending or resuming, tell everyone about it */
443 PA_IDXSET_FOREACH(i, s->inputs, idx)
444 if (s->state == PA_SINK_SUSPENDED &&
445 (i->flags & PA_SINK_INPUT_KILL_ON_SUSPEND))
446 pa_sink_input_kill(i);
448 i->suspend(i, state == PA_SINK_SUSPENDED);
450 if (s->monitor_source)
451 pa_source_sync_suspend(s->monitor_source);
457 void pa_sink_set_get_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
463 void pa_sink_set_set_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
464 pa_sink_flags_t flags;
467 pa_assert(!s->write_volume || cb);
471 /* Save the current flags so we can tell if they've changed */
475 /* The sink implementor is responsible for setting decibel volume support */
476 s->flags |= PA_SINK_HW_VOLUME_CTRL;
478 s->flags &= ~PA_SINK_HW_VOLUME_CTRL;
479 /* See note below in pa_sink_put() about volume sharing and decibel volumes */
480 pa_sink_enable_decibel_volume(s, !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
483 /* If the flags have changed after init, let any clients know via a change event */
484 if (s->state != PA_SINK_INIT && flags != s->flags)
485 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
488 void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
489 pa_sink_flags_t flags;
492 pa_assert(!cb || s->set_volume);
494 s->write_volume = cb;
496 /* Save the current flags so we can tell if they've changed */
500 s->flags |= PA_SINK_DEFERRED_VOLUME;
502 s->flags &= ~PA_SINK_DEFERRED_VOLUME;
504 /* If the flags have changed after init, let any clients know via a change event */
505 if (s->state != PA_SINK_INIT && flags != s->flags)
506 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
509 void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_get_mute_cb_t cb) {
515 void pa_sink_set_set_mute_callback(pa_sink *s, pa_sink_cb_t cb) {
516 pa_sink_flags_t flags;
522 /* Save the current flags so we can tell if they've changed */
526 s->flags |= PA_SINK_HW_MUTE_CTRL;
528 s->flags &= ~PA_SINK_HW_MUTE_CTRL;
530 /* If the flags have changed after init, let any clients know via a change event */
531 if (s->state != PA_SINK_INIT && flags != s->flags)
532 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
535 static void enable_flat_volume(pa_sink *s, bool enable) {
536 pa_sink_flags_t flags;
540 /* Always follow the overall user preference here */
541 enable = enable && s->core->flat_volumes;
543 /* Save the current flags so we can tell if they've changed */
547 s->flags |= PA_SINK_FLAT_VOLUME;
549 s->flags &= ~PA_SINK_FLAT_VOLUME;
551 /* If the flags have changed after init, let any clients know via a change event */
552 if (s->state != PA_SINK_INIT && flags != s->flags)
553 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
556 void pa_sink_enable_decibel_volume(pa_sink *s, bool enable) {
557 pa_sink_flags_t flags;
561 /* Save the current flags so we can tell if they've changed */
565 s->flags |= PA_SINK_DECIBEL_VOLUME;
566 enable_flat_volume(s, true);
568 s->flags &= ~PA_SINK_DECIBEL_VOLUME;
569 enable_flat_volume(s, false);
572 /* If the flags have changed after init, let any clients know via a change event */
573 if (s->state != PA_SINK_INIT && flags != s->flags)
574 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
577 /* Called from main context */
578 void pa_sink_put(pa_sink* s) {
579 pa_sink_assert_ref(s);
580 pa_assert_ctl_context();
582 pa_assert(s->state == PA_SINK_INIT);
583 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || pa_sink_is_filter(s));
585 /* The following fields must be initialized properly when calling _put() */
586 pa_assert(s->asyncmsgq);
587 pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
589 /* Generally, flags should be initialized via pa_sink_new(). As a
590 * special exception we allow some volume related flags to be set
591 * between _new() and _put() by the callback setter functions above.
593 * Thus we implement a couple safeguards here which ensure the above
594 * setters were used (or at least the implementor made manual changes
595 * in a compatible way).
597 * Note: All of these flags set here can change over the life time
599 pa_assert(!(s->flags & PA_SINK_HW_VOLUME_CTRL) || s->set_volume);
600 pa_assert(!(s->flags & PA_SINK_DEFERRED_VOLUME) || s->write_volume);
601 pa_assert(!(s->flags & PA_SINK_HW_MUTE_CTRL) || s->set_mute);
603 /* XXX: Currently decibel volume is disabled for all sinks that use volume
604 * sharing. When the master sink supports decibel volume, it would be good
605 * to have the flag also in the filter sink, but currently we don't do that
606 * so that the flags of the filter sink never change when it's moved from
607 * a master sink to another. One solution for this problem would be to
608 * remove user-visible volume altogether from filter sinks when volume
609 * sharing is used, but the current approach was easier to implement... */
610 /* We always support decibel volumes in software, otherwise we leave it to
611 * the sink implementor to set this flag as needed.
613 * Note: This flag can also change over the life time of the sink. */
614 if (!(s->flags & PA_SINK_HW_VOLUME_CTRL) && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
615 pa_sink_enable_decibel_volume(s, true);
616 s->soft_volume = s->reference_volume;
619 /* If the sink implementor support DB volumes by itself, we should always
620 * try and enable flat volumes too */
621 if ((s->flags & PA_SINK_DECIBEL_VOLUME))
622 enable_flat_volume(s, true);
624 if (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) {
625 pa_sink *root_sink = pa_sink_get_master(s);
627 pa_assert(root_sink);
629 s->reference_volume = root_sink->reference_volume;
630 pa_cvolume_remap(&s->reference_volume, &root_sink->channel_map, &s->channel_map);
632 s->real_volume = root_sink->real_volume;
633 pa_cvolume_remap(&s->real_volume, &root_sink->channel_map, &s->channel_map);
635 /* We assume that if the sink implementor changed the default
636 * volume he did so in real_volume, because that is the usual
637 * place where he is supposed to place his changes. */
638 s->reference_volume = s->real_volume;
640 s->thread_info.soft_volume = s->soft_volume;
641 s->thread_info.soft_muted = s->muted;
642 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
644 pa_assert((s->flags & PA_SINK_HW_VOLUME_CTRL)
645 || (s->base_volume == PA_VOLUME_NORM
646 && ((s->flags & PA_SINK_DECIBEL_VOLUME || (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)))));
647 pa_assert(!(s->flags & PA_SINK_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
648 pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == !(s->thread_info.fixed_latency == 0));
649 pa_assert(!(s->flags & PA_SINK_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_LATENCY));
650 pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_DYNAMIC_LATENCY));
652 pa_assert(s->monitor_source->thread_info.fixed_latency == s->thread_info.fixed_latency);
653 pa_assert(s->monitor_source->thread_info.min_latency == s->thread_info.min_latency);
654 pa_assert(s->monitor_source->thread_info.max_latency == s->thread_info.max_latency);
656 if (s->suspend_cause)
657 pa_assert_se(sink_set_state(s, PA_SINK_SUSPENDED) == 0);
659 pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
661 pa_source_put(s->monitor_source);
663 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
664 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
666 /* This function must be called after the PA_CORE_HOOK_SINK_PUT hook,
667 * because module-switch-on-connect needs to know the old default sink */
668 pa_core_update_default_sink(s->core);
671 /* Called from main context */
672 void pa_sink_unlink(pa_sink* s) {
674 pa_sink_input *i, PA_UNUSED *j = NULL;
676 pa_sink_assert_ref(s);
677 pa_assert_ctl_context();
679 /* Please note that pa_sink_unlink() does more than simply
680 * reversing pa_sink_put(). It also undoes the registrations
681 * already done in pa_sink_new()! */
683 if (s->unlink_requested)
686 s->unlink_requested = true;
688 linked = PA_SINK_IS_LINKED(s->state);
691 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
693 if (s->state != PA_SINK_UNLINKED)
694 pa_namereg_unregister(s->core, s->name);
695 pa_idxset_remove_by_data(s->core->sinks, s, NULL);
697 if (s == s->core->configured_default_sink)
698 pa_core_set_configured_default_sink(s->core, NULL);
700 pa_core_update_default_sink(s->core);
703 pa_idxset_remove_by_data(s->card->sinks, s, NULL);
705 while ((i = pa_idxset_first(s->inputs, NULL))) {
707 pa_sink_input_kill(i);
712 sink_set_state(s, PA_SINK_UNLINKED);
714 s->state = PA_SINK_UNLINKED;
718 if (s->monitor_source)
719 pa_source_unlink(s->monitor_source);
722 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
723 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s);
727 /* Called from main context */
728 static void sink_free(pa_object *o) {
729 pa_sink *s = PA_SINK(o);
732 pa_assert_ctl_context();
733 pa_assert(pa_sink_refcnt(s) == 0);
734 pa_assert(!PA_SINK_IS_LINKED(s->state));
736 pa_log_info("Freeing sink %u \"%s\"", s->index, s->name);
738 pa_sink_volume_change_flush(s);
740 if (s->monitor_source) {
741 pa_source_unref(s->monitor_source);
742 s->monitor_source = NULL;
745 pa_idxset_free(s->inputs, NULL);
746 pa_hashmap_free(s->thread_info.inputs);
748 if (s->silence.memblock)
749 pa_memblock_unref(s->silence.memblock);
755 pa_proplist_free(s->proplist);
758 pa_hashmap_free(s->ports);
763 /* Called from main context, and not while the IO thread is active, please */
764 void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
765 pa_sink_assert_ref(s);
766 pa_assert_ctl_context();
770 if (s->monitor_source)
771 pa_source_set_asyncmsgq(s->monitor_source, q);
774 /* Called from main context, and not while the IO thread is active, please */
775 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {
776 pa_sink_flags_t old_flags;
777 pa_sink_input *input;
780 pa_sink_assert_ref(s);
781 pa_assert_ctl_context();
783 /* For now, allow only a minimal set of flags to be changed. */
784 pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
786 old_flags = s->flags;
787 s->flags = (s->flags & ~mask) | (value & mask);
789 if (s->flags == old_flags)
792 if ((s->flags & PA_SINK_LATENCY) != (old_flags & PA_SINK_LATENCY))
793 pa_log_debug("Sink %s: LATENCY flag %s.", s->name, (s->flags & PA_SINK_LATENCY) ? "enabled" : "disabled");
795 if ((s->flags & PA_SINK_DYNAMIC_LATENCY) != (old_flags & PA_SINK_DYNAMIC_LATENCY))
796 pa_log_debug("Sink %s: DYNAMIC_LATENCY flag %s.",
797 s->name, (s->flags & PA_SINK_DYNAMIC_LATENCY) ? "enabled" : "disabled");
799 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
800 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_FLAGS_CHANGED], s);
802 if (s->monitor_source)
803 pa_source_update_flags(s->monitor_source,
804 ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
805 ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
806 ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
807 ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
809 PA_IDXSET_FOREACH(input, s->inputs, idx) {
810 if (input->origin_sink)
811 pa_sink_update_flags(input->origin_sink, mask, value);
815 /* Called from IO context, or before _put() from main context */
816 void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) {
817 pa_sink_assert_ref(s);
818 pa_sink_assert_io_context(s);
820 s->thread_info.rtpoll = p;
822 if (s->monitor_source)
823 pa_source_set_rtpoll(s->monitor_source, p);
826 /* Called from main context */
827 int pa_sink_update_status(pa_sink*s) {
828 pa_sink_assert_ref(s);
829 pa_assert_ctl_context();
830 pa_assert(PA_SINK_IS_LINKED(s->state));
832 if (s->state == PA_SINK_SUSPENDED)
835 return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
838 /* Called from any context - must be threadsafe */
839 void pa_sink_set_mixer_dirty(pa_sink *s, bool is_dirty) {
840 pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
843 /* Called from main context */
844 int pa_sink_suspend(pa_sink *s, bool suspend, pa_suspend_cause_t cause) {
845 pa_sink_assert_ref(s);
846 pa_assert_ctl_context();
847 pa_assert(PA_SINK_IS_LINKED(s->state));
848 pa_assert(cause != 0);
851 s->suspend_cause |= cause;
852 s->monitor_source->suspend_cause |= cause;
854 s->suspend_cause &= ~cause;
855 s->monitor_source->suspend_cause &= ~cause;
858 if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
859 /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
860 it'll be handled just fine. */
861 pa_sink_set_mixer_dirty(s, false);
862 pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
863 if (s->active_port && s->set_port) {
864 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
865 struct sink_message_set_port msg = { .port = s->active_port, .ret = 0 };
866 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
869 s->set_port(s, s->active_port);
879 if ((pa_sink_get_state(s) == PA_SINK_SUSPENDED) == !!s->suspend_cause)
882 pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
884 if (s->suspend_cause)
885 return sink_set_state(s, PA_SINK_SUSPENDED);
887 return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
890 /* Called from main context */
891 pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q) {
892 pa_sink_input *i, *n;
895 pa_sink_assert_ref(s);
896 pa_assert_ctl_context();
897 pa_assert(PA_SINK_IS_LINKED(s->state));
902 for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = n) {
903 n = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx));
905 pa_sink_input_ref(i);
907 if (pa_sink_input_start_move(i) >= 0)
910 pa_sink_input_unref(i);
916 /* Called from main context */
917 void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, bool save) {
920 pa_sink_assert_ref(s);
921 pa_assert_ctl_context();
922 pa_assert(PA_SINK_IS_LINKED(s->state));
925 while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
926 if (pa_sink_input_finish_move(i, s, save) < 0)
927 pa_sink_input_fail_move(i);
929 pa_sink_input_unref(i);
932 pa_queue_free(q, NULL);
935 /* Called from main context */
936 void pa_sink_move_all_fail(pa_queue *q) {
939 pa_assert_ctl_context();
942 while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
943 pa_sink_input_fail_move(i);
944 pa_sink_input_unref(i);
947 pa_queue_free(q, NULL);
950 /* Called from IO thread context */
951 size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
956 pa_sink_assert_ref(s);
957 pa_sink_assert_io_context(s);
959 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
960 size_t uf = i->thread_info.underrun_for_sink;
962 /* Propagate down the filter tree */
963 if (i->origin_sink) {
964 size_t filter_result, left_to_play_origin;
966 /* The recursive call works in the origin sink domain ... */
967 left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
969 /* .. and returns the time to sleep before waking up. We need the
970 * underrun duration for comparisons, so we undo the subtraction on
971 * the return value... */
972 filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
974 /* ... and convert it back to the master sink domain */
975 filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
977 /* Remember the longest underrun so far */
978 if (filter_result > result)
979 result = filter_result;
983 /* No underrun here, move on */
985 } else if (uf >= left_to_play) {
986 /* The sink has possibly consumed all the data the sink input provided */
987 pa_sink_input_process_underrun(i);
988 } else if (uf > result) {
989 /* Remember the longest underrun so far */
995 pa_log_debug("%s: Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", s->name,
996 (long) result, (long) left_to_play - result);
997 return left_to_play - result;
1000 /* Called from IO thread context */
1001 void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
1005 pa_sink_assert_ref(s);
1006 pa_sink_assert_io_context(s);
1007 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1009 /* If nobody requested this and this is actually no real rewind
1010 * then we can short cut this. Please note that this means that
1011 * not all rewind requests triggered upstream will always be
1012 * translated in actual requests! */
1013 if (!s->thread_info.rewind_requested && nbytes <= 0)
1016 s->thread_info.rewind_nbytes = 0;
1017 s->thread_info.rewind_requested = false;
1020 pa_log_debug("Processing rewind...");
1021 if (s->flags & PA_SINK_DEFERRED_VOLUME)
1022 pa_sink_volume_change_rewind(s, nbytes);
1025 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
1026 pa_sink_input_assert_ref(i);
1027 pa_sink_input_process_rewind(i, nbytes);
1031 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
1032 pa_source_process_rewind(s->monitor_source, nbytes);
1036 /* Called from IO thread context */
1037 static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, unsigned maxinfo) {
1041 size_t mixlength = *length;
1043 pa_sink_assert_ref(s);
1044 pa_sink_assert_io_context(s);
1047 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
1048 pa_sink_input_assert_ref(i);
1050 pa_sink_input_peek(i, *length, &info->chunk, &info->volume);
1052 if (mixlength == 0 || info->chunk.length < mixlength)
1053 mixlength = info->chunk.length;
1055 if (pa_memblock_is_silence(info->chunk.memblock)) {
1056 pa_memblock_unref(info->chunk.memblock);
1060 info->userdata = pa_sink_input_ref(i);
1062 pa_assert(info->chunk.memblock);
1063 pa_assert(info->chunk.length > 0);
1071 *length = mixlength;
1076 /* Called from IO thread context */
1077 static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {
1081 unsigned n_unreffed = 0;
1083 pa_sink_assert_ref(s);
1084 pa_sink_assert_io_context(s);
1086 pa_assert(result->memblock);
1087 pa_assert(result->length > 0);
1089 /* We optimize for the case where the order of the inputs has not changed */
1091 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
1093 pa_mix_info* m = NULL;
1095 pa_sink_input_assert_ref(i);
1097 /* Let's try to find the matching entry info the pa_mix_info array */
1098 for (j = 0; j < n; j ++) {
1100 if (info[p].userdata == i) {
1110 /* Drop read data */
1111 pa_sink_input_drop(i, result->length);
1113 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state)) {
1115 if (pa_hashmap_size(i->thread_info.direct_outputs) > 0) {
1116 void *ostate = NULL;
1117 pa_source_output *o;
1120 if (m && m->chunk.memblock) {
1122 pa_memblock_ref(c.memblock);
1123 pa_assert(result->length <= c.length);
1124 c.length = result->length;
1126 pa_memchunk_make_writable(&c, 0);
1127 pa_volume_memchunk(&c, &s->sample_spec, &m->volume);
1130 pa_memblock_ref(c.memblock);
1131 pa_assert(result->length <= c.length);
1132 c.length = result->length;
1135 while ((o = pa_hashmap_iterate(i->thread_info.direct_outputs, &ostate, NULL))) {
1136 pa_source_output_assert_ref(o);
1137 pa_assert(o->direct_on_input == i);
1138 pa_source_post_direct(s->monitor_source, o, &c);
1141 pa_memblock_unref(c.memblock);
1146 if (m->chunk.memblock) {
1147 pa_memblock_unref(m->chunk.memblock);
1148 pa_memchunk_reset(&m->chunk);
1151 pa_sink_input_unref(m->userdata);
1158 /* Now drop references to entries that are included in the
1159 * pa_mix_info array but don't exist anymore */
1161 if (n_unreffed < n) {
1162 for (; n > 0; info++, n--) {
1164 pa_sink_input_unref(info->userdata);
1165 if (info->chunk.memblock)
1166 pa_memblock_unref(info->chunk.memblock);
1170 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
1171 pa_source_post(s->monitor_source, result);
1174 /* Called from IO thread context */
1175 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
1176 pa_mix_info info[MAX_MIX_CHANNELS];
1178 size_t block_size_max;
1180 pa_sink_assert_ref(s);
1181 pa_sink_assert_io_context(s);
1182 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1183 pa_assert(pa_frame_aligned(length, &s->sample_spec));
1186 pa_assert(!s->thread_info.rewind_requested);
1187 pa_assert(s->thread_info.rewind_nbytes == 0);
1189 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1190 result->memblock = pa_memblock_ref(s->silence.memblock);
1191 result->index = s->silence.index;
1192 result->length = PA_MIN(s->silence.length, length);
1199 length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
1201 block_size_max = pa_mempool_block_size_max(s->core->mempool);
1202 if (length > block_size_max)
1203 length = pa_frame_align(block_size_max, &s->sample_spec);
1205 pa_assert(length > 0);
1207 n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
1211 *result = s->silence;
1212 pa_memblock_ref(result->memblock);
1214 if (result->length > length)
1215 result->length = length;
1217 } else if (n == 1) {
1220 *result = info[0].chunk;
1221 pa_memblock_ref(result->memblock);
1223 if (result->length > length)
1224 result->length = length;
1226 pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
1228 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
1229 pa_memblock_unref(result->memblock);
1230 pa_silence_memchunk_get(&s->core->silence_cache,
1235 } else if (!pa_cvolume_is_norm(&volume)) {
1236 pa_memchunk_make_writable(result, 0);
1237 pa_volume_memchunk(result, &s->sample_spec, &volume);
1241 result->memblock = pa_memblock_new(s->core->mempool, length);
1243 ptr = pa_memblock_acquire(result->memblock);
1244 result->length = pa_mix(info, n,
1247 &s->thread_info.soft_volume,
1248 s->thread_info.soft_muted);
1249 pa_memblock_release(result->memblock);
1254 inputs_drop(s, info, n, result);
1259 /* Called from IO thread context */
1260 void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
1261 pa_mix_info info[MAX_MIX_CHANNELS];
1263 size_t length, block_size_max;
1265 pa_sink_assert_ref(s);
1266 pa_sink_assert_io_context(s);
1267 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1269 pa_assert(target->memblock);
1270 pa_assert(target->length > 0);
1271 pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1273 pa_assert(!s->thread_info.rewind_requested);
1274 pa_assert(s->thread_info.rewind_nbytes == 0);
1276 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1277 pa_silence_memchunk(target, &s->sample_spec);
1283 length = target->length;
1284 block_size_max = pa_mempool_block_size_max(s->core->mempool);
1285 if (length > block_size_max)
1286 length = pa_frame_align(block_size_max, &s->sample_spec);
1288 pa_assert(length > 0);
1290 n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
1293 if (target->length > length)
1294 target->length = length;
1296 pa_silence_memchunk(target, &s->sample_spec);
1297 } else if (n == 1) {
1300 if (target->length > length)
1301 target->length = length;
1303 pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
1305 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
1306 pa_silence_memchunk(target, &s->sample_spec);
1310 vchunk = info[0].chunk;
1311 pa_memblock_ref(vchunk.memblock);
1313 if (vchunk.length > length)
1314 vchunk.length = length;
1316 if (!pa_cvolume_is_norm(&volume)) {
1317 pa_memchunk_make_writable(&vchunk, 0);
1318 pa_volume_memchunk(&vchunk, &s->sample_spec, &volume);
1321 pa_memchunk_memcpy(target, &vchunk);
1322 pa_memblock_unref(vchunk.memblock);
1328 ptr = pa_memblock_acquire(target->memblock);
1330 target->length = pa_mix(info, n,
1331 (uint8_t*) ptr + target->index, length,
1333 &s->thread_info.soft_volume,
1334 s->thread_info.soft_muted);
1336 pa_memblock_release(target->memblock);
1339 inputs_drop(s, info, n, target);
1344 /* Called from IO thread context */
1345 void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
1349 pa_sink_assert_ref(s);
1350 pa_sink_assert_io_context(s);
1351 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1353 pa_assert(target->memblock);
1354 pa_assert(target->length > 0);
1355 pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1357 pa_assert(!s->thread_info.rewind_requested);
1358 pa_assert(s->thread_info.rewind_nbytes == 0);
1360 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1361 pa_silence_memchunk(target, &s->sample_spec);
1374 pa_sink_render_into(s, &chunk);
1383 /* Called from IO thread context */
1384 void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
1385 pa_sink_assert_ref(s);
1386 pa_sink_assert_io_context(s);
1387 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1388 pa_assert(length > 0);
1389 pa_assert(pa_frame_aligned(length, &s->sample_spec));
1392 pa_assert(!s->thread_info.rewind_requested);
1393 pa_assert(s->thread_info.rewind_nbytes == 0);
1397 pa_sink_render(s, length, result);
1399 if (result->length < length) {
1402 pa_memchunk_make_writable(result, length);
1404 chunk.memblock = result->memblock;
1405 chunk.index = result->index + result->length;
1406 chunk.length = length - result->length;
1408 pa_sink_render_into_full(s, &chunk);
1410 result->length = length;
1416 /* Called from main thread */
1417 int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
1419 uint32_t desired_rate;
1420 uint32_t default_rate = s->default_sample_rate;
1421 uint32_t alternate_rate = s->alternate_sample_rate;
1424 bool default_rate_is_usable = false;
1425 bool alternate_rate_is_usable = false;
1426 bool avoid_resampling = s->core->avoid_resampling;
1428 if (rate == s->sample_spec.rate)
1431 if (!s->update_rate)
1434 if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !avoid_resampling)) {
1435 pa_log_debug("Default and alternate sample rates are the same, so there is no point in switching.");
1439 if (PA_SINK_IS_RUNNING(s->state)) {
1440 pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u Hz",
1441 s->sample_spec.rate);
1445 if (s->monitor_source) {
1446 if (PA_SOURCE_IS_RUNNING(s->monitor_source->state) == true) {
1447 pa_log_info("Cannot update rate, monitor source is RUNNING");
1452 if (PA_UNLIKELY(!pa_sample_rate_valid(rate)))
1456 /* We have to try to use the sink input rate */
1457 desired_rate = rate;
1459 } else if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
1460 /* We just try to set the sink input's sample rate if it's not too low */
1461 desired_rate = rate;
1463 } else if (default_rate == rate || alternate_rate == rate) {
1464 /* We can directly try to use this rate */
1465 desired_rate = rate;
1468 /* See if we can pick a rate that results in less resampling effort */
1469 if (default_rate % 11025 == 0 && rate % 11025 == 0)
1470 default_rate_is_usable = true;
1471 if (default_rate % 4000 == 0 && rate % 4000 == 0)
1472 default_rate_is_usable = true;
1473 if (alternate_rate && alternate_rate % 11025 == 0 && rate % 11025 == 0)
1474 alternate_rate_is_usable = true;
1475 if (alternate_rate && alternate_rate % 4000 == 0 && rate % 4000 == 0)
1476 alternate_rate_is_usable = true;
1478 if (alternate_rate_is_usable && !default_rate_is_usable)
1479 desired_rate = alternate_rate;
1481 desired_rate = default_rate;
1484 if (desired_rate == s->sample_spec.rate)
1487 if (!passthrough && pa_sink_used_by(s) > 0)
1490 pa_log_debug("Suspending sink %s due to changing the sample rate.", s->name);
1491 pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
1493 if (s->update_rate(s, desired_rate) >= 0) {
1494 /* update monitor source as well */
1495 if (s->monitor_source && !passthrough)
1496 pa_source_update_rate(s->monitor_source, desired_rate, false);
1497 pa_log_info("Changed sampling rate successfully");
1499 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1500 if (i->state == PA_SINK_INPUT_CORKED)
1501 pa_sink_input_update_rate(i);
1507 pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
1512 /* Called from main thread */
1513 pa_usec_t pa_sink_get_latency(pa_sink *s) {
1516 pa_sink_assert_ref(s);
1517 pa_assert_ctl_context();
1518 pa_assert(PA_SINK_IS_LINKED(s->state));
1520 /* The returned value is supposed to be in the time domain of the sound card! */
1522 if (s->state == PA_SINK_SUSPENDED)
1525 if (!(s->flags & PA_SINK_LATENCY))
1528 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
1530 /* the return value is unsigned, so check that the offset can be added to usec without
1532 if (-s->port_latency_offset <= usec)
1533 usec += s->port_latency_offset;
1537 return (pa_usec_t)usec;
1540 /* Called from IO thread */
1541 int64_t pa_sink_get_latency_within_thread(pa_sink *s, bool allow_negative) {
1545 pa_sink_assert_ref(s);
1546 pa_sink_assert_io_context(s);
1547 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1549 /* The returned value is supposed to be in the time domain of the sound card! */
1551 if (s->thread_info.state == PA_SINK_SUSPENDED)
1554 if (!(s->flags & PA_SINK_LATENCY))
1557 o = PA_MSGOBJECT(s);
1559 /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
1561 o->process_msg(o, PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL);
1563 /* If allow_negative is false, the call should only return positive values, */
1564 usec += s->thread_info.port_latency_offset;
1565 if (!allow_negative && usec < 0)
1571 /* Called from the main thread (and also from the IO thread while the main
1572 * thread is waiting).
1574 * When a sink uses volume sharing, it never has the PA_SINK_FLAT_VOLUME flag
1575 * set. Instead, flat volume mode is detected by checking whether the root sink
1576 * has the flag set. */
1577 bool pa_sink_flat_volume_enabled(pa_sink *s) {
1578 pa_sink_assert_ref(s);
1580 s = pa_sink_get_master(s);
1583 return (s->flags & PA_SINK_FLAT_VOLUME);
1588 /* Called from the main thread (and also from the IO thread while the main
1589 * thread is waiting). */
1590 pa_sink *pa_sink_get_master(pa_sink *s) {
1591 pa_sink_assert_ref(s);
1593 while (s && (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1594 if (PA_UNLIKELY(!s->input_to_master))
1597 s = s->input_to_master->sink;
1603 /* Called from main context */
1604 bool pa_sink_is_filter(pa_sink *s) {
1605 pa_sink_assert_ref(s);
1607 return (s->input_to_master != NULL);
1610 /* Called from main context */
1611 bool pa_sink_is_passthrough(pa_sink *s) {
1612 pa_sink_input *alt_i;
1615 pa_sink_assert_ref(s);
1617 /* one and only one PASSTHROUGH input can possibly be connected */
1618 if (pa_idxset_size(s->inputs) == 1) {
1619 alt_i = pa_idxset_first(s->inputs, &idx);
1621 if (pa_sink_input_is_passthrough(alt_i))
1628 /* Called from main context */
1629 void pa_sink_enter_passthrough(pa_sink *s) {
1632 /* disable the monitor in passthrough mode */
1633 if (s->monitor_source) {
1634 pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name);
1635 pa_source_suspend(s->monitor_source, true, PA_SUSPEND_PASSTHROUGH);
1638 /* set the volume to NORM */
1639 s->saved_volume = *pa_sink_get_volume(s, true);
1640 s->saved_save_volume = s->save_volume;
1642 pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
1643 pa_sink_set_volume(s, &volume, true, false);
1646 /* Called from main context */
1647 void pa_sink_leave_passthrough(pa_sink *s) {
1648 /* Unsuspend monitor */
1649 if (s->monitor_source) {
1650 pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
1651 pa_source_suspend(s->monitor_source, false, PA_SUSPEND_PASSTHROUGH);
1654 /* Restore sink volume to what it was before we entered passthrough mode */
1655 pa_sink_set_volume(s, &s->saved_volume, true, s->saved_save_volume);
1657 pa_cvolume_init(&s->saved_volume);
1658 s->saved_save_volume = false;
1661 /* Called from main context. */
1662 static void compute_reference_ratio(pa_sink_input *i) {
1664 pa_cvolume remapped;
1668 pa_assert(pa_sink_flat_volume_enabled(i->sink));
1671 * Calculates the reference ratio from the sink's reference
1672 * volume. This basically calculates:
1674 * i->reference_ratio = i->volume / i->sink->reference_volume
1677 remapped = i->sink->reference_volume;
1678 pa_cvolume_remap(&remapped, &i->sink->channel_map, &i->channel_map);
1680 ratio = i->reference_ratio;
1682 for (c = 0; c < i->sample_spec.channels; c++) {
1684 /* We don't update when the sink volume is 0 anyway */
1685 if (remapped.values[c] <= PA_VOLUME_MUTED)
1688 /* Don't update the reference ratio unless necessary */
1689 if (pa_sw_volume_multiply(
1691 remapped.values[c]) == i->volume.values[c])
1694 ratio.values[c] = pa_sw_volume_divide(
1695 i->volume.values[c],
1696 remapped.values[c]);
1699 pa_sink_input_set_reference_ratio(i, &ratio);
1702 /* Called from main context. Only called for the root sink in volume sharing
1703 * cases, except for internal recursive calls. */
1704 static void compute_reference_ratios(pa_sink *s) {
1708 pa_sink_assert_ref(s);
1709 pa_assert_ctl_context();
1710 pa_assert(PA_SINK_IS_LINKED(s->state));
1711 pa_assert(pa_sink_flat_volume_enabled(s));
1713 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1714 compute_reference_ratio(i);
1716 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1717 compute_reference_ratios(i->origin_sink);
1721 /* Called from main context. Only called for the root sink in volume sharing
1722 * cases, except for internal recursive calls. */
1723 static void compute_real_ratios(pa_sink *s) {
1727 pa_sink_assert_ref(s);
1728 pa_assert_ctl_context();
1729 pa_assert(PA_SINK_IS_LINKED(s->state));
1730 pa_assert(pa_sink_flat_volume_enabled(s));
1732 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1734 pa_cvolume remapped;
1736 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1737 /* The origin sink uses volume sharing, so this input's real ratio
1738 * is handled as a special case - the real ratio must be 0 dB, and
1739 * as a result i->soft_volume must equal i->volume_factor. */
1740 pa_cvolume_reset(&i->real_ratio, i->real_ratio.channels);
1741 i->soft_volume = i->volume_factor;
1743 compute_real_ratios(i->origin_sink);
1749 * This basically calculates:
1751 * i->real_ratio := i->volume / s->real_volume
1752 * i->soft_volume := i->real_ratio * i->volume_factor
1755 remapped = s->real_volume;
1756 pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1758 i->real_ratio.channels = i->sample_spec.channels;
1759 i->soft_volume.channels = i->sample_spec.channels;
1761 for (c = 0; c < i->sample_spec.channels; c++) {
1763 if (remapped.values[c] <= PA_VOLUME_MUTED) {
1764 /* We leave i->real_ratio untouched */
1765 i->soft_volume.values[c] = PA_VOLUME_MUTED;
1769 /* Don't lose accuracy unless necessary */
1770 if (pa_sw_volume_multiply(
1771 i->real_ratio.values[c],
1772 remapped.values[c]) != i->volume.values[c])
1774 i->real_ratio.values[c] = pa_sw_volume_divide(
1775 i->volume.values[c],
1776 remapped.values[c]);
1778 i->soft_volume.values[c] = pa_sw_volume_multiply(
1779 i->real_ratio.values[c],
1780 i->volume_factor.values[c]);
1783 /* We don't copy the soft_volume to the thread_info data
1784 * here. That must be done by the caller */
1788 static pa_cvolume *cvolume_remap_minimal_impact(
1790 const pa_cvolume *template,
1791 const pa_channel_map *from,
1792 const pa_channel_map *to) {
1797 pa_assert(template);
1800 pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
1801 pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
1803 /* Much like pa_cvolume_remap(), but tries to minimize impact when
1804 * mapping from sink input to sink volumes:
1806 * If template is a possible remapping from v it is used instead
1807 * of remapping anew.
1809 * If the channel maps don't match we set an all-channel volume on
1810 * the sink to ensure that changing a volume on one stream has no
1811 * effect that cannot be compensated for in another stream that
1812 * does not have the same channel map as the sink. */
1814 if (pa_channel_map_equal(from, to))
1818 if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
1823 pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
1827 /* Called from main thread. Only called for the root sink in volume sharing
1828 * cases, except for internal recursive calls. */
1829 static void get_maximum_input_volume(pa_sink *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
1833 pa_sink_assert_ref(s);
1834 pa_assert(max_volume);
1835 pa_assert(channel_map);
1836 pa_assert(pa_sink_flat_volume_enabled(s));
1838 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1839 pa_cvolume remapped;
1841 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1842 get_maximum_input_volume(i->origin_sink, max_volume, channel_map);
1844 /* Ignore this input. The origin sink uses volume sharing, so this
1845 * input's volume will be set to be equal to the root sink's real
1846 * volume. Obviously this input's current volume must not then
1847 * affect what the root sink's real volume will be. */
1851 remapped = i->volume;
1852 cvolume_remap_minimal_impact(&remapped, max_volume, &i->channel_map, channel_map);
1853 pa_cvolume_merge(max_volume, max_volume, &remapped);
1857 /* Called from main thread. Only called for the root sink in volume sharing
1858 * cases, except for internal recursive calls. */
1859 static bool has_inputs(pa_sink *s) {
1863 pa_sink_assert_ref(s);
1865 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1866 if (!i->origin_sink || !(i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || has_inputs(i->origin_sink))
1873 /* Called from main thread. Only called for the root sink in volume sharing
1874 * cases, except for internal recursive calls. */
1875 static void update_real_volume(pa_sink *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
1879 pa_sink_assert_ref(s);
1880 pa_assert(new_volume);
1881 pa_assert(channel_map);
1883 s->real_volume = *new_volume;
1884 pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
1886 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1887 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1888 if (pa_sink_flat_volume_enabled(s)) {
1889 pa_cvolume new_input_volume;
1891 /* Follow the root sink's real volume. */
1892 new_input_volume = *new_volume;
1893 pa_cvolume_remap(&new_input_volume, channel_map, &i->channel_map);
1894 pa_sink_input_set_volume_direct(i, &new_input_volume);
1895 compute_reference_ratio(i);
1898 update_real_volume(i->origin_sink, new_volume, channel_map);
1903 /* Called from main thread. Only called for the root sink in shared volume
1905 static void compute_real_volume(pa_sink *s) {
1906 pa_sink_assert_ref(s);
1907 pa_assert_ctl_context();
1908 pa_assert(PA_SINK_IS_LINKED(s->state));
1909 pa_assert(pa_sink_flat_volume_enabled(s));
1910 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
1912 /* This determines the maximum volume of all streams and sets
1913 * s->real_volume accordingly. */
1915 if (!has_inputs(s)) {
1916 /* In the special case that we have no sink inputs we leave the
1917 * volume unmodified. */
1918 update_real_volume(s, &s->reference_volume, &s->channel_map);
1922 pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1924 /* First let's determine the new maximum volume of all inputs
1925 * connected to this sink */
1926 get_maximum_input_volume(s, &s->real_volume, &s->channel_map);
1927 update_real_volume(s, &s->real_volume, &s->channel_map);
1929 /* Then, let's update the real ratios/soft volumes of all inputs
1930 * connected to this sink */
1931 compute_real_ratios(s);
1934 /* Called from main thread. Only called for the root sink in shared volume
1935 * cases, except for internal recursive calls. */
1936 static void propagate_reference_volume(pa_sink *s) {
1940 pa_sink_assert_ref(s);
1941 pa_assert_ctl_context();
1942 pa_assert(PA_SINK_IS_LINKED(s->state));
1943 pa_assert(pa_sink_flat_volume_enabled(s));
1945 /* This is called whenever the sink volume changes that is not
1946 * caused by a sink input volume change. We need to fix up the
1947 * sink input volumes accordingly */
1949 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1950 pa_cvolume new_volume;
1952 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1953 propagate_reference_volume(i->origin_sink);
1955 /* Since the origin sink uses volume sharing, this input's volume
1956 * needs to be updated to match the root sink's real volume, but
1957 * that will be done later in update_shared_real_volume(). */
1961 /* This basically calculates:
1963 * i->volume := s->reference_volume * i->reference_ratio */
1965 new_volume = s->reference_volume;
1966 pa_cvolume_remap(&new_volume, &s->channel_map, &i->channel_map);
1967 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
1968 pa_sink_input_set_volume_direct(i, &new_volume);
1972 /* Called from main thread. Only called for the root sink in volume sharing
1973 * cases, except for internal recursive calls. The return value indicates
1974 * whether any reference volume actually changed. */
1975 static bool update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_channel_map *channel_map, bool save) {
1977 bool reference_volume_changed;
1981 pa_sink_assert_ref(s);
1982 pa_assert(PA_SINK_IS_LINKED(s->state));
1984 pa_assert(channel_map);
1985 pa_assert(pa_cvolume_valid(v));
1988 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
1990 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
1991 pa_sink_set_reference_volume_direct(s, &volume);
1993 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
1995 if (!reference_volume_changed && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1996 /* If the root sink's volume doesn't change, then there can't be any
1997 * changes in the other sinks in the sink tree either.
1999 * It's probably theoretically possible that even if the root sink's
2000 * volume changes slightly, some filter sink doesn't change its volume
2001 * due to rounding errors. If that happens, we still want to propagate
2002 * the changed root sink volume to the sinks connected to the
2003 * intermediate sink that didn't change its volume. This theoretical
2004 * possibility is the reason why we have that !(s->flags &
2005 * PA_SINK_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
2006 * notice even if we returned here false always if
2007 * reference_volume_changed is false. */
2010 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2011 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2012 update_reference_volume(i->origin_sink, v, channel_map, false);
2018 /* Called from main thread */
2019 void pa_sink_set_volume(
2021 const pa_cvolume *volume,
2025 pa_cvolume new_reference_volume;
2028 pa_sink_assert_ref(s);
2029 pa_assert_ctl_context();
2030 pa_assert(PA_SINK_IS_LINKED(s->state));
2031 pa_assert(!volume || pa_cvolume_valid(volume));
2032 pa_assert(volume || pa_sink_flat_volume_enabled(s));
2033 pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
2035 /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
2036 * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
2037 if (pa_sink_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
2038 pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input");
2042 /* In case of volume sharing, the volume is set for the root sink first,
2043 * from which it's then propagated to the sharing sinks. */
2044 root_sink = pa_sink_get_master(s);
2046 if (PA_UNLIKELY(!root_sink))
2049 /* As a special exception we accept mono volumes on all sinks --
2050 * even on those with more complex channel maps */
2053 if (pa_cvolume_compatible(volume, &s->sample_spec))
2054 new_reference_volume = *volume;
2056 new_reference_volume = s->reference_volume;
2057 pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
2060 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2062 if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) {
2063 if (pa_sink_flat_volume_enabled(root_sink)) {
2064 /* OK, propagate this volume change back to the inputs */
2065 propagate_reference_volume(root_sink);
2067 /* And now recalculate the real volume */
2068 compute_real_volume(root_sink);
2070 update_real_volume(root_sink, &root_sink->reference_volume, &root_sink->channel_map);
2074 /* If volume is NULL we synchronize the sink's real and
2075 * reference volumes with the stream volumes. */
2077 pa_assert(pa_sink_flat_volume_enabled(root_sink));
2079 /* Ok, let's determine the new real volume */
2080 compute_real_volume(root_sink);
2082 /* Let's 'push' the reference volume if necessary */
2083 pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_sink->real_volume);
2084 /* If the sink and its root don't have the same number of channels, we need to remap */
2085 if (s != root_sink && !pa_channel_map_equal(&s->channel_map, &root_sink->channel_map))
2086 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2087 update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save);
2089 /* Now that the reference volume is updated, we can update the streams'
2090 * reference ratios. */
2091 compute_reference_ratios(root_sink);
2094 if (root_sink->set_volume) {
2095 /* If we have a function set_volume(), then we do not apply a
2096 * soft volume by default. However, set_volume() is free to
2097 * apply one to root_sink->soft_volume */
2099 pa_cvolume_reset(&root_sink->soft_volume, root_sink->sample_spec.channels);
2100 if (!(root_sink->flags & PA_SINK_DEFERRED_VOLUME))
2101 root_sink->set_volume(root_sink);
2104 /* If we have no function set_volume(), then the soft volume
2105 * becomes the real volume */
2106 root_sink->soft_volume = root_sink->real_volume;
2108 /* This tells the sink that soft volume and/or real volume changed */
2110 pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
2113 /* Called from the io thread if sync volume is used, otherwise from the main thread.
2114 * Only to be called by sink implementor */
2115 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
2117 pa_sink_assert_ref(s);
2118 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2120 if (s->flags & PA_SINK_DEFERRED_VOLUME)
2121 pa_sink_assert_io_context(s);
2123 pa_assert_ctl_context();
2126 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
2128 s->soft_volume = *volume;
2130 if (PA_SINK_IS_LINKED(s->state) && !(s->flags & PA_SINK_DEFERRED_VOLUME))
2131 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
2133 s->thread_info.soft_volume = s->soft_volume;
2136 /* Called from the main thread. Only called for the root sink in volume sharing
2137 * cases, except for internal recursive calls. */
2138 static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {
2142 pa_sink_assert_ref(s);
2143 pa_assert(old_real_volume);
2144 pa_assert_ctl_context();
2145 pa_assert(PA_SINK_IS_LINKED(s->state));
2147 /* This is called when the hardware's real volume changes due to
2148 * some external event. We copy the real volume into our
2149 * reference volume and then rebuild the stream volumes based on
2150 * i->real_ratio which should stay fixed. */
2152 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
2153 if (pa_cvolume_equal(old_real_volume, &s->real_volume))
2156 /* 1. Make the real volume the reference volume */
2157 update_reference_volume(s, &s->real_volume, &s->channel_map, true);
2160 if (pa_sink_flat_volume_enabled(s)) {
2162 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2163 pa_cvolume new_volume;
2165 /* 2. Since the sink's reference and real volumes are equal
2166 * now our ratios should be too. */
2167 pa_sink_input_set_reference_ratio(i, &i->real_ratio);
2169 /* 3. Recalculate the new stream reference volume based on the
2170 * reference ratio and the sink's reference volume.
2172 * This basically calculates:
2174 * i->volume = s->reference_volume * i->reference_ratio
2176 * This is identical to propagate_reference_volume() */
2177 new_volume = s->reference_volume;
2178 pa_cvolume_remap(&new_volume, &s->channel_map, &i->channel_map);
2179 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
2180 pa_sink_input_set_volume_direct(i, &new_volume);
2182 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2183 propagate_real_volume(i->origin_sink, old_real_volume);
2187 /* Something got changed in the hardware. It probably makes sense
2188 * to save changed hw settings given that hw volume changes not
2189 * triggered by PA are almost certainly done by the user. */
2190 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2191 s->save_volume = true;
2194 /* Called from io thread */
2195 void pa_sink_update_volume_and_mute(pa_sink *s) {
2197 pa_sink_assert_io_context(s);
2199 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
2202 /* Called from main thread */
2203 const pa_cvolume *pa_sink_get_volume(pa_sink *s, bool force_refresh) {
2204 pa_sink_assert_ref(s);
2205 pa_assert_ctl_context();
2206 pa_assert(PA_SINK_IS_LINKED(s->state));
2208 if (s->refresh_volume || force_refresh) {
2209 struct pa_cvolume old_real_volume;
2211 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2213 old_real_volume = s->real_volume;
2215 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume)
2218 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
2220 update_real_volume(s, &s->real_volume, &s->channel_map);
2221 propagate_real_volume(s, &old_real_volume);
2224 return &s->reference_volume;
2227 /* Called from main thread. In volume sharing cases, only the root sink may
2229 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {
2230 pa_cvolume old_real_volume;
2232 pa_sink_assert_ref(s);
2233 pa_assert_ctl_context();
2234 pa_assert(PA_SINK_IS_LINKED(s->state));
2235 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2237 /* The sink implementor may call this if the volume changed to make sure everyone is notified */
2239 old_real_volume = s->real_volume;
2240 update_real_volume(s, new_real_volume, &s->channel_map);
2241 propagate_real_volume(s, &old_real_volume);
2244 /* Called from main thread */
2245 void pa_sink_set_mute(pa_sink *s, bool mute, bool save) {
2248 pa_sink_assert_ref(s);
2249 pa_assert_ctl_context();
2251 old_muted = s->muted;
2253 if (mute == old_muted) {
2254 s->save_muted |= save;
2259 s->save_muted = save;
2261 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute) {
2262 s->set_mute_in_progress = true;
2264 s->set_mute_in_progress = false;
2267 if (!PA_SINK_IS_LINKED(s->state))
2270 pa_log_debug("The mute of sink %s changed from %s to %s.", s->name, pa_yes_no(old_muted), pa_yes_no(mute));
2271 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
2272 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2273 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED], s);
2276 /* Called from main thread */
2277 bool pa_sink_get_mute(pa_sink *s, bool force_refresh) {
2279 pa_sink_assert_ref(s);
2280 pa_assert_ctl_context();
2281 pa_assert(PA_SINK_IS_LINKED(s->state));
2283 if ((s->refresh_muted || force_refresh) && s->get_mute) {
2286 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
2287 if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, &mute, 0, NULL) >= 0)
2288 pa_sink_mute_changed(s, mute);
2290 if (s->get_mute(s, &mute) >= 0)
2291 pa_sink_mute_changed(s, mute);
2298 /* Called from main thread */
2299 void pa_sink_mute_changed(pa_sink *s, bool new_muted) {
2300 pa_sink_assert_ref(s);
2301 pa_assert_ctl_context();
2302 pa_assert(PA_SINK_IS_LINKED(s->state));
2304 if (s->set_mute_in_progress)
2307 /* pa_sink_set_mute() does this same check, so this may appear redundant,
2308 * but we must have this here also, because the save parameter of
2309 * pa_sink_set_mute() would otherwise have unintended side effects (saving
2310 * the mute state when it shouldn't be saved). */
2311 if (new_muted == s->muted)
2314 pa_sink_set_mute(s, new_muted, true);
2317 /* Called from main thread */
2318 bool pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
2319 pa_sink_assert_ref(s);
2320 pa_assert_ctl_context();
2323 pa_proplist_update(s->proplist, mode, p);
2325 if (PA_SINK_IS_LINKED(s->state)) {
2326 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2327 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2333 /* Called from main thread */
2334 /* FIXME -- this should be dropped and be merged into pa_sink_update_proplist() */
2335 void pa_sink_set_description(pa_sink *s, const char *description) {
2337 pa_sink_assert_ref(s);
2338 pa_assert_ctl_context();
2340 if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
2343 old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2345 if (old && description && pa_streq(old, description))
2349 pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
2351 pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2353 if (s->monitor_source) {
2356 n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
2357 pa_source_set_description(s->monitor_source, n);
2361 if (PA_SINK_IS_LINKED(s->state)) {
2362 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2363 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2367 /* Called from main thread */
2368 unsigned pa_sink_linked_by(pa_sink *s) {
2371 pa_sink_assert_ref(s);
2372 pa_assert_ctl_context();
2373 pa_assert(PA_SINK_IS_LINKED(s->state));
2375 ret = pa_idxset_size(s->inputs);
2377 /* We add in the number of streams connected to us here. Please
2378 * note the asymmetry to pa_sink_used_by()! */
2380 if (s->monitor_source)
2381 ret += pa_source_linked_by(s->monitor_source);
2386 /* Called from main thread */
2387 unsigned pa_sink_used_by(pa_sink *s) {
2390 pa_sink_assert_ref(s);
2391 pa_assert_ctl_context();
2392 pa_assert(PA_SINK_IS_LINKED(s->state));
2394 ret = pa_idxset_size(s->inputs);
2395 pa_assert(ret >= s->n_corked);
2397 /* Streams connected to our monitor source do not matter for
2398 * pa_sink_used_by()!.*/
2400 return ret - s->n_corked;
2403 /* Called from main thread */
2404 unsigned pa_sink_check_suspend(pa_sink *s, pa_sink_input *ignore_input, pa_source_output *ignore_output) {
2409 pa_sink_assert_ref(s);
2410 pa_assert_ctl_context();
2412 if (!PA_SINK_IS_LINKED(s->state))
2417 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2418 pa_sink_input_state_t st;
2420 if (i == ignore_input)
2423 st = pa_sink_input_get_state(i);
2425 /* We do not assert here. It is perfectly valid for a sink input to
2426 * be in the INIT state (i.e. created, marked done but not yet put)
2427 * and we should not care if it's unlinked as it won't contribute
2428 * towards our busy status.
2430 if (!PA_SINK_INPUT_IS_LINKED(st))
2433 if (st == PA_SINK_INPUT_CORKED)
2436 if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
2442 if (s->monitor_source)
2443 ret += pa_source_check_suspend(s->monitor_source, ignore_output);
2448 /* Called from the IO thread */
2449 static void sync_input_volumes_within_thread(pa_sink *s) {
2453 pa_sink_assert_ref(s);
2454 pa_sink_assert_io_context(s);
2456 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2457 if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
2460 i->thread_info.soft_volume = i->soft_volume;
2461 pa_sink_input_request_rewind(i, 0, true, false, false);
2465 /* Called from the IO thread. Only called for the root sink in volume sharing
2466 * cases, except for internal recursive calls. */
2467 static void set_shared_volume_within_thread(pa_sink *s) {
2468 pa_sink_input *i = NULL;
2471 pa_sink_assert_ref(s);
2473 PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2475 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2476 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2477 set_shared_volume_within_thread(i->origin_sink);
2481 /* Called from IO thread, except when it is not */
2482 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2483 pa_sink *s = PA_SINK(o);
2484 pa_sink_assert_ref(s);
2486 switch ((pa_sink_message_t) code) {
2488 case PA_SINK_MESSAGE_ADD_INPUT: {
2489 pa_sink_input *i = PA_SINK_INPUT(userdata);
2491 /* If you change anything here, make sure to change the
2492 * sink input handling a few lines down at
2493 * PA_SINK_MESSAGE_FINISH_MOVE, too. */
2495 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2497 /* Since the caller sleeps in pa_sink_input_put(), we can
2498 * safely access data outside of thread_info even though
2501 if ((i->thread_info.sync_prev = i->sync_prev)) {
2502 pa_assert(i->sink == i->thread_info.sync_prev->sink);
2503 pa_assert(i->sync_prev->sync_next == i);
2504 i->thread_info.sync_prev->thread_info.sync_next = i;
2507 if ((i->thread_info.sync_next = i->sync_next)) {
2508 pa_assert(i->sink == i->thread_info.sync_next->sink);
2509 pa_assert(i->sync_next->sync_prev == i);
2510 i->thread_info.sync_next->thread_info.sync_prev = i;
2513 pa_sink_input_attach(i);
2515 pa_sink_input_set_state_within_thread(i, i->state);
2517 /* The requested latency of the sink input needs to be fixed up and
2518 * then configured on the sink. If this causes the sink latency to
2519 * go down, the sink implementor is responsible for doing a rewind
2520 * in the update_requested_latency() callback to ensure that the
2521 * sink buffer doesn't contain more data than what the new latency
2524 * XXX: Does it really make sense to push this responsibility to
2525 * the sink implementors? Wouldn't it be better to do it once in
2526 * the core than many times in the modules? */
2528 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2529 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2531 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2532 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2534 /* We don't rewind here automatically. This is left to the
2535 * sink input implementor because some sink inputs need a
2536 * slow start, i.e. need some time to buffer client
2537 * samples before beginning streaming.
2539 * XXX: Does it really make sense to push this functionality to
2540 * the sink implementors? Wouldn't it be better to do it once in
2541 * the core than many times in the modules? */
2543 /* In flat volume mode we need to update the volume as
2545 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2548 case PA_SINK_MESSAGE_REMOVE_INPUT: {
2549 pa_sink_input *i = PA_SINK_INPUT(userdata);
2551 /* If you change anything here, make sure to change the
2552 * sink input handling a few lines down at
2553 * PA_SINK_MESSAGE_START_MOVE, too. */
2555 pa_sink_input_detach(i);
2557 pa_sink_input_set_state_within_thread(i, i->state);
2559 /* Since the caller sleeps in pa_sink_input_unlink(),
2560 * we can safely access data outside of thread_info even
2561 * though it is mutable */
2563 pa_assert(!i->sync_prev);
2564 pa_assert(!i->sync_next);
2566 if (i->thread_info.sync_prev) {
2567 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
2568 i->thread_info.sync_prev = NULL;
2571 if (i->thread_info.sync_next) {
2572 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
2573 i->thread_info.sync_next = NULL;
2576 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2577 pa_sink_invalidate_requested_latency(s, true);
2578 pa_sink_request_rewind(s, (size_t) -1);
2580 /* In flat volume mode we need to update the volume as
2582 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2585 case PA_SINK_MESSAGE_START_MOVE: {
2586 pa_sink_input *i = PA_SINK_INPUT(userdata);
2588 /* We don't support moving synchronized streams. */
2589 pa_assert(!i->sync_prev);
2590 pa_assert(!i->sync_next);
2591 pa_assert(!i->thread_info.sync_next);
2592 pa_assert(!i->thread_info.sync_prev);
2594 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2596 size_t sink_nbytes, total_nbytes;
2598 /* The old sink probably has some audio from this
2599 * stream in its buffer. We want to "take it back" as
2600 * much as possible and play it to the new sink. We
2601 * don't know at this point how much the old sink can
2602 * rewind. We have to pick something, and that
2603 * something is the full latency of the old sink here.
2604 * So we rewind the stream buffer by the sink latency
2605 * amount, which may be more than what we should
2606 * rewind. This can result in a chunk of audio being
2607 * played both to the old sink and the new sink.
2609 * FIXME: Fix this code so that we don't have to make
2610 * guesses about how much the sink will actually be
2611 * able to rewind. If someone comes up with a solution
2612 * for this, something to note is that the part of the
2613 * latency that the old sink couldn't rewind should
2614 * ideally be compensated after the stream has moved
2615 * to the new sink by adding silence. The new sink
2616 * most likely can't start playing the moved stream
2617 * immediately, and that gap should be removed from
2618 * the "compensation silence" (at least at the time of
2619 * writing this, the move finish code will actually
2620 * already take care of dropping the new sink's
2621 * unrewindable latency, so taking into account the
2622 * unrewindable latency of the old sink is the only
2625 * The render_memblockq contents are discarded,
2626 * because when the sink changes, the format of the
2627 * audio stored in the render_memblockq may change
2628 * too, making the stored audio invalid. FIXME:
2629 * However, the read and write indices are moved back
2630 * the same amount, so if they are not the same now,
2631 * they won't be the same after the rewind either. If
2632 * the write index of the render_memblockq is ahead of
2633 * the read index, then the render_memblockq will feed
2634 * the new sink some silence first, which it shouldn't
2635 * do. The write index should be flushed to be the
2636 * same as the read index. */
2638 /* Get the latency of the sink */
2639 usec = pa_sink_get_latency_within_thread(s, false);
2640 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2641 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
2643 if (total_nbytes > 0) {
2644 i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
2645 i->thread_info.rewrite_flush = true;
2646 pa_sink_input_process_rewind(i, sink_nbytes);
2650 pa_sink_input_detach(i);
2652 /* Let's remove the sink input ...*/
2653 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2655 pa_sink_invalidate_requested_latency(s, true);
2657 pa_log_debug("Requesting rewind due to started move");
2658 pa_sink_request_rewind(s, (size_t) -1);
2660 /* In flat volume mode we need to update the volume as
2662 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2665 case PA_SINK_MESSAGE_FINISH_MOVE: {
2666 pa_sink_input *i = PA_SINK_INPUT(userdata);
2668 /* We don't support moving synchronized streams. */
2669 pa_assert(!i->sync_prev);
2670 pa_assert(!i->sync_next);
2671 pa_assert(!i->thread_info.sync_next);
2672 pa_assert(!i->thread_info.sync_prev);
2674 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2676 pa_sink_input_attach(i);
2678 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2682 /* In the ideal case the new sink would start playing
2683 * the stream immediately. That requires the sink to
2684 * be able to rewind all of its latency, which usually
2685 * isn't possible, so there will probably be some gap
2686 * before the moved stream becomes audible. We then
2687 * have two possibilities: 1) start playing the stream
2688 * from where it is now, or 2) drop the unrewindable
2689 * latency of the sink from the stream. With option 1
2690 * we won't lose any audio but the stream will have a
2691 * pause. With option 2 we may lose some audio but the
2692 * stream time will be somewhat in sync with the wall
2693 * clock. Lennart seems to have chosen option 2 (one
2694 * of the reasons might have been that option 1 is
2695 * actually much harder to implement), so we drop the
2696 * latency of the new sink from the moved stream and
2697 * hope that the sink will undo most of that in the
2700 /* Get the latency of the sink */
2701 usec = pa_sink_get_latency_within_thread(s, false);
2702 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2705 pa_sink_input_drop(i, nbytes);
2707 pa_log_debug("Requesting rewind due to finished move");
2708 pa_sink_request_rewind(s, nbytes);
2711 /* Updating the requested sink latency has to be done
2712 * after the sink rewind request, not before, because
2713 * otherwise the sink may limit the rewind amount
2716 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2717 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2719 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2720 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2722 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2725 case PA_SINK_MESSAGE_SET_SHARED_VOLUME: {
2726 pa_sink *root_sink = pa_sink_get_master(s);
2728 if (PA_LIKELY(root_sink))
2729 set_shared_volume_within_thread(root_sink);
2734 case PA_SINK_MESSAGE_SET_VOLUME_SYNCED:
2736 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
2738 pa_sink_volume_change_push(s);
2740 /* Fall through ... */
2742 case PA_SINK_MESSAGE_SET_VOLUME:
2744 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2745 s->thread_info.soft_volume = s->soft_volume;
2746 pa_sink_request_rewind(s, (size_t) -1);
2749 /* Fall through ... */
2751 case PA_SINK_MESSAGE_SYNC_VOLUMES:
2752 sync_input_volumes_within_thread(s);
2755 case PA_SINK_MESSAGE_GET_VOLUME:
2757 if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
2759 pa_sink_volume_change_flush(s);
2760 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2763 /* In case sink implementor reset SW volume. */
2764 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2765 s->thread_info.soft_volume = s->soft_volume;
2766 pa_sink_request_rewind(s, (size_t) -1);
2771 case PA_SINK_MESSAGE_SET_MUTE:
2773 if (s->thread_info.soft_muted != s->muted) {
2774 s->thread_info.soft_muted = s->muted;
2775 pa_sink_request_rewind(s, (size_t) -1);
2778 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->set_mute)
2783 case PA_SINK_MESSAGE_GET_MUTE:
2785 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->get_mute)
2786 return s->get_mute(s, userdata);
2790 case PA_SINK_MESSAGE_SET_STATE: {
2792 bool suspend_change =
2793 (s->thread_info.state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2794 (PA_SINK_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SINK_SUSPENDED);
2796 s->thread_info.state = PA_PTR_TO_UINT(userdata);
2798 if (s->thread_info.state == PA_SINK_SUSPENDED) {
2799 s->thread_info.rewind_nbytes = 0;
2800 s->thread_info.rewind_requested = false;
2803 if (suspend_change) {
2807 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
2808 if (i->suspend_within_thread)
2809 i->suspend_within_thread(i, s->thread_info.state == PA_SINK_SUSPENDED);
2815 case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
2817 pa_usec_t *usec = userdata;
2818 *usec = pa_sink_get_requested_latency_within_thread(s);
2820 /* Yes, that's right, the IO thread will see -1 when no
2821 * explicit requested latency is configured, the main
2822 * thread will see max_latency */
2823 if (*usec == (pa_usec_t) -1)
2824 *usec = s->thread_info.max_latency;
2829 case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
2830 pa_usec_t *r = userdata;
2832 pa_sink_set_latency_range_within_thread(s, r[0], r[1]);
2837 case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
2838 pa_usec_t *r = userdata;
2840 r[0] = s->thread_info.min_latency;
2841 r[1] = s->thread_info.max_latency;
2846 case PA_SINK_MESSAGE_GET_FIXED_LATENCY:
2848 *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2851 case PA_SINK_MESSAGE_SET_FIXED_LATENCY:
2853 pa_sink_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2856 case PA_SINK_MESSAGE_GET_MAX_REWIND:
2858 *((size_t*) userdata) = s->thread_info.max_rewind;
2861 case PA_SINK_MESSAGE_GET_MAX_REQUEST:
2863 *((size_t*) userdata) = s->thread_info.max_request;
2866 case PA_SINK_MESSAGE_SET_MAX_REWIND:
2868 pa_sink_set_max_rewind_within_thread(s, (size_t) offset);
2871 case PA_SINK_MESSAGE_SET_MAX_REQUEST:
2873 pa_sink_set_max_request_within_thread(s, (size_t) offset);
2876 case PA_SINK_MESSAGE_SET_PORT:
2878 pa_assert(userdata);
2880 struct sink_message_set_port *msg_data = userdata;
2881 msg_data->ret = s->set_port(s, msg_data->port);
2885 case PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2886 /* This message is sent from IO-thread and handled in main thread. */
2887 pa_assert_ctl_context();
2889 /* Make sure we're not messing with main thread when no longer linked */
2890 if (!PA_SINK_IS_LINKED(s->state))
2893 pa_sink_get_volume(s, true);
2894 pa_sink_get_mute(s, true);
2897 case PA_SINK_MESSAGE_SET_PORT_LATENCY_OFFSET:
2898 s->thread_info.port_latency_offset = offset;
2901 case PA_SINK_MESSAGE_GET_LATENCY:
2902 case PA_SINK_MESSAGE_MAX:
2909 /* Called from main thread */
2910 int pa_sink_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
2915 pa_core_assert_ref(c);
2916 pa_assert_ctl_context();
2917 pa_assert(cause != 0);
2919 PA_IDXSET_FOREACH(sink, c->sinks, idx) {
2922 if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
2929 /* Called from IO thread */
2930 void pa_sink_detach_within_thread(pa_sink *s) {
2934 pa_sink_assert_ref(s);
2935 pa_sink_assert_io_context(s);
2936 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2938 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2939 pa_sink_input_detach(i);
2941 if (s->monitor_source)
2942 pa_source_detach_within_thread(s->monitor_source);
2945 /* Called from IO thread */
2946 void pa_sink_attach_within_thread(pa_sink *s) {
2950 pa_sink_assert_ref(s);
2951 pa_sink_assert_io_context(s);
2952 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2954 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2955 pa_sink_input_attach(i);
2957 if (s->monitor_source)
2958 pa_source_attach_within_thread(s->monitor_source);
2961 /* Called from IO thread */
2962 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
2963 pa_sink_assert_ref(s);
2964 pa_sink_assert_io_context(s);
2965 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2967 if (nbytes == (size_t) -1)
2968 nbytes = s->thread_info.max_rewind;
2970 nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
2972 if (s->thread_info.rewind_requested &&
2973 nbytes <= s->thread_info.rewind_nbytes)
2976 s->thread_info.rewind_nbytes = nbytes;
2977 s->thread_info.rewind_requested = true;
2979 if (s->request_rewind)
2980 s->request_rewind(s);
2983 /* Called from IO thread */
2984 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
2985 pa_usec_t result = (pa_usec_t) -1;
2988 pa_usec_t monitor_latency;
2990 pa_sink_assert_ref(s);
2991 pa_sink_assert_io_context(s);
2993 if (!(s->flags & PA_SINK_DYNAMIC_LATENCY))
2994 return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2996 if (s->thread_info.requested_latency_valid)
2997 return s->thread_info.requested_latency;
2999 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3000 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
3001 (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
3002 result = i->thread_info.requested_sink_latency;
3004 monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
3006 if (monitor_latency != (pa_usec_t) -1 &&
3007 (result == (pa_usec_t) -1 || result > monitor_latency))
3008 result = monitor_latency;
3010 if (result != (pa_usec_t) -1)
3011 result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
3013 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3014 /* Only cache if properly initialized */
3015 s->thread_info.requested_latency = result;
3016 s->thread_info.requested_latency_valid = true;
3022 /* Called from main thread */
3023 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
3026 pa_sink_assert_ref(s);
3027 pa_assert_ctl_context();
3028 pa_assert(PA_SINK_IS_LINKED(s->state));
3030 if (s->state == PA_SINK_SUSPENDED)
3033 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
3038 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3039 void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) {
3043 pa_sink_assert_ref(s);
3044 pa_sink_assert_io_context(s);
3046 if (max_rewind == s->thread_info.max_rewind)
3049 s->thread_info.max_rewind = max_rewind;
3051 if (PA_SINK_IS_LINKED(s->thread_info.state))
3052 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3053 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
3055 if (s->monitor_source)
3056 pa_source_set_max_rewind_within_thread(s->monitor_source, s->thread_info.max_rewind);
3059 /* Called from main thread */
3060 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
3061 pa_sink_assert_ref(s);
3062 pa_assert_ctl_context();
3064 if (PA_SINK_IS_LINKED(s->state))
3065 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
3067 pa_sink_set_max_rewind_within_thread(s, max_rewind);
3070 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3071 void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request) {
3074 pa_sink_assert_ref(s);
3075 pa_sink_assert_io_context(s);
3077 if (max_request == s->thread_info.max_request)
3080 s->thread_info.max_request = max_request;
3082 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3085 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3086 pa_sink_input_update_max_request(i, s->thread_info.max_request);
3090 /* Called from main thread */
3091 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
3092 pa_sink_assert_ref(s);
3093 pa_assert_ctl_context();
3095 if (PA_SINK_IS_LINKED(s->state))
3096 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REQUEST, NULL, max_request, NULL) == 0);
3098 pa_sink_set_max_request_within_thread(s, max_request);
3101 /* Called from IO thread */
3102 void pa_sink_invalidate_requested_latency(pa_sink *s, bool dynamic) {
3106 pa_sink_assert_ref(s);
3107 pa_sink_assert_io_context(s);
3109 if ((s->flags & PA_SINK_DYNAMIC_LATENCY))
3110 s->thread_info.requested_latency_valid = false;
3114 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3116 if (s->update_requested_latency)
3117 s->update_requested_latency(s);
3119 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3120 if (i->update_sink_requested_latency)
3121 i->update_sink_requested_latency(i);
3125 /* Called from main thread */
3126 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3127 pa_sink_assert_ref(s);
3128 pa_assert_ctl_context();
3130 /* min_latency == 0: no limit
3131 * min_latency anything else: specified limit
3133 * Similar for max_latency */
3135 if (min_latency < ABSOLUTE_MIN_LATENCY)
3136 min_latency = ABSOLUTE_MIN_LATENCY;
3138 if (max_latency <= 0 ||
3139 max_latency > ABSOLUTE_MAX_LATENCY)
3140 max_latency = ABSOLUTE_MAX_LATENCY;
3142 pa_assert(min_latency <= max_latency);
3144 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3145 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3146 max_latency == ABSOLUTE_MAX_LATENCY) ||
3147 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3149 if (PA_SINK_IS_LINKED(s->state)) {
3155 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
3157 pa_sink_set_latency_range_within_thread(s, min_latency, max_latency);
3160 /* Called from main thread */
3161 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
3162 pa_sink_assert_ref(s);
3163 pa_assert_ctl_context();
3164 pa_assert(min_latency);
3165 pa_assert(max_latency);
3167 if (PA_SINK_IS_LINKED(s->state)) {
3168 pa_usec_t r[2] = { 0, 0 };
3170 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
3172 *min_latency = r[0];
3173 *max_latency = r[1];
3175 *min_latency = s->thread_info.min_latency;
3176 *max_latency = s->thread_info.max_latency;
3180 /* Called from IO thread */
3181 void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3182 pa_sink_assert_ref(s);
3183 pa_sink_assert_io_context(s);
3185 pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
3186 pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
3187 pa_assert(min_latency <= max_latency);
3189 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3190 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3191 max_latency == ABSOLUTE_MAX_LATENCY) ||
3192 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3194 if (s->thread_info.min_latency == min_latency &&
3195 s->thread_info.max_latency == max_latency)
3198 s->thread_info.min_latency = min_latency;
3199 s->thread_info.max_latency = max_latency;
3201 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3205 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3206 if (i->update_sink_latency_range)
3207 i->update_sink_latency_range(i);
3210 pa_sink_invalidate_requested_latency(s, false);
3212 pa_source_set_latency_range_within_thread(s->monitor_source, min_latency, max_latency);
3215 /* Called from main thread */
3216 void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {
3217 pa_sink_assert_ref(s);
3218 pa_assert_ctl_context();
3220 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3221 pa_assert(latency == 0);
3225 if (latency < ABSOLUTE_MIN_LATENCY)
3226 latency = ABSOLUTE_MIN_LATENCY;
3228 if (latency > ABSOLUTE_MAX_LATENCY)
3229 latency = ABSOLUTE_MAX_LATENCY;
3231 if (PA_SINK_IS_LINKED(s->state))
3232 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
3234 s->thread_info.fixed_latency = latency;
3236 pa_source_set_fixed_latency(s->monitor_source, latency);
3239 /* Called from main thread */
3240 pa_usec_t pa_sink_get_fixed_latency(pa_sink *s) {
3243 pa_sink_assert_ref(s);
3244 pa_assert_ctl_context();
3246 if (s->flags & PA_SINK_DYNAMIC_LATENCY)
3249 if (PA_SINK_IS_LINKED(s->state))
3250 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
3252 latency = s->thread_info.fixed_latency;
3257 /* Called from IO thread */
3258 void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
3259 pa_sink_assert_ref(s);
3260 pa_sink_assert_io_context(s);
3262 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3263 pa_assert(latency == 0);
3264 s->thread_info.fixed_latency = 0;
3266 if (s->monitor_source)
3267 pa_source_set_fixed_latency_within_thread(s->monitor_source, 0);
3272 pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
3273 pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
3275 if (s->thread_info.fixed_latency == latency)
3278 s->thread_info.fixed_latency = latency;
3280 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3284 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3285 if (i->update_sink_fixed_latency)
3286 i->update_sink_fixed_latency(i);
3289 pa_sink_invalidate_requested_latency(s, false);
3291 pa_source_set_fixed_latency_within_thread(s->monitor_source, latency);
3294 /* Called from main context */
3295 void pa_sink_set_port_latency_offset(pa_sink *s, int64_t offset) {
3296 pa_sink_assert_ref(s);
3298 s->port_latency_offset = offset;
3300 if (PA_SINK_IS_LINKED(s->state))
3301 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT_LATENCY_OFFSET, NULL, offset, NULL) == 0);
3303 s->thread_info.port_latency_offset = offset;
3305 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_LATENCY_OFFSET_CHANGED], s);
3308 /* Called from main context */
3309 size_t pa_sink_get_max_rewind(pa_sink *s) {
3311 pa_assert_ctl_context();
3312 pa_sink_assert_ref(s);
3314 if (!PA_SINK_IS_LINKED(s->state))
3315 return s->thread_info.max_rewind;
3317 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
3322 /* Called from main context */
3323 size_t pa_sink_get_max_request(pa_sink *s) {
3325 pa_sink_assert_ref(s);
3326 pa_assert_ctl_context();
3328 if (!PA_SINK_IS_LINKED(s->state))
3329 return s->thread_info.max_request;
3331 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
3336 /* Called from main context */
3337 int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
3338 pa_device_port *port;
3341 pa_sink_assert_ref(s);
3342 pa_assert_ctl_context();
3345 pa_log_debug("set_port() operation not implemented for sink %u \"%s\"", s->index, s->name);
3346 return -PA_ERR_NOTIMPLEMENTED;
3350 return -PA_ERR_NOENTITY;
3352 if (!(port = pa_hashmap_get(s->ports, name)))
3353 return -PA_ERR_NOENTITY;
3355 if (s->active_port == port) {
3356 s->save_port = s->save_port || save;
3360 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
3361 struct sink_message_set_port msg = { .port = port, .ret = 0 };
3362 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
3366 ret = s->set_port(s, port);
3369 return -PA_ERR_NOENTITY;
3371 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3373 pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
3375 s->active_port = port;
3376 s->save_port = save;
3378 pa_sink_set_port_latency_offset(s, s->active_port->latency_offset);
3380 /* The active port affects the default sink selection. */
3381 pa_core_update_default_sink(s->core);
3383 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
3388 bool pa_device_init_icon(pa_proplist *p, bool is_sink) {
3389 const char *ff, *c, *t = NULL, *s = "", *profile, *bus;
3393 if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME))
3396 if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3398 if (pa_streq(ff, "microphone"))
3399 t = "audio-input-microphone";
3400 else if (pa_streq(ff, "webcam"))
3402 else if (pa_streq(ff, "computer"))
3404 else if (pa_streq(ff, "handset"))
3406 else if (pa_streq(ff, "portable"))
3407 t = "multimedia-player";
3408 else if (pa_streq(ff, "tv"))
3409 t = "video-display";
3412 * The following icons are not part of the icon naming spec,
3413 * because Rodney Dawes sucks as the maintainer of that spec.
3415 * http://lists.freedesktop.org/archives/xdg/2009-May/010397.html
3417 else if (pa_streq(ff, "headset"))
3418 t = "audio-headset";
3419 else if (pa_streq(ff, "headphone"))
3420 t = "audio-headphones";
3421 else if (pa_streq(ff, "speaker"))
3422 t = "audio-speakers";
3423 else if (pa_streq(ff, "hands-free"))
3424 t = "audio-handsfree";
3428 if ((c = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3429 if (pa_streq(c, "modem"))
3436 t = "audio-input-microphone";
3439 if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3440 if (strstr(profile, "analog"))
3442 else if (strstr(profile, "iec958"))
3444 else if (strstr(profile, "hdmi"))
3448 bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS);
3450 pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus));
3455 bool pa_device_init_description(pa_proplist *p, pa_card *card) {
3456 const char *s, *d = NULL, *k;
3459 if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
3463 if ((s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_DESCRIPTION)))
3467 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3468 if (pa_streq(s, "internal"))
3469 d = _("Built-in Audio");
3472 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3473 if (pa_streq(s, "modem"))
3477 d = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME);
3482 k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
3485 pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
3487 pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
3492 bool pa_device_init_intended_roles(pa_proplist *p) {
3496 if (pa_proplist_contains(p, PA_PROP_DEVICE_INTENDED_ROLES))
3499 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3500 if (pa_streq(s, "handset") || pa_streq(s, "hands-free")
3501 || pa_streq(s, "headset")) {
3502 pa_proplist_sets(p, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
3509 unsigned pa_device_init_priority(pa_proplist *p) {
3511 unsigned priority = 0;
3515 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS))) {
3517 if (pa_streq(s, "sound"))
3519 else if (!pa_streq(s, "modem"))
3523 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3525 if (pa_streq(s, "headphone"))
3527 else if (pa_streq(s, "hifi"))
3529 else if (pa_streq(s, "speaker"))
3531 else if (pa_streq(s, "portable"))
3533 else if (pa_streq(s, "internal"))
3537 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) {
3539 if (pa_streq(s, "bluetooth"))
3541 else if (pa_streq(s, "usb"))
3543 else if (pa_streq(s, "pci"))
3547 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3549 if (pa_startswith(s, "analog-"))
3551 else if (pa_startswith(s, "iec958-"))
3558 PA_STATIC_FLIST_DECLARE(pa_sink_volume_change, 0, pa_xfree);
3560 /* Called from the IO thread. */
3561 static pa_sink_volume_change *pa_sink_volume_change_new(pa_sink *s) {
3562 pa_sink_volume_change *c;
3563 if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_sink_volume_change))))
3564 c = pa_xnew(pa_sink_volume_change, 1);
3566 PA_LLIST_INIT(pa_sink_volume_change, c);
3568 pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
3572 /* Called from the IO thread. */
3573 static void pa_sink_volume_change_free(pa_sink_volume_change *c) {
3575 if (pa_flist_push(PA_STATIC_FLIST_GET(pa_sink_volume_change), c) < 0)
3579 /* Called from the IO thread. */
3580 void pa_sink_volume_change_push(pa_sink *s) {
3581 pa_sink_volume_change *c = NULL;
3582 pa_sink_volume_change *nc = NULL;
3583 pa_sink_volume_change *pc = NULL;
3584 uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
3586 const char *direction = NULL;
3589 nc = pa_sink_volume_change_new(s);
3591 /* NOTE: There is already more different volumes in pa_sink that I can remember.
3592 * Adding one more volume for HW would get us rid of this, but I am trying
3593 * to survive with the ones we already have. */
3594 pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
3596 if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
3597 pa_log_debug("Volume not changing");
3598 pa_sink_volume_change_free(nc);
3602 nc->at = pa_sink_get_latency_within_thread(s, false);
3603 nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3605 if (s->thread_info.volume_changes_tail) {
3606 for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
3607 /* If volume is going up let's do it a bit late. If it is going
3608 * down let's do it a bit early. */
3609 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
3610 if (nc->at + safety_margin > c->at) {
3611 nc->at += safety_margin;
3616 else if (nc->at - safety_margin > c->at) {
3617 nc->at -= safety_margin;
3625 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
3626 nc->at += safety_margin;
3629 nc->at -= safety_margin;
3632 PA_LLIST_PREPEND(pa_sink_volume_change, s->thread_info.volume_changes, nc);
3635 PA_LLIST_INSERT_AFTER(pa_sink_volume_change, s->thread_info.volume_changes, c, nc);
3638 pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
3640 /* We can ignore volume events that came earlier but should happen later than this. */
3641 PA_LLIST_FOREACH_SAFE(c, pc, nc->next) {
3642 pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
3643 pa_sink_volume_change_free(c);
3646 s->thread_info.volume_changes_tail = nc;
3649 /* Called from the IO thread. */
3650 static void pa_sink_volume_change_flush(pa_sink *s) {
3651 pa_sink_volume_change *c = s->thread_info.volume_changes;
3653 s->thread_info.volume_changes = NULL;
3654 s->thread_info.volume_changes_tail = NULL;
3656 pa_sink_volume_change *next = c->next;
3657 pa_sink_volume_change_free(c);
3662 /* Called from the IO thread. */
3663 bool pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next) {
3669 if (!s->thread_info.volume_changes || !PA_SINK_IS_LINKED(s->state)) {
3675 pa_assert(s->write_volume);
3677 now = pa_rtclock_now();
3679 while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
3680 pa_sink_volume_change *c = s->thread_info.volume_changes;
3681 PA_LLIST_REMOVE(pa_sink_volume_change, s->thread_info.volume_changes, c);
3682 pa_log_debug("Volume change to %d at %llu was written %llu usec late",
3683 pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
3685 s->thread_info.current_hw_volume = c->hw_volume;
3686 pa_sink_volume_change_free(c);
3692 if (s->thread_info.volume_changes) {
3694 *usec_to_next = s->thread_info.volume_changes->at - now;
3695 if (pa_log_ratelimit(PA_LOG_DEBUG))
3696 pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
3701 s->thread_info.volume_changes_tail = NULL;
3706 /* Called from the IO thread. */
3707 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
3708 /* All the queued volume events later than current latency are shifted to happen earlier. */
3709 pa_sink_volume_change *c;
3710 pa_volume_t prev_vol = pa_cvolume_avg(&s->thread_info.current_hw_volume);
3711 pa_usec_t rewound = pa_bytes_to_usec(nbytes, &s->sample_spec);
3712 pa_usec_t limit = pa_sink_get_latency_within_thread(s, false);
3714 pa_log_debug("latency = %lld", (long long) limit);
3715 limit += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3717 PA_LLIST_FOREACH(c, s->thread_info.volume_changes) {
3718 pa_usec_t modified_limit = limit;
3719 if (prev_vol > pa_cvolume_avg(&c->hw_volume))
3720 modified_limit -= s->thread_info.volume_change_safety_margin;
3722 modified_limit += s->thread_info.volume_change_safety_margin;
3723 if (c->at > modified_limit) {
3725 if (c->at < modified_limit)
3726 c->at = modified_limit;
3728 prev_vol = pa_cvolume_avg(&c->hw_volume);
3730 pa_sink_volume_change_apply(s, NULL);
3733 /* Called from the main thread */
3734 /* Gets the list of formats supported by the sink. The members and idxset must
3735 * be freed by the caller. */
3736 pa_idxset* pa_sink_get_formats(pa_sink *s) {
3741 if (s->get_formats) {
3742 /* Sink supports format query, all is good */
3743 ret = s->get_formats(s);
3745 /* Sink doesn't support format query, so assume it does PCM */
3746 pa_format_info *f = pa_format_info_new();
3747 f->encoding = PA_ENCODING_PCM;
3749 ret = pa_idxset_new(NULL, NULL);
3750 pa_idxset_put(ret, f, NULL);
3756 /* Called from the main thread */
3757 /* Allows an external source to set what formats a sink supports if the sink
3758 * permits this. The function makes a copy of the formats on success. */
3759 bool pa_sink_set_formats(pa_sink *s, pa_idxset *formats) {
3764 /* Sink supports setting formats -- let's give it a shot */
3765 return s->set_formats(s, formats);
3767 /* Sink doesn't support setting this -- bail out */
3771 /* Called from the main thread */
3772 /* Checks if the sink can accept this format */
3773 bool pa_sink_check_format(pa_sink *s, pa_format_info *f) {
3774 pa_idxset *formats = NULL;
3780 formats = pa_sink_get_formats(s);
3783 pa_format_info *finfo_device;
3786 PA_IDXSET_FOREACH(finfo_device, formats, i) {
3787 if (pa_format_info_is_compatible(finfo_device, f)) {
3793 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
3799 /* Called from the main thread */
3800 /* Calculates the intersection between formats supported by the sink and
3801 * in_formats, and returns these, in the order of the sink's formats. */
3802 pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
3803 pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats = NULL;
3804 pa_format_info *f_sink, *f_in;
3809 if (!in_formats || pa_idxset_isempty(in_formats))
3812 sink_formats = pa_sink_get_formats(s);
3814 PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
3815 PA_IDXSET_FOREACH(f_in, in_formats, j) {
3816 if (pa_format_info_is_compatible(f_sink, f_in))
3817 pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
3823 pa_idxset_free(sink_formats, (pa_free_cb_t) pa_format_info_free);
3828 /* Called from the main thread. */
3829 void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
3830 pa_cvolume old_volume;
3831 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3832 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3837 old_volume = s->reference_volume;
3839 if (pa_cvolume_equal(volume, &old_volume))
3842 s->reference_volume = *volume;
3843 pa_log_debug("The reference volume of sink %s changed from %s to %s.", s->name,
3844 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
3845 s->flags & PA_SINK_DECIBEL_VOLUME),
3846 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
3847 s->flags & PA_SINK_DECIBEL_VOLUME));
3849 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3850 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED], s);