]> code.delx.au - pulseaudio/blob - src/pulsecore/source.c
sink, source: Fix error reporting style for rate updates
[pulseaudio] / src / pulsecore / source.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29
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>
37
38 #include <pulsecore/core-util.h>
39 #include <pulsecore/source-output.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-subscribe.h>
42 #include <pulsecore/log.h>
43 #include <pulsecore/mix.h>
44 #include <pulsecore/flist.h>
45
46 #include "source.h"
47
48 #define ABSOLUTE_MIN_LATENCY (500)
49 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
50 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
51
52 PA_DEFINE_PUBLIC_CLASS(pa_source, pa_msgobject);
53
54 struct pa_source_volume_change {
55 pa_usec_t at;
56 pa_cvolume hw_volume;
57
58 PA_LLIST_FIELDS(pa_source_volume_change);
59 };
60
61 struct source_message_set_port {
62 pa_device_port *port;
63 int ret;
64 };
65
66 static void source_free(pa_object *o);
67
68 static void pa_source_volume_change_push(pa_source *s);
69 static void pa_source_volume_change_flush(pa_source *s);
70
71 pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
72 pa_assert(data);
73
74 pa_zero(*data);
75 data->proplist = pa_proplist_new();
76 data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
77
78 return data;
79 }
80
81 void pa_source_new_data_set_name(pa_source_new_data *data, const char *name) {
82 pa_assert(data);
83
84 pa_xfree(data->name);
85 data->name = pa_xstrdup(name);
86 }
87
88 void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec) {
89 pa_assert(data);
90
91 if ((data->sample_spec_is_set = !!spec))
92 data->sample_spec = *spec;
93 }
94
95 void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map) {
96 pa_assert(data);
97
98 if ((data->channel_map_is_set = !!map))
99 data->channel_map = *map;
100 }
101
102 void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, const uint32_t alternate_sample_rate) {
103 pa_assert(data);
104
105 data->alternate_sample_rate_is_set = true;
106 data->alternate_sample_rate = alternate_sample_rate;
107 }
108
109 void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {
110 pa_assert(data);
111
112 if ((data->volume_is_set = !!volume))
113 data->volume = *volume;
114 }
115
116 void pa_source_new_data_set_muted(pa_source_new_data *data, bool mute) {
117 pa_assert(data);
118
119 data->muted_is_set = true;
120 data->muted = !!mute;
121 }
122
123 void pa_source_new_data_set_port(pa_source_new_data *data, const char *port) {
124 pa_assert(data);
125
126 pa_xfree(data->active_port);
127 data->active_port = pa_xstrdup(port);
128 }
129
130 void pa_source_new_data_done(pa_source_new_data *data) {
131 pa_assert(data);
132
133 pa_proplist_free(data->proplist);
134
135 if (data->ports)
136 pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
137
138 pa_xfree(data->name);
139 pa_xfree(data->active_port);
140 }
141
142 /* Called from main context */
143 static void reset_callbacks(pa_source *s) {
144 pa_assert(s);
145
146 s->set_state = NULL;
147 s->get_volume = NULL;
148 s->set_volume = NULL;
149 s->write_volume = NULL;
150 s->get_mute = NULL;
151 s->set_mute = NULL;
152 s->update_requested_latency = NULL;
153 s->set_port = NULL;
154 s->get_formats = NULL;
155 s->update_rate = NULL;
156 }
157
158 /* Called from main context */
159 pa_source* pa_source_new(
160 pa_core *core,
161 pa_source_new_data *data,
162 pa_source_flags_t flags) {
163
164 pa_source *s;
165 const char *name;
166 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
167 char *pt;
168
169 pa_assert(core);
170 pa_assert(data);
171 pa_assert(data->name);
172 pa_assert_ctl_context();
173
174 s = pa_msgobject_new(pa_source);
175
176 if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SOURCE, s, data->namereg_fail))) {
177 pa_log_debug("Failed to register name %s.", data->name);
178 pa_xfree(s);
179 return NULL;
180 }
181
182 pa_source_new_data_set_name(data, name);
183
184 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW], data) < 0) {
185 pa_xfree(s);
186 pa_namereg_unregister(core, name);
187 return NULL;
188 }
189
190 /* FIXME, need to free s here on failure */
191
192 pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
193 pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
194
195 pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
196
197 if (!data->channel_map_is_set)
198 pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
199
200 pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
201 pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
202
203 /* FIXME: There should probably be a general function for checking whether
204 * the source volume is allowed to be set, like there is for source outputs. */
205 pa_assert(!data->volume_is_set || !(flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
206
207 if (!data->volume_is_set) {
208 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
209 data->save_volume = false;
210 }
211
212 pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
213 pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
214
215 if (!data->muted_is_set)
216 data->muted = false;
217
218 if (data->card)
219 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
220
221 pa_device_init_description(data->proplist);
222 pa_device_init_icon(data->proplist, false);
223 pa_device_init_intended_roles(data->proplist);
224
225 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
226 pa_xfree(s);
227 pa_namereg_unregister(core, name);
228 return NULL;
229 }
230
231 s->parent.parent.free = source_free;
232 s->parent.process_msg = pa_source_process_msg;
233
234 s->core = core;
235 s->state = PA_SOURCE_INIT;
236 s->flags = flags;
237 s->priority = 0;
238 s->suspend_cause = data->suspend_cause;
239 pa_source_set_mixer_dirty(s, false);
240 s->name = pa_xstrdup(name);
241 s->proplist = pa_proplist_copy(data->proplist);
242 s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
243 s->module = data->module;
244 s->card = data->card;
245
246 s->priority = pa_device_init_priority(s->proplist);
247
248 s->sample_spec = data->sample_spec;
249 s->channel_map = data->channel_map;
250 s->default_sample_rate = s->sample_spec.rate;
251
252 if (data->alternate_sample_rate_is_set)
253 s->alternate_sample_rate = data->alternate_sample_rate;
254 else
255 s->alternate_sample_rate = s->core->alternate_sample_rate;
256
257 if (s->sample_spec.rate == s->alternate_sample_rate) {
258 pa_log_warn("Default and alternate sample rates are the same.");
259 s->alternate_sample_rate = 0;
260 }
261
262 s->outputs = pa_idxset_new(NULL, NULL);
263 s->n_corked = 0;
264 s->monitor_of = NULL;
265 s->output_from_master = NULL;
266
267 s->reference_volume = s->real_volume = data->volume;
268 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
269 s->base_volume = PA_VOLUME_NORM;
270 s->n_volume_steps = PA_VOLUME_NORM+1;
271 s->muted = data->muted;
272 s->refresh_volume = s->refresh_muted = false;
273
274 reset_callbacks(s);
275 s->userdata = NULL;
276
277 s->asyncmsgq = NULL;
278
279 /* As a minor optimization we just steal the list instead of
280 * copying it here */
281 s->ports = data->ports;
282 data->ports = NULL;
283
284 s->active_port = NULL;
285 s->save_port = false;
286
287 if (data->active_port)
288 if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
289 s->save_port = data->save_port;
290
291 if (!s->active_port) {
292 void *state;
293 pa_device_port *p;
294
295 PA_HASHMAP_FOREACH(p, s->ports, state)
296 if (!s->active_port || p->priority > s->active_port->priority)
297 s->active_port = p;
298 }
299
300 if (s->active_port)
301 s->latency_offset = s->active_port->latency_offset;
302 else
303 s->latency_offset = 0;
304
305 s->save_volume = data->save_volume;
306 s->save_muted = data->save_muted;
307
308 pa_silence_memchunk_get(
309 &core->silence_cache,
310 core->mempool,
311 &s->silence,
312 &s->sample_spec,
313 0);
314
315 s->thread_info.rtpoll = NULL;
316 s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
317 s->thread_info.soft_volume = s->soft_volume;
318 s->thread_info.soft_muted = s->muted;
319 s->thread_info.state = s->state;
320 s->thread_info.max_rewind = 0;
321 s->thread_info.requested_latency_valid = false;
322 s->thread_info.requested_latency = 0;
323 s->thread_info.min_latency = ABSOLUTE_MIN_LATENCY;
324 s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
325 s->thread_info.fixed_latency = flags & PA_SOURCE_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
326
327 PA_LLIST_HEAD_INIT(pa_source_volume_change, s->thread_info.volume_changes);
328 s->thread_info.volume_changes_tail = NULL;
329 pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
330 s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
331 s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
332 s->thread_info.latency_offset = s->latency_offset;
333
334 /* FIXME: This should probably be moved to pa_source_put() */
335 pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
336
337 if (s->card)
338 pa_assert_se(pa_idxset_put(s->card->sources, s, NULL) >= 0);
339
340 pt = pa_proplist_to_string_sep(s->proplist, "\n ");
341 pa_log_info("Created source %u \"%s\" with sample spec %s and channel map %s\n %s",
342 s->index,
343 s->name,
344 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
345 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
346 pt);
347 pa_xfree(pt);
348
349 return s;
350 }
351
352 /* Called from main context */
353 static int source_set_state(pa_source *s, pa_source_state_t state) {
354 int ret;
355 bool suspend_change;
356 pa_source_state_t original_state;
357
358 pa_assert(s);
359 pa_assert_ctl_context();
360
361 if (s->state == state)
362 return 0;
363
364 original_state = s->state;
365
366 suspend_change =
367 (original_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) ||
368 (PA_SOURCE_IS_OPENED(original_state) && state == PA_SOURCE_SUSPENDED);
369
370 if (s->set_state)
371 if ((ret = s->set_state(s, state)) < 0)
372 return ret;
373
374 if (s->asyncmsgq)
375 if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
376
377 if (s->set_state)
378 s->set_state(s, original_state);
379
380 return ret;
381 }
382
383 s->state = state;
384
385 if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the appropriate events */
386 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
387 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
388 }
389
390 if (suspend_change) {
391 pa_source_output *o;
392 uint32_t idx;
393
394 /* We're suspending or resuming, tell everyone about it */
395
396 PA_IDXSET_FOREACH(o, s->outputs, idx)
397 if (s->state == PA_SOURCE_SUSPENDED &&
398 (o->flags & PA_SOURCE_OUTPUT_KILL_ON_SUSPEND))
399 pa_source_output_kill(o);
400 else if (o->suspend)
401 o->suspend(o, state == PA_SOURCE_SUSPENDED);
402 }
403
404 return 0;
405 }
406
407 void pa_source_set_get_volume_callback(pa_source *s, pa_source_cb_t cb) {
408 pa_assert(s);
409
410 s->get_volume = cb;
411 }
412
413 void pa_source_set_set_volume_callback(pa_source *s, pa_source_cb_t cb) {
414 pa_source_flags_t flags;
415
416 pa_assert(s);
417 pa_assert(!s->write_volume || cb);
418
419 s->set_volume = cb;
420
421 /* Save the current flags so we can tell if they've changed */
422 flags = s->flags;
423
424 if (cb) {
425 /* The source implementor is responsible for setting decibel volume support */
426 s->flags |= PA_SOURCE_HW_VOLUME_CTRL;
427 } else {
428 s->flags &= ~PA_SOURCE_HW_VOLUME_CTRL;
429 /* See note below in pa_source_put() about volume sharing and decibel volumes */
430 pa_source_enable_decibel_volume(s, !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
431 }
432
433 /* If the flags have changed after init, let any clients know via a change event */
434 if (s->state != PA_SOURCE_INIT && flags != s->flags)
435 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
436 }
437
438 void pa_source_set_write_volume_callback(pa_source *s, pa_source_cb_t cb) {
439 pa_source_flags_t flags;
440
441 pa_assert(s);
442 pa_assert(!cb || s->set_volume);
443
444 s->write_volume = cb;
445
446 /* Save the current flags so we can tell if they've changed */
447 flags = s->flags;
448
449 if (cb)
450 s->flags |= PA_SOURCE_DEFERRED_VOLUME;
451 else
452 s->flags &= ~PA_SOURCE_DEFERRED_VOLUME;
453
454 /* If the flags have changed after init, let any clients know via a change event */
455 if (s->state != PA_SOURCE_INIT && flags != s->flags)
456 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
457 }
458
459 void pa_source_set_get_mute_callback(pa_source *s, pa_source_cb_t cb) {
460 pa_assert(s);
461
462 s->get_mute = cb;
463 }
464
465 void pa_source_set_set_mute_callback(pa_source *s, pa_source_cb_t cb) {
466 pa_source_flags_t flags;
467
468 pa_assert(s);
469
470 s->set_mute = cb;
471
472 /* Save the current flags so we can tell if they've changed */
473 flags = s->flags;
474
475 if (cb)
476 s->flags |= PA_SOURCE_HW_MUTE_CTRL;
477 else
478 s->flags &= ~PA_SOURCE_HW_MUTE_CTRL;
479
480 /* If the flags have changed after init, let any clients know via a change event */
481 if (s->state != PA_SOURCE_INIT && flags != s->flags)
482 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
483 }
484
485 static void enable_flat_volume(pa_source *s, bool enable) {
486 pa_source_flags_t flags;
487
488 pa_assert(s);
489
490 /* Always follow the overall user preference here */
491 enable = enable && s->core->flat_volumes;
492
493 /* Save the current flags so we can tell if they've changed */
494 flags = s->flags;
495
496 if (enable)
497 s->flags |= PA_SOURCE_FLAT_VOLUME;
498 else
499 s->flags &= ~PA_SOURCE_FLAT_VOLUME;
500
501 /* If the flags have changed after init, let any clients know via a change event */
502 if (s->state != PA_SOURCE_INIT && flags != s->flags)
503 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
504 }
505
506 void pa_source_enable_decibel_volume(pa_source *s, bool enable) {
507 pa_source_flags_t flags;
508
509 pa_assert(s);
510
511 /* Save the current flags so we can tell if they've changed */
512 flags = s->flags;
513
514 if (enable) {
515 s->flags |= PA_SOURCE_DECIBEL_VOLUME;
516 enable_flat_volume(s, true);
517 } else {
518 s->flags &= ~PA_SOURCE_DECIBEL_VOLUME;
519 enable_flat_volume(s, false);
520 }
521
522 /* If the flags have changed after init, let any clients know via a change event */
523 if (s->state != PA_SOURCE_INIT && flags != s->flags)
524 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
525 }
526
527 /* Called from main context */
528 void pa_source_put(pa_source *s) {
529 pa_source_assert_ref(s);
530 pa_assert_ctl_context();
531
532 pa_assert(s->state == PA_SOURCE_INIT);
533 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || s->output_from_master);
534
535 /* The following fields must be initialized properly when calling _put() */
536 pa_assert(s->asyncmsgq);
537 pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
538
539 /* Generally, flags should be initialized via pa_source_new(). As a
540 * special exception we allow some volume related flags to be set
541 * between _new() and _put() by the callback setter functions above.
542 *
543 * Thus we implement a couple safeguards here which ensure the above
544 * setters were used (or at least the implementor made manual changes
545 * in a compatible way).
546 *
547 * Note: All of these flags set here can change over the life time
548 * of the source. */
549 pa_assert(!(s->flags & PA_SOURCE_HW_VOLUME_CTRL) || s->set_volume);
550 pa_assert(!(s->flags & PA_SOURCE_DEFERRED_VOLUME) || s->write_volume);
551 pa_assert(!(s->flags & PA_SOURCE_HW_MUTE_CTRL) || s->set_mute);
552
553 /* XXX: Currently decibel volume is disabled for all sources that use volume
554 * sharing. When the master source supports decibel volume, it would be good
555 * to have the flag also in the filter source, but currently we don't do that
556 * so that the flags of the filter source never change when it's moved from
557 * a master source to another. One solution for this problem would be to
558 * remove user-visible volume altogether from filter sources when volume
559 * sharing is used, but the current approach was easier to implement... */
560 /* We always support decibel volumes in software, otherwise we leave it to
561 * the source implementor to set this flag as needed.
562 *
563 * Note: This flag can also change over the life time of the source. */
564 if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL) && !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
565 pa_source_enable_decibel_volume(s, true);
566
567 /* If the source implementor support DB volumes by itself, we should always
568 * try and enable flat volumes too */
569 if ((s->flags & PA_SOURCE_DECIBEL_VOLUME))
570 enable_flat_volume(s, true);
571
572 if (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) {
573 pa_source *root_source = pa_source_get_master(s);
574
575 pa_assert(PA_LIKELY(root_source));
576
577 s->reference_volume = root_source->reference_volume;
578 pa_cvolume_remap(&s->reference_volume, &root_source->channel_map, &s->channel_map);
579
580 s->real_volume = root_source->real_volume;
581 pa_cvolume_remap(&s->real_volume, &root_source->channel_map, &s->channel_map);
582 } else
583 /* We assume that if the sink implementor changed the default
584 * volume he did so in real_volume, because that is the usual
585 * place where he is supposed to place his changes. */
586 s->reference_volume = s->real_volume;
587
588 s->thread_info.soft_volume = s->soft_volume;
589 s->thread_info.soft_muted = s->muted;
590 pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
591
592 pa_assert((s->flags & PA_SOURCE_HW_VOLUME_CTRL)
593 || (s->base_volume == PA_VOLUME_NORM
594 && ((s->flags & PA_SOURCE_DECIBEL_VOLUME || (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)))));
595 pa_assert(!(s->flags & PA_SOURCE_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
596 pa_assert(!(s->flags & PA_SOURCE_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0));
597
598 if (s->suspend_cause)
599 pa_assert_se(source_set_state(s, PA_SOURCE_SUSPENDED) == 0);
600 else
601 pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
602
603 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
604 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
605 }
606
607 /* Called from main context */
608 void pa_source_unlink(pa_source *s) {
609 bool linked;
610 pa_source_output *o, *j = NULL;
611
612 pa_assert(s);
613 pa_assert_ctl_context();
614
615 /* See pa_sink_unlink() for a couple of comments how this function
616 * works. */
617
618 linked = PA_SOURCE_IS_LINKED(s->state);
619
620 if (linked)
621 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s);
622
623 if (s->state != PA_SOURCE_UNLINKED)
624 pa_namereg_unregister(s->core, s->name);
625 pa_idxset_remove_by_data(s->core->sources, s, NULL);
626
627 if (s->card)
628 pa_idxset_remove_by_data(s->card->sources, s, NULL);
629
630 while ((o = pa_idxset_first(s->outputs, NULL))) {
631 pa_assert(o != j);
632 pa_source_output_kill(o);
633 j = o;
634 }
635
636 if (linked)
637 source_set_state(s, PA_SOURCE_UNLINKED);
638 else
639 s->state = PA_SOURCE_UNLINKED;
640
641 reset_callbacks(s);
642
643 if (linked) {
644 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
645 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s);
646 }
647 }
648
649 /* Called from main context */
650 static void source_free(pa_object *o) {
651 pa_source *s = PA_SOURCE(o);
652
653 pa_assert(s);
654 pa_assert_ctl_context();
655 pa_assert(pa_source_refcnt(s) == 0);
656
657 if (PA_SOURCE_IS_LINKED(s->state))
658 pa_source_unlink(s);
659
660 pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
661
662 pa_idxset_free(s->outputs, NULL);
663 pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
664
665 if (s->silence.memblock)
666 pa_memblock_unref(s->silence.memblock);
667
668 pa_xfree(s->name);
669 pa_xfree(s->driver);
670
671 if (s->proplist)
672 pa_proplist_free(s->proplist);
673
674 if (s->ports)
675 pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
676
677 pa_xfree(s);
678 }
679
680 /* Called from main context, and not while the IO thread is active, please */
681 void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
682 pa_source_assert_ref(s);
683 pa_assert_ctl_context();
684
685 s->asyncmsgq = q;
686 }
687
688 /* Called from main context, and not while the IO thread is active, please */
689 void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flags_t value) {
690 pa_source_flags_t old_flags;
691 pa_source_output *output;
692 uint32_t idx;
693
694 pa_source_assert_ref(s);
695 pa_assert_ctl_context();
696
697 /* For now, allow only a minimal set of flags to be changed. */
698 pa_assert((mask & ~(PA_SOURCE_DYNAMIC_LATENCY|PA_SOURCE_LATENCY)) == 0);
699
700 old_flags = s->flags;
701 s->flags = (s->flags & ~mask) | (value & mask);
702
703 if (s->flags == old_flags)
704 return;
705
706 if ((s->flags & PA_SOURCE_LATENCY) != (old_flags & PA_SOURCE_LATENCY))
707 pa_log_debug("Source %s: LATENCY flag %s.", s->name, (s->flags & PA_SOURCE_LATENCY) ? "enabled" : "disabled");
708
709 if ((s->flags & PA_SOURCE_DYNAMIC_LATENCY) != (old_flags & PA_SOURCE_DYNAMIC_LATENCY))
710 pa_log_debug("Source %s: DYNAMIC_LATENCY flag %s.",
711 s->name, (s->flags & PA_SOURCE_DYNAMIC_LATENCY) ? "enabled" : "disabled");
712
713 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
714 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_FLAGS_CHANGED], s);
715
716 PA_IDXSET_FOREACH(output, s->outputs, idx) {
717 if (output->destination_source)
718 pa_source_update_flags(output->destination_source, mask, value);
719 }
720 }
721
722 /* Called from IO context, or before _put() from main context */
723 void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) {
724 pa_source_assert_ref(s);
725 pa_source_assert_io_context(s);
726
727 s->thread_info.rtpoll = p;
728 }
729
730 /* Called from main context */
731 int pa_source_update_status(pa_source*s) {
732 pa_source_assert_ref(s);
733 pa_assert_ctl_context();
734 pa_assert(PA_SOURCE_IS_LINKED(s->state));
735
736 if (s->state == PA_SOURCE_SUSPENDED)
737 return 0;
738
739 return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
740 }
741
742 /* Called from any context - must be threadsafe */
743 void pa_source_set_mixer_dirty(pa_source *s, bool is_dirty) {
744 pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
745 }
746
747 /* Called from main context */
748 int pa_source_suspend(pa_source *s, bool suspend, pa_suspend_cause_t cause) {
749 pa_source_assert_ref(s);
750 pa_assert_ctl_context();
751 pa_assert(PA_SOURCE_IS_LINKED(s->state));
752 pa_assert(cause != 0);
753
754 if (s->monitor_of && cause != PA_SUSPEND_PASSTHROUGH)
755 return -PA_ERR_NOTSUPPORTED;
756
757 if (suspend)
758 s->suspend_cause |= cause;
759 else
760 s->suspend_cause &= ~cause;
761
762 if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
763 /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
764 it'll be handled just fine. */
765 pa_source_set_mixer_dirty(s, false);
766 pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
767 if (s->active_port && s->set_port) {
768 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
769 struct source_message_set_port msg = { .port = s->active_port, .ret = 0 };
770 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
771 }
772 else
773 s->set_port(s, s->active_port);
774 }
775 else {
776 if (s->set_mute)
777 s->set_mute(s);
778 if (s->set_volume)
779 s->set_volume(s);
780 }
781 }
782
783 if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause)
784 return 0;
785
786 pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
787
788 if (s->suspend_cause)
789 return source_set_state(s, PA_SOURCE_SUSPENDED);
790 else
791 return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
792 }
793
794 /* Called from main context */
795 int pa_source_sync_suspend(pa_source *s) {
796 pa_sink_state_t state;
797
798 pa_source_assert_ref(s);
799 pa_assert_ctl_context();
800 pa_assert(PA_SOURCE_IS_LINKED(s->state));
801 pa_assert(s->monitor_of);
802
803 state = pa_sink_get_state(s->monitor_of);
804
805 if (state == PA_SINK_SUSPENDED)
806 return source_set_state(s, PA_SOURCE_SUSPENDED);
807
808 pa_assert(PA_SINK_IS_OPENED(state));
809
810 return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
811 }
812
813 /* Called from main context */
814 pa_queue *pa_source_move_all_start(pa_source *s, pa_queue *q) {
815 pa_source_output *o, *n;
816 uint32_t idx;
817
818 pa_source_assert_ref(s);
819 pa_assert_ctl_context();
820 pa_assert(PA_SOURCE_IS_LINKED(s->state));
821
822 if (!q)
823 q = pa_queue_new();
824
825 for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = n) {
826 n = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx));
827
828 pa_source_output_ref(o);
829
830 if (pa_source_output_start_move(o) >= 0)
831 pa_queue_push(q, o);
832 else
833 pa_source_output_unref(o);
834 }
835
836 return q;
837 }
838
839 /* Called from main context */
840 void pa_source_move_all_finish(pa_source *s, pa_queue *q, bool save) {
841 pa_source_output *o;
842
843 pa_source_assert_ref(s);
844 pa_assert_ctl_context();
845 pa_assert(PA_SOURCE_IS_LINKED(s->state));
846 pa_assert(q);
847
848 while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
849 if (pa_source_output_finish_move(o, s, save) < 0)
850 pa_source_output_fail_move(o);
851
852 pa_source_output_unref(o);
853 }
854
855 pa_queue_free(q, NULL);
856 }
857
858 /* Called from main context */
859 void pa_source_move_all_fail(pa_queue *q) {
860 pa_source_output *o;
861
862 pa_assert_ctl_context();
863 pa_assert(q);
864
865 while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
866 pa_source_output_fail_move(o);
867 pa_source_output_unref(o);
868 }
869
870 pa_queue_free(q, NULL);
871 }
872
873 /* Called from IO thread context */
874 void pa_source_process_rewind(pa_source *s, size_t nbytes) {
875 pa_source_output *o;
876 void *state = NULL;
877
878 pa_source_assert_ref(s);
879 pa_source_assert_io_context(s);
880 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
881
882 if (nbytes <= 0)
883 return;
884
885 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
886 return;
887
888 pa_log_debug("Processing rewind...");
889
890 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
891 pa_source_output_assert_ref(o);
892 pa_source_output_process_rewind(o, nbytes);
893 }
894 }
895
896 /* Called from IO thread context */
897 void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
898 pa_source_output *o;
899 void *state = NULL;
900
901 pa_source_assert_ref(s);
902 pa_source_assert_io_context(s);
903 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
904 pa_assert(chunk);
905
906 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
907 return;
908
909 if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
910 pa_memchunk vchunk = *chunk;
911
912 pa_memblock_ref(vchunk.memblock);
913 pa_memchunk_make_writable(&vchunk, 0);
914
915 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
916 pa_silence_memchunk(&vchunk, &s->sample_spec);
917 else
918 pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
919
920 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
921 pa_source_output_assert_ref(o);
922
923 if (!o->thread_info.direct_on_input)
924 pa_source_output_push(o, &vchunk);
925 }
926
927 pa_memblock_unref(vchunk.memblock);
928 } else {
929
930 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
931 pa_source_output_assert_ref(o);
932
933 if (!o->thread_info.direct_on_input)
934 pa_source_output_push(o, chunk);
935 }
936 }
937 }
938
939 /* Called from IO thread context */
940 void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *chunk) {
941 pa_source_assert_ref(s);
942 pa_source_assert_io_context(s);
943 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
944 pa_source_output_assert_ref(o);
945 pa_assert(o->thread_info.direct_on_input);
946 pa_assert(chunk);
947
948 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
949 return;
950
951 if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
952 pa_memchunk vchunk = *chunk;
953
954 pa_memblock_ref(vchunk.memblock);
955 pa_memchunk_make_writable(&vchunk, 0);
956
957 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
958 pa_silence_memchunk(&vchunk, &s->sample_spec);
959 else
960 pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
961
962 pa_source_output_push(o, &vchunk);
963
964 pa_memblock_unref(vchunk.memblock);
965 } else
966 pa_source_output_push(o, chunk);
967 }
968
969 /* Called from main thread */
970 int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
971 int ret;
972 uint32_t desired_rate = rate;
973 uint32_t default_rate = s->default_sample_rate;
974 uint32_t alternate_rate = s->alternate_sample_rate;
975 bool use_alternate = false;
976
977 if (rate == s->sample_spec.rate)
978 return 0;
979
980 if (!s->update_rate && !s->monitor_of)
981 return -1;
982
983 if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough)) {
984 pa_log_debug("Default and alternate sample rates are the same.");
985 return -1;
986 }
987
988 if (PA_SOURCE_IS_RUNNING(s->state)) {
989 pa_log_info("Cannot update rate, SOURCE_IS_RUNNING, will keep using %u Hz",
990 s->sample_spec.rate);
991 return -1;
992 }
993
994 if (s->monitor_of) {
995 if (PA_SINK_IS_RUNNING(s->monitor_of->state)) {
996 pa_log_info("Cannot update rate, this is a monitor source and the sink is running.");
997 return -1;
998 }
999 }
1000
1001 if (PA_UNLIKELY (desired_rate < 8000 ||
1002 desired_rate > PA_RATE_MAX))
1003 return -1;
1004
1005 if (!passthrough) {
1006 pa_assert((default_rate % 4000 == 0) || (default_rate % 11025 == 0));
1007 pa_assert((alternate_rate % 4000 == 0) || (alternate_rate % 11025 == 0));
1008
1009 if (default_rate % 11025 == 0) {
1010 if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
1011 use_alternate=true;
1012 } else {
1013 /* default is 4000 multiple */
1014 if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
1015 use_alternate=true;
1016 }
1017
1018 if (use_alternate)
1019 desired_rate = alternate_rate;
1020 else
1021 desired_rate = default_rate;
1022 } else {
1023 desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
1024 }
1025
1026 if (desired_rate == s->sample_spec.rate)
1027 return -1;
1028
1029 if (!passthrough && pa_source_used_by(s) > 0)
1030 return -1;
1031
1032 pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
1033 pa_source_suspend(s, true, PA_SUSPEND_INTERNAL);
1034
1035 if (s->update_rate)
1036 ret = s->update_rate(s, desired_rate);
1037 else {
1038 /* This is a monitor source. */
1039
1040 /* XXX: This code is written with non-passthrough streams in mind. I
1041 * have no idea whether the behaviour with passthrough streams is
1042 * sensible. */
1043 if (!passthrough) {
1044 uint32_t old_rate = s->sample_spec.rate;
1045
1046 s->sample_spec.rate = desired_rate;
1047 ret = pa_sink_update_rate(s->monitor_of, desired_rate, false);
1048
1049 if (ret < 0) {
1050 /* Changing the sink rate failed, roll back the old rate for
1051 * the monitor source. Why did we set the source rate before
1052 * calling pa_sink_update_rate(), you may ask. The reason is
1053 * that pa_sink_update_rate() tries to update the monitor
1054 * source rate, but we are already in the process of updating
1055 * the monitor source rate, so there's a risk of entering an
1056 * infinite loop. Setting the source rate before calling
1057 * pa_sink_update_rate() makes the rate == s->sample_spec.rate
1058 * check in the beginning of this function return early, so we
1059 * avoid looping. */
1060 s->sample_spec.rate = old_rate;
1061 }
1062 } else
1063 ret = -1;
1064 }
1065
1066 if (ret >= 0) {
1067 uint32_t idx;
1068 pa_source_output *o;
1069
1070 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1071 if (o->state == PA_SOURCE_OUTPUT_CORKED)
1072 pa_source_output_update_rate(o);
1073 }
1074
1075 pa_log_info("Changed sampling rate successfully");
1076 }
1077
1078 pa_source_suspend(s, false, PA_SUSPEND_INTERNAL);
1079
1080 return ret;
1081 }
1082
1083 /* Called from main thread */
1084 pa_usec_t pa_source_get_latency(pa_source *s) {
1085 pa_usec_t usec;
1086
1087 pa_source_assert_ref(s);
1088 pa_assert_ctl_context();
1089 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1090
1091 if (s->state == PA_SOURCE_SUSPENDED)
1092 return 0;
1093
1094 if (!(s->flags & PA_SOURCE_LATENCY))
1095 return 0;
1096
1097 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
1098
1099 /* usec is unsigned, so check that the offset can be added to usec without
1100 * underflowing. */
1101 if (-s->latency_offset <= (int64_t) usec)
1102 usec += s->latency_offset;
1103 else
1104 usec = 0;
1105
1106 return usec;
1107 }
1108
1109 /* Called from IO thread */
1110 pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {
1111 pa_usec_t usec = 0;
1112 pa_msgobject *o;
1113
1114 pa_source_assert_ref(s);
1115 pa_source_assert_io_context(s);
1116 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
1117
1118 /* The returned value is supposed to be in the time domain of the sound card! */
1119
1120 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
1121 return 0;
1122
1123 if (!(s->flags & PA_SOURCE_LATENCY))
1124 return 0;
1125
1126 o = PA_MSGOBJECT(s);
1127
1128 /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
1129
1130 if (o->process_msg(o, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1131 return -1;
1132
1133 /* usec is unsigned, so check that the offset can be added to usec without
1134 * underflowing. */
1135 if (-s->thread_info.latency_offset <= (int64_t) usec)
1136 usec += s->thread_info.latency_offset;
1137 else
1138 usec = 0;
1139
1140 return usec;
1141 }
1142
1143 /* Called from the main thread (and also from the IO thread while the main
1144 * thread is waiting).
1145 *
1146 * When a source uses volume sharing, it never has the PA_SOURCE_FLAT_VOLUME flag
1147 * set. Instead, flat volume mode is detected by checking whether the root source
1148 * has the flag set. */
1149 bool pa_source_flat_volume_enabled(pa_source *s) {
1150 pa_source_assert_ref(s);
1151
1152 s = pa_source_get_master(s);
1153
1154 if (PA_LIKELY(s))
1155 return (s->flags & PA_SOURCE_FLAT_VOLUME);
1156 else
1157 return false;
1158 }
1159
1160 /* Called from the main thread (and also from the IO thread while the main
1161 * thread is waiting). */
1162 pa_source *pa_source_get_master(pa_source *s) {
1163 pa_source_assert_ref(s);
1164
1165 while (s && (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1166 if (PA_UNLIKELY(!s->output_from_master))
1167 return NULL;
1168
1169 s = s->output_from_master->source;
1170 }
1171
1172 return s;
1173 }
1174
1175 /* Called from main context */
1176 bool pa_source_is_passthrough(pa_source *s) {
1177
1178 pa_source_assert_ref(s);
1179
1180 /* NB Currently only monitor sources support passthrough mode */
1181 return (s->monitor_of && pa_sink_is_passthrough(s->monitor_of));
1182 }
1183
1184 /* Called from main context */
1185 void pa_source_enter_passthrough(pa_source *s) {
1186 pa_cvolume volume;
1187
1188 /* set the volume to NORM */
1189 s->saved_volume = *pa_source_get_volume(s, true);
1190 s->saved_save_volume = s->save_volume;
1191
1192 pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
1193 pa_source_set_volume(s, &volume, true, false);
1194 }
1195
1196 /* Called from main context */
1197 void pa_source_leave_passthrough(pa_source *s) {
1198 /* Restore source volume to what it was before we entered passthrough mode */
1199 pa_source_set_volume(s, &s->saved_volume, true, s->saved_save_volume);
1200
1201 pa_cvolume_init(&s->saved_volume);
1202 s->saved_save_volume = false;
1203 }
1204
1205 /* Called from main context. */
1206 static void compute_reference_ratio(pa_source_output *o) {
1207 unsigned c = 0;
1208 pa_cvolume remapped;
1209
1210 pa_assert(o);
1211 pa_assert(pa_source_flat_volume_enabled(o->source));
1212
1213 /*
1214 * Calculates the reference ratio from the source's reference
1215 * volume. This basically calculates:
1216 *
1217 * o->reference_ratio = o->volume / o->source->reference_volume
1218 */
1219
1220 remapped = o->source->reference_volume;
1221 pa_cvolume_remap(&remapped, &o->source->channel_map, &o->channel_map);
1222
1223 o->reference_ratio.channels = o->sample_spec.channels;
1224
1225 for (c = 0; c < o->sample_spec.channels; c++) {
1226
1227 /* We don't update when the source volume is 0 anyway */
1228 if (remapped.values[c] <= PA_VOLUME_MUTED)
1229 continue;
1230
1231 /* Don't update the reference ratio unless necessary */
1232 if (pa_sw_volume_multiply(
1233 o->reference_ratio.values[c],
1234 remapped.values[c]) == o->volume.values[c])
1235 continue;
1236
1237 o->reference_ratio.values[c] = pa_sw_volume_divide(
1238 o->volume.values[c],
1239 remapped.values[c]);
1240 }
1241 }
1242
1243 /* Called from main context. Only called for the root source in volume sharing
1244 * cases, except for internal recursive calls. */
1245 static void compute_reference_ratios(pa_source *s) {
1246 uint32_t idx;
1247 pa_source_output *o;
1248
1249 pa_source_assert_ref(s);
1250 pa_assert_ctl_context();
1251 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1252 pa_assert(pa_source_flat_volume_enabled(s));
1253
1254 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1255 compute_reference_ratio(o);
1256
1257 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1258 compute_reference_ratios(o->destination_source);
1259 }
1260 }
1261
1262 /* Called from main context. Only called for the root source in volume sharing
1263 * cases, except for internal recursive calls. */
1264 static void compute_real_ratios(pa_source *s) {
1265 pa_source_output *o;
1266 uint32_t idx;
1267
1268 pa_source_assert_ref(s);
1269 pa_assert_ctl_context();
1270 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1271 pa_assert(pa_source_flat_volume_enabled(s));
1272
1273 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1274 unsigned c;
1275 pa_cvolume remapped;
1276
1277 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1278 /* The origin source uses volume sharing, so this input's real ratio
1279 * is handled as a special case - the real ratio must be 0 dB, and
1280 * as a result i->soft_volume must equal i->volume_factor. */
1281 pa_cvolume_reset(&o->real_ratio, o->real_ratio.channels);
1282 o->soft_volume = o->volume_factor;
1283
1284 compute_real_ratios(o->destination_source);
1285
1286 continue;
1287 }
1288
1289 /*
1290 * This basically calculates:
1291 *
1292 * i->real_ratio := i->volume / s->real_volume
1293 * i->soft_volume := i->real_ratio * i->volume_factor
1294 */
1295
1296 remapped = s->real_volume;
1297 pa_cvolume_remap(&remapped, &s->channel_map, &o->channel_map);
1298
1299 o->real_ratio.channels = o->sample_spec.channels;
1300 o->soft_volume.channels = o->sample_spec.channels;
1301
1302 for (c = 0; c < o->sample_spec.channels; c++) {
1303
1304 if (remapped.values[c] <= PA_VOLUME_MUTED) {
1305 /* We leave o->real_ratio untouched */
1306 o->soft_volume.values[c] = PA_VOLUME_MUTED;
1307 continue;
1308 }
1309
1310 /* Don't lose accuracy unless necessary */
1311 if (pa_sw_volume_multiply(
1312 o->real_ratio.values[c],
1313 remapped.values[c]) != o->volume.values[c])
1314
1315 o->real_ratio.values[c] = pa_sw_volume_divide(
1316 o->volume.values[c],
1317 remapped.values[c]);
1318
1319 o->soft_volume.values[c] = pa_sw_volume_multiply(
1320 o->real_ratio.values[c],
1321 o->volume_factor.values[c]);
1322 }
1323
1324 /* We don't copy the soft_volume to the thread_info data
1325 * here. That must be done by the caller */
1326 }
1327 }
1328
1329 static pa_cvolume *cvolume_remap_minimal_impact(
1330 pa_cvolume *v,
1331 const pa_cvolume *template,
1332 const pa_channel_map *from,
1333 const pa_channel_map *to) {
1334
1335 pa_cvolume t;
1336
1337 pa_assert(v);
1338 pa_assert(template);
1339 pa_assert(from);
1340 pa_assert(to);
1341 pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
1342 pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
1343
1344 /* Much like pa_cvolume_remap(), but tries to minimize impact when
1345 * mapping from source output to source volumes:
1346 *
1347 * If template is a possible remapping from v it is used instead
1348 * of remapping anew.
1349 *
1350 * If the channel maps don't match we set an all-channel volume on
1351 * the source to ensure that changing a volume on one stream has no
1352 * effect that cannot be compensated for in another stream that
1353 * does not have the same channel map as the source. */
1354
1355 if (pa_channel_map_equal(from, to))
1356 return v;
1357
1358 t = *template;
1359 if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
1360 *v = *template;
1361 return v;
1362 }
1363
1364 pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
1365 return v;
1366 }
1367
1368 /* Called from main thread. Only called for the root source in volume sharing
1369 * cases, except for internal recursive calls. */
1370 static void get_maximum_output_volume(pa_source *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
1371 pa_source_output *o;
1372 uint32_t idx;
1373
1374 pa_source_assert_ref(s);
1375 pa_assert(max_volume);
1376 pa_assert(channel_map);
1377 pa_assert(pa_source_flat_volume_enabled(s));
1378
1379 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1380 pa_cvolume remapped;
1381
1382 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1383 get_maximum_output_volume(o->destination_source, max_volume, channel_map);
1384
1385 /* Ignore this output. The origin source uses volume sharing, so this
1386 * output's volume will be set to be equal to the root source's real
1387 * volume. Obviously this output's current volume must not then
1388 * affect what the root source's real volume will be. */
1389 continue;
1390 }
1391
1392 remapped = o->volume;
1393 cvolume_remap_minimal_impact(&remapped, max_volume, &o->channel_map, channel_map);
1394 pa_cvolume_merge(max_volume, max_volume, &remapped);
1395 }
1396 }
1397
1398 /* Called from main thread. Only called for the root source in volume sharing
1399 * cases, except for internal recursive calls. */
1400 static bool has_outputs(pa_source *s) {
1401 pa_source_output *o;
1402 uint32_t idx;
1403
1404 pa_source_assert_ref(s);
1405
1406 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1407 if (!o->destination_source || !(o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || has_outputs(o->destination_source))
1408 return true;
1409 }
1410
1411 return false;
1412 }
1413
1414 /* Called from main thread. Only called for the root source in volume sharing
1415 * cases, except for internal recursive calls. */
1416 static void update_real_volume(pa_source *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
1417 pa_source_output *o;
1418 uint32_t idx;
1419
1420 pa_source_assert_ref(s);
1421 pa_assert(new_volume);
1422 pa_assert(channel_map);
1423
1424 s->real_volume = *new_volume;
1425 pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
1426
1427 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1428 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1429 if (pa_source_flat_volume_enabled(s)) {
1430 pa_cvolume old_volume = o->volume;
1431
1432 /* Follow the root source's real volume. */
1433 o->volume = *new_volume;
1434 pa_cvolume_remap(&o->volume, channel_map, &o->channel_map);
1435 compute_reference_ratio(o);
1436
1437 /* The volume changed, let's tell people so */
1438 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1439 if (o->volume_changed)
1440 o->volume_changed(o);
1441
1442 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1443 }
1444 }
1445
1446 update_real_volume(o->destination_source, new_volume, channel_map);
1447 }
1448 }
1449 }
1450
1451 /* Called from main thread. Only called for the root source in shared volume
1452 * cases. */
1453 static void compute_real_volume(pa_source *s) {
1454 pa_source_assert_ref(s);
1455 pa_assert_ctl_context();
1456 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1457 pa_assert(pa_source_flat_volume_enabled(s));
1458 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1459
1460 /* This determines the maximum volume of all streams and sets
1461 * s->real_volume accordingly. */
1462
1463 if (!has_outputs(s)) {
1464 /* In the special case that we have no source outputs we leave the
1465 * volume unmodified. */
1466 update_real_volume(s, &s->reference_volume, &s->channel_map);
1467 return;
1468 }
1469
1470 pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1471
1472 /* First let's determine the new maximum volume of all outputs
1473 * connected to this source */
1474 get_maximum_output_volume(s, &s->real_volume, &s->channel_map);
1475 update_real_volume(s, &s->real_volume, &s->channel_map);
1476
1477 /* Then, let's update the real ratios/soft volumes of all outputs
1478 * connected to this source */
1479 compute_real_ratios(s);
1480 }
1481
1482 /* Called from main thread. Only called for the root source in shared volume
1483 * cases, except for internal recursive calls. */
1484 static void propagate_reference_volume(pa_source *s) {
1485 pa_source_output *o;
1486 uint32_t idx;
1487
1488 pa_source_assert_ref(s);
1489 pa_assert_ctl_context();
1490 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1491 pa_assert(pa_source_flat_volume_enabled(s));
1492
1493 /* This is called whenever the source volume changes that is not
1494 * caused by a source output volume change. We need to fix up the
1495 * source output volumes accordingly */
1496
1497 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1498 pa_cvolume old_volume;
1499
1500 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1501 propagate_reference_volume(o->destination_source);
1502
1503 /* Since the origin source uses volume sharing, this output's volume
1504 * needs to be updated to match the root source's real volume, but
1505 * that will be done later in update_shared_real_volume(). */
1506 continue;
1507 }
1508
1509 old_volume = o->volume;
1510
1511 /* This basically calculates:
1512 *
1513 * o->volume := o->reference_volume * o->reference_ratio */
1514
1515 o->volume = s->reference_volume;
1516 pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
1517 pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
1518
1519 /* The volume changed, let's tell people so */
1520 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1521
1522 if (o->volume_changed)
1523 o->volume_changed(o);
1524
1525 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1526 }
1527 }
1528 }
1529
1530 /* Called from main thread. Only called for the root source in volume sharing
1531 * cases, except for internal recursive calls. The return value indicates
1532 * whether any reference volume actually changed. */
1533 static bool update_reference_volume(pa_source *s, const pa_cvolume *v, const pa_channel_map *channel_map, bool save) {
1534 pa_cvolume volume;
1535 bool reference_volume_changed;
1536 pa_source_output *o;
1537 uint32_t idx;
1538
1539 pa_source_assert_ref(s);
1540 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1541 pa_assert(v);
1542 pa_assert(channel_map);
1543 pa_assert(pa_cvolume_valid(v));
1544
1545 volume = *v;
1546 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
1547
1548 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
1549 s->reference_volume = volume;
1550
1551 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
1552
1553 if (reference_volume_changed)
1554 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1555 else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1556 /* If the root source's volume doesn't change, then there can't be any
1557 * changes in the other source in the source tree either.
1558 *
1559 * It's probably theoretically possible that even if the root source's
1560 * volume changes slightly, some filter source doesn't change its volume
1561 * due to rounding errors. If that happens, we still want to propagate
1562 * the changed root source volume to the sources connected to the
1563 * intermediate source that didn't change its volume. This theoretical
1564 * possibility is the reason why we have that !(s->flags &
1565 * PA_SOURCE_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
1566 * notice even if we returned here false always if
1567 * reference_volume_changed is false. */
1568 return false;
1569
1570 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1571 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1572 update_reference_volume(o->destination_source, v, channel_map, false);
1573 }
1574
1575 return true;
1576 }
1577
1578 /* Called from main thread */
1579 void pa_source_set_volume(
1580 pa_source *s,
1581 const pa_cvolume *volume,
1582 bool send_msg,
1583 bool save) {
1584
1585 pa_cvolume new_reference_volume;
1586 pa_source *root_source;
1587
1588 pa_source_assert_ref(s);
1589 pa_assert_ctl_context();
1590 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1591 pa_assert(!volume || pa_cvolume_valid(volume));
1592 pa_assert(volume || pa_source_flat_volume_enabled(s));
1593 pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
1594
1595 /* make sure we don't change the volume in PASSTHROUGH mode ...
1596 * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
1597 if (pa_source_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
1598 pa_log_warn("Cannot change volume, source is monitor of a PASSTHROUGH sink");
1599 return;
1600 }
1601
1602 /* In case of volume sharing, the volume is set for the root source first,
1603 * from which it's then propagated to the sharing sources. */
1604 root_source = pa_source_get_master(s);
1605
1606 if (PA_UNLIKELY(!root_source))
1607 return;
1608
1609 /* As a special exception we accept mono volumes on all sources --
1610 * even on those with more complex channel maps */
1611
1612 if (volume) {
1613 if (pa_cvolume_compatible(volume, &s->sample_spec))
1614 new_reference_volume = *volume;
1615 else {
1616 new_reference_volume = s->reference_volume;
1617 pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
1618 }
1619
1620 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
1621
1622 if (update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save)) {
1623 if (pa_source_flat_volume_enabled(root_source)) {
1624 /* OK, propagate this volume change back to the outputs */
1625 propagate_reference_volume(root_source);
1626
1627 /* And now recalculate the real volume */
1628 compute_real_volume(root_source);
1629 } else
1630 update_real_volume(root_source, &root_source->reference_volume, &root_source->channel_map);
1631 }
1632
1633 } else {
1634 /* If volume is NULL we synchronize the source's real and
1635 * reference volumes with the stream volumes. */
1636
1637 pa_assert(pa_source_flat_volume_enabled(root_source));
1638
1639 /* Ok, let's determine the new real volume */
1640 compute_real_volume(root_source);
1641
1642 /* Let's 'push' the reference volume if necessary */
1643 pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_source->real_volume);
1644 /* If the source and it's root don't have the same number of channels, we need to remap */
1645 if (s != root_source && !pa_channel_map_equal(&s->channel_map, &root_source->channel_map))
1646 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
1647 update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save);
1648
1649 /* Now that the reference volume is updated, we can update the streams'
1650 * reference ratios. */
1651 compute_reference_ratios(root_source);
1652 }
1653
1654 if (root_source->set_volume) {
1655 /* If we have a function set_volume(), then we do not apply a
1656 * soft volume by default. However, set_volume() is free to
1657 * apply one to root_source->soft_volume */
1658
1659 pa_cvolume_reset(&root_source->soft_volume, root_source->sample_spec.channels);
1660 if (!(root_source->flags & PA_SOURCE_DEFERRED_VOLUME))
1661 root_source->set_volume(root_source);
1662
1663 } else
1664 /* If we have no function set_volume(), then the soft volume
1665 * becomes the real volume */
1666 root_source->soft_volume = root_source->real_volume;
1667
1668 /* This tells the source that soft volume and/or real volume changed */
1669 if (send_msg)
1670 pa_assert_se(pa_asyncmsgq_send(root_source->asyncmsgq, PA_MSGOBJECT(root_source), PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
1671 }
1672
1673 /* Called from the io thread if sync volume is used, otherwise from the main thread.
1674 * Only to be called by source implementor */
1675 void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
1676
1677 pa_source_assert_ref(s);
1678 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1679
1680 if (s->flags & PA_SOURCE_DEFERRED_VOLUME)
1681 pa_source_assert_io_context(s);
1682 else
1683 pa_assert_ctl_context();
1684
1685 if (!volume)
1686 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1687 else
1688 s->soft_volume = *volume;
1689
1690 if (PA_SOURCE_IS_LINKED(s->state) && !(s->flags & PA_SOURCE_DEFERRED_VOLUME))
1691 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1692 else
1693 s->thread_info.soft_volume = s->soft_volume;
1694 }
1695
1696 /* Called from the main thread. Only called for the root source in volume sharing
1697 * cases, except for internal recursive calls. */
1698 static void propagate_real_volume(pa_source *s, const pa_cvolume *old_real_volume) {
1699 pa_source_output *o;
1700 uint32_t idx;
1701
1702 pa_source_assert_ref(s);
1703 pa_assert(old_real_volume);
1704 pa_assert_ctl_context();
1705 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1706
1707 /* This is called when the hardware's real volume changes due to
1708 * some external event. We copy the real volume into our
1709 * reference volume and then rebuild the stream volumes based on
1710 * i->real_ratio which should stay fixed. */
1711
1712 if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1713 if (pa_cvolume_equal(old_real_volume, &s->real_volume))
1714 return;
1715
1716 /* 1. Make the real volume the reference volume */
1717 update_reference_volume(s, &s->real_volume, &s->channel_map, true);
1718 }
1719
1720 if (pa_source_flat_volume_enabled(s)) {
1721
1722 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1723 pa_cvolume old_volume = o->volume;
1724
1725 /* 2. Since the source's reference and real volumes are equal
1726 * now our ratios should be too. */
1727 o->reference_ratio = o->real_ratio;
1728
1729 /* 3. Recalculate the new stream reference volume based on the
1730 * reference ratio and the sink's reference volume.
1731 *
1732 * This basically calculates:
1733 *
1734 * o->volume = s->reference_volume * o->reference_ratio
1735 *
1736 * This is identical to propagate_reference_volume() */
1737 o->volume = s->reference_volume;
1738 pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
1739 pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
1740
1741 /* Notify if something changed */
1742 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1743
1744 if (o->volume_changed)
1745 o->volume_changed(o);
1746
1747 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1748 }
1749
1750 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1751 propagate_real_volume(o->destination_source, old_real_volume);
1752 }
1753 }
1754
1755 /* Something got changed in the hardware. It probably makes sense
1756 * to save changed hw settings given that hw volume changes not
1757 * triggered by PA are almost certainly done by the user. */
1758 if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1759 s->save_volume = true;
1760 }
1761
1762 /* Called from io thread */
1763 void pa_source_update_volume_and_mute(pa_source *s) {
1764 pa_assert(s);
1765 pa_source_assert_io_context(s);
1766
1767 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
1768 }
1769
1770 /* Called from main thread */
1771 const pa_cvolume *pa_source_get_volume(pa_source *s, bool force_refresh) {
1772 pa_source_assert_ref(s);
1773 pa_assert_ctl_context();
1774 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1775
1776 if (s->refresh_volume || force_refresh) {
1777 struct pa_cvolume old_real_volume;
1778
1779 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1780
1781 old_real_volume = s->real_volume;
1782
1783 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume)
1784 s->get_volume(s);
1785
1786 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
1787
1788 update_real_volume(s, &s->real_volume, &s->channel_map);
1789 propagate_real_volume(s, &old_real_volume);
1790 }
1791
1792 return &s->reference_volume;
1793 }
1794
1795 /* Called from main thread. In volume sharing cases, only the root source may
1796 * call this. */
1797 void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_real_volume) {
1798 pa_cvolume old_real_volume;
1799
1800 pa_source_assert_ref(s);
1801 pa_assert_ctl_context();
1802 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1803 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1804
1805 /* The source implementor may call this if the volume changed to make sure everyone is notified */
1806
1807 old_real_volume = s->real_volume;
1808 update_real_volume(s, new_real_volume, &s->channel_map);
1809 propagate_real_volume(s, &old_real_volume);
1810 }
1811
1812 /* Called from main thread */
1813 void pa_source_set_mute(pa_source *s, bool mute, bool save) {
1814 bool old_muted;
1815
1816 pa_source_assert_ref(s);
1817 pa_assert_ctl_context();
1818 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1819
1820 old_muted = s->muted;
1821 s->muted = mute;
1822 s->save_muted = (old_muted == s->muted && s->save_muted) || save;
1823
1824 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->set_mute)
1825 s->set_mute(s);
1826
1827 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1828
1829 if (old_muted != s->muted)
1830 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1831 }
1832
1833 /* Called from main thread */
1834 bool pa_source_get_mute(pa_source *s, bool force_refresh) {
1835
1836 pa_source_assert_ref(s);
1837 pa_assert_ctl_context();
1838 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1839
1840 if (s->refresh_muted || force_refresh) {
1841 bool old_muted = s->muted;
1842
1843 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_mute)
1844 s->get_mute(s);
1845
1846 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
1847
1848 if (old_muted != s->muted) {
1849 s->save_muted = true;
1850
1851 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1852
1853 /* Make sure the soft mute status stays in sync */
1854 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1855 }
1856 }
1857
1858 return s->muted;
1859 }
1860
1861 /* Called from main thread */
1862 void pa_source_mute_changed(pa_source *s, bool new_muted) {
1863 pa_source_assert_ref(s);
1864 pa_assert_ctl_context();
1865 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1866
1867 /* The source implementor may call this if the mute state changed to make sure everyone is notified */
1868
1869 if (s->muted == new_muted)
1870 return;
1871
1872 s->muted = new_muted;
1873 s->save_muted = true;
1874
1875 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1876 }
1877
1878 /* Called from main thread */
1879 bool pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p) {
1880 pa_source_assert_ref(s);
1881 pa_assert_ctl_context();
1882
1883 if (p)
1884 pa_proplist_update(s->proplist, mode, p);
1885
1886 if (PA_SOURCE_IS_LINKED(s->state)) {
1887 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
1888 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1889 }
1890
1891 return true;
1892 }
1893
1894 /* Called from main thread */
1895 /* FIXME -- this should be dropped and be merged into pa_source_update_proplist() */
1896 void pa_source_set_description(pa_source *s, const char *description) {
1897 const char *old;
1898 pa_source_assert_ref(s);
1899 pa_assert_ctl_context();
1900
1901 if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
1902 return;
1903
1904 old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1905
1906 if (old && description && pa_streq(old, description))
1907 return;
1908
1909 if (description)
1910 pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
1911 else
1912 pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1913
1914 if (PA_SOURCE_IS_LINKED(s->state)) {
1915 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1916 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
1917 }
1918 }
1919
1920 /* Called from main thread */
1921 unsigned pa_source_linked_by(pa_source *s) {
1922 pa_source_assert_ref(s);
1923 pa_assert_ctl_context();
1924 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1925
1926 return pa_idxset_size(s->outputs);
1927 }
1928
1929 /* Called from main thread */
1930 unsigned pa_source_used_by(pa_source *s) {
1931 unsigned ret;
1932
1933 pa_source_assert_ref(s);
1934 pa_assert_ctl_context();
1935 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1936
1937 ret = pa_idxset_size(s->outputs);
1938 pa_assert(ret >= s->n_corked);
1939
1940 return ret - s->n_corked;
1941 }
1942
1943 /* Called from main thread */
1944 unsigned pa_source_check_suspend(pa_source *s) {
1945 unsigned ret;
1946 pa_source_output *o;
1947 uint32_t idx;
1948
1949 pa_source_assert_ref(s);
1950 pa_assert_ctl_context();
1951
1952 if (!PA_SOURCE_IS_LINKED(s->state))
1953 return 0;
1954
1955 ret = 0;
1956
1957 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1958 pa_source_output_state_t st;
1959
1960 st = pa_source_output_get_state(o);
1961
1962 /* We do not assert here. It is perfectly valid for a source output to
1963 * be in the INIT state (i.e. created, marked done but not yet put)
1964 * and we should not care if it's unlinked as it won't contribute
1965 * towards our busy status.
1966 */
1967 if (!PA_SOURCE_OUTPUT_IS_LINKED(st))
1968 continue;
1969
1970 if (st == PA_SOURCE_OUTPUT_CORKED)
1971 continue;
1972
1973 if (o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND)
1974 continue;
1975
1976 ret ++;
1977 }
1978
1979 return ret;
1980 }
1981
1982 /* Called from the IO thread */
1983 static void sync_output_volumes_within_thread(pa_source *s) {
1984 pa_source_output *o;
1985 void *state = NULL;
1986
1987 pa_source_assert_ref(s);
1988 pa_source_assert_io_context(s);
1989
1990 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
1991 if (pa_cvolume_equal(&o->thread_info.soft_volume, &o->soft_volume))
1992 continue;
1993
1994 o->thread_info.soft_volume = o->soft_volume;
1995 //pa_source_output_request_rewind(o, 0, true, false, false);
1996 }
1997 }
1998
1999 /* Called from the IO thread. Only called for the root source in volume sharing
2000 * cases, except for internal recursive calls. */
2001 static void set_shared_volume_within_thread(pa_source *s) {
2002 pa_source_output *o;
2003 void *state = NULL;
2004
2005 pa_source_assert_ref(s);
2006
2007 PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2008
2009 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
2010 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
2011 set_shared_volume_within_thread(o->destination_source);
2012 }
2013 }
2014
2015 /* Called from IO thread, except when it is not */
2016 int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2017 pa_source *s = PA_SOURCE(object);
2018 pa_source_assert_ref(s);
2019
2020 switch ((pa_source_message_t) code) {
2021
2022 case PA_SOURCE_MESSAGE_ADD_OUTPUT: {
2023 pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
2024
2025 pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o));
2026
2027 if (o->direct_on_input) {
2028 o->thread_info.direct_on_input = o->direct_on_input;
2029 pa_hashmap_put(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index), o);
2030 }
2031
2032 pa_assert(!o->thread_info.attached);
2033 o->thread_info.attached = true;
2034
2035 if (o->attach)
2036 o->attach(o);
2037
2038 pa_source_output_set_state_within_thread(o, o->state);
2039
2040 if (o->thread_info.requested_source_latency != (pa_usec_t) -1)
2041 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
2042
2043 pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
2044
2045 /* We don't just invalidate the requested latency here,
2046 * because if we are in a move we might need to fix up the
2047 * requested latency. */
2048 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
2049
2050 /* In flat volume mode we need to update the volume as
2051 * well */
2052 return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2053 }
2054
2055 case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: {
2056 pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
2057
2058 pa_source_output_set_state_within_thread(o, o->state);
2059
2060 if (o->detach)
2061 o->detach(o);
2062
2063 pa_assert(o->thread_info.attached);
2064 o->thread_info.attached = false;
2065
2066 if (o->thread_info.direct_on_input) {
2067 pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index));
2068 o->thread_info.direct_on_input = NULL;
2069 }
2070
2071 if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
2072 pa_source_output_unref(o);
2073
2074 pa_source_invalidate_requested_latency(s, true);
2075
2076 /* In flat volume mode we need to update the volume as
2077 * well */
2078 return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2079 }
2080
2081 case PA_SOURCE_MESSAGE_SET_SHARED_VOLUME: {
2082 pa_source *root_source = pa_source_get_master(s);
2083
2084 if (PA_LIKELY(root_source))
2085 set_shared_volume_within_thread(root_source);
2086
2087 return 0;
2088 }
2089
2090 case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED:
2091
2092 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
2093 s->set_volume(s);
2094 pa_source_volume_change_push(s);
2095 }
2096 /* Fall through ... */
2097
2098 case PA_SOURCE_MESSAGE_SET_VOLUME:
2099
2100 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2101 s->thread_info.soft_volume = s->soft_volume;
2102 }
2103
2104 /* Fall through ... */
2105
2106 case PA_SOURCE_MESSAGE_SYNC_VOLUMES:
2107 sync_output_volumes_within_thread(s);
2108 return 0;
2109
2110 case PA_SOURCE_MESSAGE_GET_VOLUME:
2111
2112 if ((s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume) {
2113 s->get_volume(s);
2114 pa_source_volume_change_flush(s);
2115 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2116 }
2117
2118 /* In case source implementor reset SW volume. */
2119 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2120 s->thread_info.soft_volume = s->soft_volume;
2121 }
2122
2123 return 0;
2124
2125 case PA_SOURCE_MESSAGE_SET_MUTE:
2126
2127 if (s->thread_info.soft_muted != s->muted) {
2128 s->thread_info.soft_muted = s->muted;
2129 }
2130
2131 if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->set_mute)
2132 s->set_mute(s);
2133
2134 return 0;
2135
2136 case PA_SOURCE_MESSAGE_GET_MUTE:
2137
2138 if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->get_mute)
2139 s->get_mute(s);
2140
2141 return 0;
2142
2143 case PA_SOURCE_MESSAGE_SET_STATE: {
2144
2145 bool suspend_change =
2146 (s->thread_info.state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2147 (PA_SOURCE_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SOURCE_SUSPENDED);
2148
2149 s->thread_info.state = PA_PTR_TO_UINT(userdata);
2150
2151 if (suspend_change) {
2152 pa_source_output *o;
2153 void *state = NULL;
2154
2155 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
2156 if (o->suspend_within_thread)
2157 o->suspend_within_thread(o, s->thread_info.state == PA_SOURCE_SUSPENDED);
2158 }
2159
2160 return 0;
2161 }
2162
2163 case PA_SOURCE_MESSAGE_DETACH:
2164
2165 /* Detach all streams */
2166 pa_source_detach_within_thread(s);
2167 return 0;
2168
2169 case PA_SOURCE_MESSAGE_ATTACH:
2170
2171 /* Reattach all streams */
2172 pa_source_attach_within_thread(s);
2173 return 0;
2174
2175 case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: {
2176
2177 pa_usec_t *usec = userdata;
2178 *usec = pa_source_get_requested_latency_within_thread(s);
2179
2180 /* Yes, that's right, the IO thread will see -1 when no
2181 * explicit requested latency is configured, the main
2182 * thread will see max_latency */
2183 if (*usec == (pa_usec_t) -1)
2184 *usec = s->thread_info.max_latency;
2185
2186 return 0;
2187 }
2188
2189 case PA_SOURCE_MESSAGE_SET_LATENCY_RANGE: {
2190 pa_usec_t *r = userdata;
2191
2192 pa_source_set_latency_range_within_thread(s, r[0], r[1]);
2193
2194 return 0;
2195 }
2196
2197 case PA_SOURCE_MESSAGE_GET_LATENCY_RANGE: {
2198 pa_usec_t *r = userdata;
2199
2200 r[0] = s->thread_info.min_latency;
2201 r[1] = s->thread_info.max_latency;
2202
2203 return 0;
2204 }
2205
2206 case PA_SOURCE_MESSAGE_GET_FIXED_LATENCY:
2207
2208 *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2209 return 0;
2210
2211 case PA_SOURCE_MESSAGE_SET_FIXED_LATENCY:
2212
2213 pa_source_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2214 return 0;
2215
2216 case PA_SOURCE_MESSAGE_GET_MAX_REWIND:
2217
2218 *((size_t*) userdata) = s->thread_info.max_rewind;
2219 return 0;
2220
2221 case PA_SOURCE_MESSAGE_SET_MAX_REWIND:
2222
2223 pa_source_set_max_rewind_within_thread(s, (size_t) offset);
2224 return 0;
2225
2226 case PA_SOURCE_MESSAGE_GET_LATENCY:
2227
2228 if (s->monitor_of) {
2229 *((pa_usec_t*) userdata) = 0;
2230 return 0;
2231 }
2232
2233 /* Implementors need to overwrite this implementation! */
2234 return -1;
2235
2236 case PA_SOURCE_MESSAGE_SET_PORT:
2237
2238 pa_assert(userdata);
2239 if (s->set_port) {
2240 struct source_message_set_port *msg_data = userdata;
2241 msg_data->ret = s->set_port(s, msg_data->port);
2242 }
2243 return 0;
2244
2245 case PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2246 /* This message is sent from IO-thread and handled in main thread. */
2247 pa_assert_ctl_context();
2248
2249 /* Make sure we're not messing with main thread when no longer linked */
2250 if (!PA_SOURCE_IS_LINKED(s->state))
2251 return 0;
2252
2253 pa_source_get_volume(s, true);
2254 pa_source_get_mute(s, true);
2255 return 0;
2256
2257 case PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET:
2258 s->thread_info.latency_offset = offset;
2259 return 0;
2260
2261 case PA_SOURCE_MESSAGE_MAX:
2262 ;
2263 }
2264
2265 return -1;
2266 }
2267
2268 /* Called from main thread */
2269 int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
2270 pa_source *source;
2271 uint32_t idx;
2272 int ret = 0;
2273
2274 pa_core_assert_ref(c);
2275 pa_assert_ctl_context();
2276 pa_assert(cause != 0);
2277
2278 for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) {
2279 int r;
2280
2281 if (source->monitor_of)
2282 continue;
2283
2284 if ((r = pa_source_suspend(source, suspend, cause)) < 0)
2285 ret = r;
2286 }
2287
2288 return ret;
2289 }
2290
2291 /* Called from main thread */
2292 void pa_source_detach(pa_source *s) {
2293 pa_source_assert_ref(s);
2294 pa_assert_ctl_context();
2295 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2296
2297 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL) == 0);
2298 }
2299
2300 /* Called from main thread */
2301 void pa_source_attach(pa_source *s) {
2302 pa_source_assert_ref(s);
2303 pa_assert_ctl_context();
2304 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2305
2306 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
2307 }
2308
2309 /* Called from IO thread */
2310 void pa_source_detach_within_thread(pa_source *s) {
2311 pa_source_output *o;
2312 void *state = NULL;
2313
2314 pa_source_assert_ref(s);
2315 pa_source_assert_io_context(s);
2316 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
2317
2318 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2319 if (o->detach)
2320 o->detach(o);
2321 }
2322
2323 /* Called from IO thread */
2324 void pa_source_attach_within_thread(pa_source *s) {
2325 pa_source_output *o;
2326 void *state = NULL;
2327
2328 pa_source_assert_ref(s);
2329 pa_source_assert_io_context(s);
2330 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
2331
2332 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2333 if (o->attach)
2334 o->attach(o);
2335 }
2336
2337 /* Called from IO thread */
2338 pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
2339 pa_usec_t result = (pa_usec_t) -1;
2340 pa_source_output *o;
2341 void *state = NULL;
2342
2343 pa_source_assert_ref(s);
2344 pa_source_assert_io_context(s);
2345
2346 if (!(s->flags & PA_SOURCE_DYNAMIC_LATENCY))
2347 return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2348
2349 if (s->thread_info.requested_latency_valid)
2350 return s->thread_info.requested_latency;
2351
2352 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2353 if (o->thread_info.requested_source_latency != (pa_usec_t) -1 &&
2354 (result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency))
2355 result = o->thread_info.requested_source_latency;
2356
2357 if (result != (pa_usec_t) -1)
2358 result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
2359
2360 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2361 /* Only cache this if we are fully set up */
2362 s->thread_info.requested_latency = result;
2363 s->thread_info.requested_latency_valid = true;
2364 }
2365
2366 return result;
2367 }
2368
2369 /* Called from main thread */
2370 pa_usec_t pa_source_get_requested_latency(pa_source *s) {
2371 pa_usec_t usec = 0;
2372
2373 pa_source_assert_ref(s);
2374 pa_assert_ctl_context();
2375 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2376
2377 if (s->state == PA_SOURCE_SUSPENDED)
2378 return 0;
2379
2380 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
2381
2382 return usec;
2383 }
2384
2385 /* Called from IO thread */
2386 void pa_source_set_max_rewind_within_thread(pa_source *s, size_t max_rewind) {
2387 pa_source_output *o;
2388 void *state = NULL;
2389
2390 pa_source_assert_ref(s);
2391 pa_source_assert_io_context(s);
2392
2393 if (max_rewind == s->thread_info.max_rewind)
2394 return;
2395
2396 s->thread_info.max_rewind = max_rewind;
2397
2398 if (PA_SOURCE_IS_LINKED(s->thread_info.state))
2399 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2400 pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
2401 }
2402
2403 /* Called from main thread */
2404 void pa_source_set_max_rewind(pa_source *s, size_t max_rewind) {
2405 pa_source_assert_ref(s);
2406 pa_assert_ctl_context();
2407
2408 if (PA_SOURCE_IS_LINKED(s->state))
2409 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
2410 else
2411 pa_source_set_max_rewind_within_thread(s, max_rewind);
2412 }
2413
2414 /* Called from IO thread */
2415 void pa_source_invalidate_requested_latency(pa_source *s, bool dynamic) {
2416 pa_source_output *o;
2417 void *state = NULL;
2418
2419 pa_source_assert_ref(s);
2420 pa_source_assert_io_context(s);
2421
2422 if ((s->flags & PA_SOURCE_DYNAMIC_LATENCY))
2423 s->thread_info.requested_latency_valid = false;
2424 else if (dynamic)
2425 return;
2426
2427 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2428
2429 if (s->update_requested_latency)
2430 s->update_requested_latency(s);
2431
2432 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
2433 if (o->update_source_requested_latency)
2434 o->update_source_requested_latency(o);
2435 }
2436
2437 if (s->monitor_of)
2438 pa_sink_invalidate_requested_latency(s->monitor_of, dynamic);
2439 }
2440
2441 /* Called from main thread */
2442 void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2443 pa_source_assert_ref(s);
2444 pa_assert_ctl_context();
2445
2446 /* min_latency == 0: no limit
2447 * min_latency anything else: specified limit
2448 *
2449 * Similar for max_latency */
2450
2451 if (min_latency < ABSOLUTE_MIN_LATENCY)
2452 min_latency = ABSOLUTE_MIN_LATENCY;
2453
2454 if (max_latency <= 0 ||
2455 max_latency > ABSOLUTE_MAX_LATENCY)
2456 max_latency = ABSOLUTE_MAX_LATENCY;
2457
2458 pa_assert(min_latency <= max_latency);
2459
2460 /* Hmm, let's see if someone forgot to set PA_SOURCE_DYNAMIC_LATENCY here... */
2461 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2462 max_latency == ABSOLUTE_MAX_LATENCY) ||
2463 (s->flags & PA_SOURCE_DYNAMIC_LATENCY));
2464
2465 if (PA_SOURCE_IS_LINKED(s->state)) {
2466 pa_usec_t r[2];
2467
2468 r[0] = min_latency;
2469 r[1] = max_latency;
2470
2471 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
2472 } else
2473 pa_source_set_latency_range_within_thread(s, min_latency, max_latency);
2474 }
2475
2476 /* Called from main thread */
2477 void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
2478 pa_source_assert_ref(s);
2479 pa_assert_ctl_context();
2480 pa_assert(min_latency);
2481 pa_assert(max_latency);
2482
2483 if (PA_SOURCE_IS_LINKED(s->state)) {
2484 pa_usec_t r[2] = { 0, 0 };
2485
2486 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
2487
2488 *min_latency = r[0];
2489 *max_latency = r[1];
2490 } else {
2491 *min_latency = s->thread_info.min_latency;
2492 *max_latency = s->thread_info.max_latency;
2493 }
2494 }
2495
2496 /* Called from IO thread, and from main thread before pa_source_put() is called */
2497 void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2498 pa_source_assert_ref(s);
2499 pa_source_assert_io_context(s);
2500
2501 pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
2502 pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
2503 pa_assert(min_latency <= max_latency);
2504
2505 /* Hmm, let's see if someone forgot to set PA_SOURCE_DYNAMIC_LATENCY here... */
2506 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2507 max_latency == ABSOLUTE_MAX_LATENCY) ||
2508 (s->flags & PA_SOURCE_DYNAMIC_LATENCY) ||
2509 s->monitor_of);
2510
2511 if (s->thread_info.min_latency == min_latency &&
2512 s->thread_info.max_latency == max_latency)
2513 return;
2514
2515 s->thread_info.min_latency = min_latency;
2516 s->thread_info.max_latency = max_latency;
2517
2518 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2519 pa_source_output *o;
2520 void *state = NULL;
2521
2522 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2523 if (o->update_source_latency_range)
2524 o->update_source_latency_range(o);
2525 }
2526
2527 pa_source_invalidate_requested_latency(s, false);
2528 }
2529
2530 /* Called from main thread, before the source is put */
2531 void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency) {
2532 pa_source_assert_ref(s);
2533 pa_assert_ctl_context();
2534
2535 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) {
2536 pa_assert(latency == 0);
2537 return;
2538 }
2539
2540 if (latency < ABSOLUTE_MIN_LATENCY)
2541 latency = ABSOLUTE_MIN_LATENCY;
2542
2543 if (latency > ABSOLUTE_MAX_LATENCY)
2544 latency = ABSOLUTE_MAX_LATENCY;
2545
2546 if (PA_SOURCE_IS_LINKED(s->state))
2547 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
2548 else
2549 s->thread_info.fixed_latency = latency;
2550 }
2551
2552 /* Called from main thread */
2553 pa_usec_t pa_source_get_fixed_latency(pa_source *s) {
2554 pa_usec_t latency;
2555
2556 pa_source_assert_ref(s);
2557 pa_assert_ctl_context();
2558
2559 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY)
2560 return 0;
2561
2562 if (PA_SOURCE_IS_LINKED(s->state))
2563 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
2564 else
2565 latency = s->thread_info.fixed_latency;
2566
2567 return latency;
2568 }
2569
2570 /* Called from IO thread */
2571 void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency) {
2572 pa_source_assert_ref(s);
2573 pa_source_assert_io_context(s);
2574
2575 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) {
2576 pa_assert(latency == 0);
2577 s->thread_info.fixed_latency = 0;
2578
2579 return;
2580 }
2581
2582 pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
2583 pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
2584
2585 if (s->thread_info.fixed_latency == latency)
2586 return;
2587
2588 s->thread_info.fixed_latency = latency;
2589
2590 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2591 pa_source_output *o;
2592 void *state = NULL;
2593
2594 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2595 if (o->update_source_fixed_latency)
2596 o->update_source_fixed_latency(o);
2597 }
2598
2599 pa_source_invalidate_requested_latency(s, false);
2600 }
2601
2602 /* Called from main thread */
2603 void pa_source_set_latency_offset(pa_source *s, int64_t offset) {
2604 pa_source_assert_ref(s);
2605
2606 s->latency_offset = offset;
2607
2608 if (PA_SOURCE_IS_LINKED(s->state))
2609 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
2610 else
2611 s->thread_info.latency_offset = offset;
2612 }
2613
2614 /* Called from main thread */
2615 size_t pa_source_get_max_rewind(pa_source *s) {
2616 size_t r;
2617 pa_assert_ctl_context();
2618 pa_source_assert_ref(s);
2619
2620 if (!PA_SOURCE_IS_LINKED(s->state))
2621 return s->thread_info.max_rewind;
2622
2623 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
2624
2625 return r;
2626 }
2627
2628 /* Called from main context */
2629 int pa_source_set_port(pa_source *s, const char *name, bool save) {
2630 pa_device_port *port;
2631 int ret;
2632
2633 pa_source_assert_ref(s);
2634 pa_assert_ctl_context();
2635
2636 if (!s->set_port) {
2637 pa_log_debug("set_port() operation not implemented for source %u \"%s\"", s->index, s->name);
2638 return -PA_ERR_NOTIMPLEMENTED;
2639 }
2640
2641 if (!name)
2642 return -PA_ERR_NOENTITY;
2643
2644 if (!(port = pa_hashmap_get(s->ports, name)))
2645 return -PA_ERR_NOENTITY;
2646
2647 if (s->active_port == port) {
2648 s->save_port = s->save_port || save;
2649 return 0;
2650 }
2651
2652 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
2653 struct source_message_set_port msg = { .port = port, .ret = 0 };
2654 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
2655 ret = msg.ret;
2656 }
2657 else
2658 ret = s->set_port(s, port);
2659
2660 if (ret < 0)
2661 return -PA_ERR_NOENTITY;
2662
2663 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2664
2665 pa_log_info("Changed port of source %u \"%s\" to %s", s->index, s->name, port->name);
2666
2667 s->active_port = port;
2668 s->save_port = save;
2669
2670 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
2671
2672 return 0;
2673 }
2674
2675 PA_STATIC_FLIST_DECLARE(pa_source_volume_change, 0, pa_xfree);
2676
2677 /* Called from the IO thread. */
2678 static pa_source_volume_change *pa_source_volume_change_new(pa_source *s) {
2679 pa_source_volume_change *c;
2680 if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_source_volume_change))))
2681 c = pa_xnew(pa_source_volume_change, 1);
2682
2683 PA_LLIST_INIT(pa_source_volume_change, c);
2684 c->at = 0;
2685 pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
2686 return c;
2687 }
2688
2689 /* Called from the IO thread. */
2690 static void pa_source_volume_change_free(pa_source_volume_change *c) {
2691 pa_assert(c);
2692 if (pa_flist_push(PA_STATIC_FLIST_GET(pa_source_volume_change), c) < 0)
2693 pa_xfree(c);
2694 }
2695
2696 /* Called from the IO thread. */
2697 void pa_source_volume_change_push(pa_source *s) {
2698 pa_source_volume_change *c = NULL;
2699 pa_source_volume_change *nc = NULL;
2700 uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
2701
2702 const char *direction = NULL;
2703
2704 pa_assert(s);
2705 nc = pa_source_volume_change_new(s);
2706
2707 /* NOTE: There is already more different volumes in pa_source that I can remember.
2708 * Adding one more volume for HW would get us rid of this, but I am trying
2709 * to survive with the ones we already have. */
2710 pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
2711
2712 if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
2713 pa_log_debug("Volume not changing");
2714 pa_source_volume_change_free(nc);
2715 return;
2716 }
2717
2718 nc->at = pa_source_get_latency_within_thread(s);
2719 nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
2720
2721 if (s->thread_info.volume_changes_tail) {
2722 for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
2723 /* If volume is going up let's do it a bit late. If it is going
2724 * down let's do it a bit early. */
2725 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
2726 if (nc->at + safety_margin > c->at) {
2727 nc->at += safety_margin;
2728 direction = "up";
2729 break;
2730 }
2731 }
2732 else if (nc->at - safety_margin > c->at) {
2733 nc->at -= safety_margin;
2734 direction = "down";
2735 break;
2736 }
2737 }
2738 }
2739
2740 if (c == NULL) {
2741 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
2742 nc->at += safety_margin;
2743 direction = "up";
2744 } else {
2745 nc->at -= safety_margin;
2746 direction = "down";
2747 }
2748 PA_LLIST_PREPEND(pa_source_volume_change, s->thread_info.volume_changes, nc);
2749 }
2750 else {
2751 PA_LLIST_INSERT_AFTER(pa_source_volume_change, s->thread_info.volume_changes, c, nc);
2752 }
2753
2754 pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
2755
2756 /* We can ignore volume events that came earlier but should happen later than this. */
2757 PA_LLIST_FOREACH(c, nc->next) {
2758 pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
2759 pa_source_volume_change_free(c);
2760 }
2761 nc->next = NULL;
2762 s->thread_info.volume_changes_tail = nc;
2763 }
2764
2765 /* Called from the IO thread. */
2766 static void pa_source_volume_change_flush(pa_source *s) {
2767 pa_source_volume_change *c = s->thread_info.volume_changes;
2768 pa_assert(s);
2769 s->thread_info.volume_changes = NULL;
2770 s->thread_info.volume_changes_tail = NULL;
2771 while (c) {
2772 pa_source_volume_change *next = c->next;
2773 pa_source_volume_change_free(c);
2774 c = next;
2775 }
2776 }
2777
2778 /* Called from the IO thread. */
2779 bool pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next) {
2780 pa_usec_t now;
2781 bool ret = false;
2782
2783 pa_assert(s);
2784
2785 if (!s->thread_info.volume_changes || !PA_SOURCE_IS_LINKED(s->state)) {
2786 if (usec_to_next)
2787 *usec_to_next = 0;
2788 return ret;
2789 }
2790
2791 pa_assert(s->write_volume);
2792
2793 now = pa_rtclock_now();
2794
2795 while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
2796 pa_source_volume_change *c = s->thread_info.volume_changes;
2797 PA_LLIST_REMOVE(pa_source_volume_change, s->thread_info.volume_changes, c);
2798 pa_log_debug("Volume change to %d at %llu was written %llu usec late",
2799 pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
2800 ret = true;
2801 s->thread_info.current_hw_volume = c->hw_volume;
2802 pa_source_volume_change_free(c);
2803 }
2804
2805 if (ret)
2806 s->write_volume(s);
2807
2808 if (s->thread_info.volume_changes) {
2809 if (usec_to_next)
2810 *usec_to_next = s->thread_info.volume_changes->at - now;
2811 if (pa_log_ratelimit(PA_LOG_DEBUG))
2812 pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
2813 }
2814 else {
2815 if (usec_to_next)
2816 *usec_to_next = 0;
2817 s->thread_info.volume_changes_tail = NULL;
2818 }
2819 return ret;
2820 }
2821
2822 /* Called from the main thread */
2823 /* Gets the list of formats supported by the source. The members and idxset must
2824 * be freed by the caller. */
2825 pa_idxset* pa_source_get_formats(pa_source *s) {
2826 pa_idxset *ret;
2827
2828 pa_assert(s);
2829
2830 if (s->get_formats) {
2831 /* Source supports format query, all is good */
2832 ret = s->get_formats(s);
2833 } else {
2834 /* Source doesn't support format query, so assume it does PCM */
2835 pa_format_info *f = pa_format_info_new();
2836 f->encoding = PA_ENCODING_PCM;
2837
2838 ret = pa_idxset_new(NULL, NULL);
2839 pa_idxset_put(ret, f, NULL);
2840 }
2841
2842 return ret;
2843 }
2844
2845 /* Called from the main thread */
2846 /* Checks if the source can accept this format */
2847 bool pa_source_check_format(pa_source *s, pa_format_info *f) {
2848 pa_idxset *formats = NULL;
2849 bool ret = false;
2850
2851 pa_assert(s);
2852 pa_assert(f);
2853
2854 formats = pa_source_get_formats(s);
2855
2856 if (formats) {
2857 pa_format_info *finfo_device;
2858 uint32_t i;
2859
2860 PA_IDXSET_FOREACH(finfo_device, formats, i) {
2861 if (pa_format_info_is_compatible(finfo_device, f)) {
2862 ret = true;
2863 break;
2864 }
2865 }
2866
2867 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
2868 }
2869
2870 return ret;
2871 }
2872
2873 /* Called from the main thread */
2874 /* Calculates the intersection between formats supported by the source and
2875 * in_formats, and returns these, in the order of the source's formats. */
2876 pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats) {
2877 pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *source_formats = NULL;
2878 pa_format_info *f_source, *f_in;
2879 uint32_t i, j;
2880
2881 pa_assert(s);
2882
2883 if (!in_formats || pa_idxset_isempty(in_formats))
2884 goto done;
2885
2886 source_formats = pa_source_get_formats(s);
2887
2888 PA_IDXSET_FOREACH(f_source, source_formats, i) {
2889 PA_IDXSET_FOREACH(f_in, in_formats, j) {
2890 if (pa_format_info_is_compatible(f_source, f_in))
2891 pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
2892 }
2893 }
2894
2895 done:
2896 if (source_formats)
2897 pa_idxset_free(source_formats, (pa_free_cb_t) pa_format_info_free);
2898
2899 return out_formats;
2900 }