]> code.delx.au - pulseaudio/blob - src/pulsecore/source.c
core: Add an "internal" suspend cause
[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, pa_bool_t 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 pa_bool_t 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, pa_bool_t 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, pa_bool_t 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 pa_bool_t 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, pa_bool_t is_dirty)
744 {
745 pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
746 }
747
748 /* Called from main context */
749 int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
750 pa_source_assert_ref(s);
751 pa_assert_ctl_context();
752 pa_assert(PA_SOURCE_IS_LINKED(s->state));
753 pa_assert(cause != 0);
754
755 if (s->monitor_of && cause != PA_SUSPEND_PASSTHROUGH)
756 return -PA_ERR_NOTSUPPORTED;
757
758 if (suspend)
759 s->suspend_cause |= cause;
760 else
761 s->suspend_cause &= ~cause;
762
763 if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
764 /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
765 it'll be handled just fine. */
766 pa_source_set_mixer_dirty(s, FALSE);
767 pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
768 if (s->active_port && s->set_port) {
769 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
770 struct source_message_set_port msg = { .port = s->active_port, .ret = 0 };
771 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
772 }
773 else
774 s->set_port(s, s->active_port);
775 }
776 else {
777 if (s->set_mute)
778 s->set_mute(s);
779 if (s->set_volume)
780 s->set_volume(s);
781 }
782 }
783
784 if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause)
785 return 0;
786
787 pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
788
789 if (s->suspend_cause)
790 return source_set_state(s, PA_SOURCE_SUSPENDED);
791 else
792 return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
793 }
794
795 /* Called from main context */
796 int pa_source_sync_suspend(pa_source *s) {
797 pa_sink_state_t state;
798
799 pa_source_assert_ref(s);
800 pa_assert_ctl_context();
801 pa_assert(PA_SOURCE_IS_LINKED(s->state));
802 pa_assert(s->monitor_of);
803
804 state = pa_sink_get_state(s->monitor_of);
805
806 if (state == PA_SINK_SUSPENDED)
807 return source_set_state(s, PA_SOURCE_SUSPENDED);
808
809 pa_assert(PA_SINK_IS_OPENED(state));
810
811 return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
812 }
813
814 /* Called from main context */
815 pa_queue *pa_source_move_all_start(pa_source *s, pa_queue *q) {
816 pa_source_output *o, *n;
817 uint32_t idx;
818
819 pa_source_assert_ref(s);
820 pa_assert_ctl_context();
821 pa_assert(PA_SOURCE_IS_LINKED(s->state));
822
823 if (!q)
824 q = pa_queue_new();
825
826 for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = n) {
827 n = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx));
828
829 pa_source_output_ref(o);
830
831 if (pa_source_output_start_move(o) >= 0)
832 pa_queue_push(q, o);
833 else
834 pa_source_output_unref(o);
835 }
836
837 return q;
838 }
839
840 /* Called from main context */
841 void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
842 pa_source_output *o;
843
844 pa_source_assert_ref(s);
845 pa_assert_ctl_context();
846 pa_assert(PA_SOURCE_IS_LINKED(s->state));
847 pa_assert(q);
848
849 while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
850 if (pa_source_output_finish_move(o, s, save) < 0)
851 pa_source_output_fail_move(o);
852
853 pa_source_output_unref(o);
854 }
855
856 pa_queue_free(q, NULL);
857 }
858
859 /* Called from main context */
860 void pa_source_move_all_fail(pa_queue *q) {
861 pa_source_output *o;
862
863 pa_assert_ctl_context();
864 pa_assert(q);
865
866 while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
867 pa_source_output_fail_move(o);
868 pa_source_output_unref(o);
869 }
870
871 pa_queue_free(q, NULL);
872 }
873
874 /* Called from IO thread context */
875 void pa_source_process_rewind(pa_source *s, size_t nbytes) {
876 pa_source_output *o;
877 void *state = NULL;
878
879 pa_source_assert_ref(s);
880 pa_source_assert_io_context(s);
881 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
882
883 if (nbytes <= 0)
884 return;
885
886 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
887 return;
888
889 pa_log_debug("Processing rewind...");
890
891 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
892 pa_source_output_assert_ref(o);
893 pa_source_output_process_rewind(o, nbytes);
894 }
895 }
896
897 /* Called from IO thread context */
898 void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
899 pa_source_output *o;
900 void *state = NULL;
901
902 pa_source_assert_ref(s);
903 pa_source_assert_io_context(s);
904 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
905 pa_assert(chunk);
906
907 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
908 return;
909
910 if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
911 pa_memchunk vchunk = *chunk;
912
913 pa_memblock_ref(vchunk.memblock);
914 pa_memchunk_make_writable(&vchunk, 0);
915
916 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
917 pa_silence_memchunk(&vchunk, &s->sample_spec);
918 else
919 pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
920
921 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
922 pa_source_output_assert_ref(o);
923
924 if (!o->thread_info.direct_on_input)
925 pa_source_output_push(o, &vchunk);
926 }
927
928 pa_memblock_unref(vchunk.memblock);
929 } else {
930
931 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
932 pa_source_output_assert_ref(o);
933
934 if (!o->thread_info.direct_on_input)
935 pa_source_output_push(o, chunk);
936 }
937 }
938 }
939
940 /* Called from IO thread context */
941 void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *chunk) {
942 pa_source_assert_ref(s);
943 pa_source_assert_io_context(s);
944 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
945 pa_source_output_assert_ref(o);
946 pa_assert(o->thread_info.direct_on_input);
947 pa_assert(chunk);
948
949 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
950 return;
951
952 if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
953 pa_memchunk vchunk = *chunk;
954
955 pa_memblock_ref(vchunk.memblock);
956 pa_memchunk_make_writable(&vchunk, 0);
957
958 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
959 pa_silence_memchunk(&vchunk, &s->sample_spec);
960 else
961 pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
962
963 pa_source_output_push(o, &vchunk);
964
965 pa_memblock_unref(vchunk.memblock);
966 } else
967 pa_source_output_push(o, chunk);
968 }
969
970 /* Called from main thread */
971 pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrough)
972 {
973 pa_bool_t ret = FALSE;
974
975 if (s->update_rate) {
976 uint32_t desired_rate = rate;
977 uint32_t default_rate = s->default_sample_rate;
978 uint32_t alternate_rate = s->alternate_sample_rate;
979 uint32_t idx;
980 pa_source_output *o;
981 pa_bool_t use_alternate = FALSE;
982
983 if (PA_UNLIKELY(default_rate == alternate_rate)) {
984 pa_log_warn("Default and alternate sample rates are the same.");
985 return FALSE;
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 FALSE;
992 }
993
994 if (PA_UNLIKELY (desired_rate < 8000 ||
995 desired_rate > PA_RATE_MAX))
996 return FALSE;
997
998 if (!passthrough) {
999 pa_assert(default_rate % 4000 || default_rate % 11025);
1000 pa_assert(alternate_rate % 4000 || alternate_rate % 11025);
1001
1002 if (default_rate % 4000) {
1003 /* default is a 11025 multiple */
1004 if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
1005 use_alternate=TRUE;
1006 } else {
1007 /* default is 4000 multiple */
1008 if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
1009 use_alternate=TRUE;
1010 }
1011
1012 if (use_alternate)
1013 desired_rate = alternate_rate;
1014 else
1015 desired_rate = default_rate;
1016 } else {
1017 desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
1018 }
1019
1020 if (desired_rate == s->sample_spec.rate)
1021 return FALSE;
1022
1023 if (!passthrough && pa_source_used_by(s) > 0)
1024 return FALSE;
1025
1026 pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
1027 pa_source_suspend(s, TRUE, PA_SUSPEND_INTERNAL);
1028
1029 if (s->update_rate(s, desired_rate) == TRUE) {
1030 pa_log_info("Changed sampling rate successfully ");
1031
1032 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1033 if (o->state == PA_SOURCE_OUTPUT_CORKED)
1034 pa_source_output_update_rate(o);
1035 }
1036 ret = TRUE;
1037 }
1038
1039 pa_source_suspend(s, FALSE, PA_SUSPEND_INTERNAL);
1040 }
1041
1042 return ret;
1043 }
1044
1045 /* Called from main thread */
1046 pa_usec_t pa_source_get_latency(pa_source *s) {
1047 pa_usec_t usec;
1048
1049 pa_source_assert_ref(s);
1050 pa_assert_ctl_context();
1051 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1052
1053 if (s->state == PA_SOURCE_SUSPENDED)
1054 return 0;
1055
1056 if (!(s->flags & PA_SOURCE_LATENCY))
1057 return 0;
1058
1059 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
1060
1061 /* usec is unsigned, so check that the offset can be added to usec without
1062 * underflowing. */
1063 if (-s->latency_offset <= (int64_t) usec)
1064 usec += s->latency_offset;
1065 else
1066 usec = 0;
1067
1068 return usec;
1069 }
1070
1071 /* Called from IO thread */
1072 pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {
1073 pa_usec_t usec = 0;
1074 pa_msgobject *o;
1075
1076 pa_source_assert_ref(s);
1077 pa_source_assert_io_context(s);
1078 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
1079
1080 /* The returned value is supposed to be in the time domain of the sound card! */
1081
1082 if (s->thread_info.state == PA_SOURCE_SUSPENDED)
1083 return 0;
1084
1085 if (!(s->flags & PA_SOURCE_LATENCY))
1086 return 0;
1087
1088 o = PA_MSGOBJECT(s);
1089
1090 /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
1091
1092 if (o->process_msg(o, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1093 return -1;
1094
1095 /* usec is unsigned, so check that the offset can be added to usec without
1096 * underflowing. */
1097 if (-s->thread_info.latency_offset <= (int64_t) usec)
1098 usec += s->thread_info.latency_offset;
1099 else
1100 usec = 0;
1101
1102 return usec;
1103 }
1104
1105 /* Called from the main thread (and also from the IO thread while the main
1106 * thread is waiting).
1107 *
1108 * When a source uses volume sharing, it never has the PA_SOURCE_FLAT_VOLUME flag
1109 * set. Instead, flat volume mode is detected by checking whether the root source
1110 * has the flag set. */
1111 pa_bool_t pa_source_flat_volume_enabled(pa_source *s) {
1112 pa_source_assert_ref(s);
1113
1114 s = pa_source_get_master(s);
1115
1116 if (PA_LIKELY(s))
1117 return (s->flags & PA_SOURCE_FLAT_VOLUME);
1118 else
1119 return FALSE;
1120 }
1121
1122 /* Called from the main thread (and also from the IO thread while the main
1123 * thread is waiting). */
1124 pa_source *pa_source_get_master(pa_source *s) {
1125 pa_source_assert_ref(s);
1126
1127 while (s && (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1128 if (PA_UNLIKELY(!s->output_from_master))
1129 return NULL;
1130
1131 s = s->output_from_master->source;
1132 }
1133
1134 return s;
1135 }
1136
1137 /* Called from main context */
1138 pa_bool_t pa_source_is_passthrough(pa_source *s) {
1139
1140 pa_source_assert_ref(s);
1141
1142 /* NB Currently only monitor sources support passthrough mode */
1143 return (s->monitor_of && pa_sink_is_passthrough(s->monitor_of));
1144 }
1145
1146 /* Called from main context */
1147 void pa_source_enter_passthrough(pa_source *s) {
1148 pa_cvolume volume;
1149
1150 /* set the volume to NORM */
1151 s->saved_volume = *pa_source_get_volume(s, TRUE);
1152 s->saved_save_volume = s->save_volume;
1153
1154 pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
1155 pa_source_set_volume(s, &volume, TRUE, FALSE);
1156 }
1157
1158 /* Called from main context */
1159 void pa_source_leave_passthrough(pa_source *s) {
1160 /* Restore source volume to what it was before we entered passthrough mode */
1161 pa_source_set_volume(s, &s->saved_volume, TRUE, s->saved_save_volume);
1162
1163 pa_cvolume_init(&s->saved_volume);
1164 s->saved_save_volume = FALSE;
1165 }
1166
1167 /* Called from main context. */
1168 static void compute_reference_ratio(pa_source_output *o) {
1169 unsigned c = 0;
1170 pa_cvolume remapped;
1171
1172 pa_assert(o);
1173 pa_assert(pa_source_flat_volume_enabled(o->source));
1174
1175 /*
1176 * Calculates the reference ratio from the source's reference
1177 * volume. This basically calculates:
1178 *
1179 * o->reference_ratio = o->volume / o->source->reference_volume
1180 */
1181
1182 remapped = o->source->reference_volume;
1183 pa_cvolume_remap(&remapped, &o->source->channel_map, &o->channel_map);
1184
1185 o->reference_ratio.channels = o->sample_spec.channels;
1186
1187 for (c = 0; c < o->sample_spec.channels; c++) {
1188
1189 /* We don't update when the source volume is 0 anyway */
1190 if (remapped.values[c] <= PA_VOLUME_MUTED)
1191 continue;
1192
1193 /* Don't update the reference ratio unless necessary */
1194 if (pa_sw_volume_multiply(
1195 o->reference_ratio.values[c],
1196 remapped.values[c]) == o->volume.values[c])
1197 continue;
1198
1199 o->reference_ratio.values[c] = pa_sw_volume_divide(
1200 o->volume.values[c],
1201 remapped.values[c]);
1202 }
1203 }
1204
1205 /* Called from main context. Only called for the root source in volume sharing
1206 * cases, except for internal recursive calls. */
1207 static void compute_reference_ratios(pa_source *s) {
1208 uint32_t idx;
1209 pa_source_output *o;
1210
1211 pa_source_assert_ref(s);
1212 pa_assert_ctl_context();
1213 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1214 pa_assert(pa_source_flat_volume_enabled(s));
1215
1216 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1217 compute_reference_ratio(o);
1218
1219 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1220 compute_reference_ratios(o->destination_source);
1221 }
1222 }
1223
1224 /* Called from main context. Only called for the root source in volume sharing
1225 * cases, except for internal recursive calls. */
1226 static void compute_real_ratios(pa_source *s) {
1227 pa_source_output *o;
1228 uint32_t idx;
1229
1230 pa_source_assert_ref(s);
1231 pa_assert_ctl_context();
1232 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1233 pa_assert(pa_source_flat_volume_enabled(s));
1234
1235 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1236 unsigned c;
1237 pa_cvolume remapped;
1238
1239 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1240 /* The origin source uses volume sharing, so this input's real ratio
1241 * is handled as a special case - the real ratio must be 0 dB, and
1242 * as a result i->soft_volume must equal i->volume_factor. */
1243 pa_cvolume_reset(&o->real_ratio, o->real_ratio.channels);
1244 o->soft_volume = o->volume_factor;
1245
1246 compute_real_ratios(o->destination_source);
1247
1248 continue;
1249 }
1250
1251 /*
1252 * This basically calculates:
1253 *
1254 * i->real_ratio := i->volume / s->real_volume
1255 * i->soft_volume := i->real_ratio * i->volume_factor
1256 */
1257
1258 remapped = s->real_volume;
1259 pa_cvolume_remap(&remapped, &s->channel_map, &o->channel_map);
1260
1261 o->real_ratio.channels = o->sample_spec.channels;
1262 o->soft_volume.channels = o->sample_spec.channels;
1263
1264 for (c = 0; c < o->sample_spec.channels; c++) {
1265
1266 if (remapped.values[c] <= PA_VOLUME_MUTED) {
1267 /* We leave o->real_ratio untouched */
1268 o->soft_volume.values[c] = PA_VOLUME_MUTED;
1269 continue;
1270 }
1271
1272 /* Don't lose accuracy unless necessary */
1273 if (pa_sw_volume_multiply(
1274 o->real_ratio.values[c],
1275 remapped.values[c]) != o->volume.values[c])
1276
1277 o->real_ratio.values[c] = pa_sw_volume_divide(
1278 o->volume.values[c],
1279 remapped.values[c]);
1280
1281 o->soft_volume.values[c] = pa_sw_volume_multiply(
1282 o->real_ratio.values[c],
1283 o->volume_factor.values[c]);
1284 }
1285
1286 /* We don't copy the soft_volume to the thread_info data
1287 * here. That must be done by the caller */
1288 }
1289 }
1290
1291 static pa_cvolume *cvolume_remap_minimal_impact(
1292 pa_cvolume *v,
1293 const pa_cvolume *template,
1294 const pa_channel_map *from,
1295 const pa_channel_map *to) {
1296
1297 pa_cvolume t;
1298
1299 pa_assert(v);
1300 pa_assert(template);
1301 pa_assert(from);
1302 pa_assert(to);
1303 pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
1304 pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
1305
1306 /* Much like pa_cvolume_remap(), but tries to minimize impact when
1307 * mapping from source output to source volumes:
1308 *
1309 * If template is a possible remapping from v it is used instead
1310 * of remapping anew.
1311 *
1312 * If the channel maps don't match we set an all-channel volume on
1313 * the source to ensure that changing a volume on one stream has no
1314 * effect that cannot be compensated for in another stream that
1315 * does not have the same channel map as the source. */
1316
1317 if (pa_channel_map_equal(from, to))
1318 return v;
1319
1320 t = *template;
1321 if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
1322 *v = *template;
1323 return v;
1324 }
1325
1326 pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
1327 return v;
1328 }
1329
1330 /* Called from main thread. Only called for the root source in volume sharing
1331 * cases, except for internal recursive calls. */
1332 static void get_maximum_output_volume(pa_source *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
1333 pa_source_output *o;
1334 uint32_t idx;
1335
1336 pa_source_assert_ref(s);
1337 pa_assert(max_volume);
1338 pa_assert(channel_map);
1339 pa_assert(pa_source_flat_volume_enabled(s));
1340
1341 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1342 pa_cvolume remapped;
1343
1344 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1345 get_maximum_output_volume(o->destination_source, max_volume, channel_map);
1346
1347 /* Ignore this output. The origin source uses volume sharing, so this
1348 * output's volume will be set to be equal to the root source's real
1349 * volume. Obviously this output's current volume must not then
1350 * affect what the root source's real volume will be. */
1351 continue;
1352 }
1353
1354 remapped = o->volume;
1355 cvolume_remap_minimal_impact(&remapped, max_volume, &o->channel_map, channel_map);
1356 pa_cvolume_merge(max_volume, max_volume, &remapped);
1357 }
1358 }
1359
1360 /* Called from main thread. Only called for the root source in volume sharing
1361 * cases, except for internal recursive calls. */
1362 static pa_bool_t has_outputs(pa_source *s) {
1363 pa_source_output *o;
1364 uint32_t idx;
1365
1366 pa_source_assert_ref(s);
1367
1368 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1369 if (!o->destination_source || !(o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || has_outputs(o->destination_source))
1370 return TRUE;
1371 }
1372
1373 return FALSE;
1374 }
1375
1376 /* Called from main thread. Only called for the root source in volume sharing
1377 * cases, except for internal recursive calls. */
1378 static void update_real_volume(pa_source *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
1379 pa_source_output *o;
1380 uint32_t idx;
1381
1382 pa_source_assert_ref(s);
1383 pa_assert(new_volume);
1384 pa_assert(channel_map);
1385
1386 s->real_volume = *new_volume;
1387 pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
1388
1389 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1390 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1391 if (pa_source_flat_volume_enabled(s)) {
1392 pa_cvolume old_volume = o->volume;
1393
1394 /* Follow the root source's real volume. */
1395 o->volume = *new_volume;
1396 pa_cvolume_remap(&o->volume, channel_map, &o->channel_map);
1397 compute_reference_ratio(o);
1398
1399 /* The volume changed, let's tell people so */
1400 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1401 if (o->volume_changed)
1402 o->volume_changed(o);
1403
1404 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1405 }
1406 }
1407
1408 update_real_volume(o->destination_source, new_volume, channel_map);
1409 }
1410 }
1411 }
1412
1413 /* Called from main thread. Only called for the root source in shared volume
1414 * cases. */
1415 static void compute_real_volume(pa_source *s) {
1416 pa_source_assert_ref(s);
1417 pa_assert_ctl_context();
1418 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1419 pa_assert(pa_source_flat_volume_enabled(s));
1420 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1421
1422 /* This determines the maximum volume of all streams and sets
1423 * s->real_volume accordingly. */
1424
1425 if (!has_outputs(s)) {
1426 /* In the special case that we have no source outputs we leave the
1427 * volume unmodified. */
1428 update_real_volume(s, &s->reference_volume, &s->channel_map);
1429 return;
1430 }
1431
1432 pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1433
1434 /* First let's determine the new maximum volume of all outputs
1435 * connected to this source */
1436 get_maximum_output_volume(s, &s->real_volume, &s->channel_map);
1437 update_real_volume(s, &s->real_volume, &s->channel_map);
1438
1439 /* Then, let's update the real ratios/soft volumes of all outputs
1440 * connected to this source */
1441 compute_real_ratios(s);
1442 }
1443
1444 /* Called from main thread. Only called for the root source in shared volume
1445 * cases, except for internal recursive calls. */
1446 static void propagate_reference_volume(pa_source *s) {
1447 pa_source_output *o;
1448 uint32_t idx;
1449
1450 pa_source_assert_ref(s);
1451 pa_assert_ctl_context();
1452 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1453 pa_assert(pa_source_flat_volume_enabled(s));
1454
1455 /* This is called whenever the source volume changes that is not
1456 * caused by a source output volume change. We need to fix up the
1457 * source output volumes accordingly */
1458
1459 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1460 pa_cvolume old_volume;
1461
1462 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1463 propagate_reference_volume(o->destination_source);
1464
1465 /* Since the origin source uses volume sharing, this output's volume
1466 * needs to be updated to match the root source's real volume, but
1467 * that will be done later in update_shared_real_volume(). */
1468 continue;
1469 }
1470
1471 old_volume = o->volume;
1472
1473 /* This basically calculates:
1474 *
1475 * o->volume := o->reference_volume * o->reference_ratio */
1476
1477 o->volume = s->reference_volume;
1478 pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
1479 pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
1480
1481 /* The volume changed, let's tell people so */
1482 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1483
1484 if (o->volume_changed)
1485 o->volume_changed(o);
1486
1487 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1488 }
1489 }
1490 }
1491
1492 /* Called from main thread. Only called for the root source in volume sharing
1493 * cases, except for internal recursive calls. The return value indicates
1494 * whether any reference volume actually changed. */
1495 static pa_bool_t update_reference_volume(pa_source *s, const pa_cvolume *v, const pa_channel_map *channel_map, pa_bool_t save) {
1496 pa_cvolume volume;
1497 pa_bool_t reference_volume_changed;
1498 pa_source_output *o;
1499 uint32_t idx;
1500
1501 pa_source_assert_ref(s);
1502 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1503 pa_assert(v);
1504 pa_assert(channel_map);
1505 pa_assert(pa_cvolume_valid(v));
1506
1507 volume = *v;
1508 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
1509
1510 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
1511 s->reference_volume = volume;
1512
1513 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
1514
1515 if (reference_volume_changed)
1516 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1517 else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1518 /* If the root source's volume doesn't change, then there can't be any
1519 * changes in the other source in the source tree either.
1520 *
1521 * It's probably theoretically possible that even if the root source's
1522 * volume changes slightly, some filter source doesn't change its volume
1523 * due to rounding errors. If that happens, we still want to propagate
1524 * the changed root source volume to the sources connected to the
1525 * intermediate source that didn't change its volume. This theoretical
1526 * possibility is the reason why we have that !(s->flags &
1527 * PA_SOURCE_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
1528 * notice even if we returned here FALSE always if
1529 * reference_volume_changed is FALSE. */
1530 return FALSE;
1531
1532 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1533 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1534 update_reference_volume(o->destination_source, v, channel_map, FALSE);
1535 }
1536
1537 return TRUE;
1538 }
1539
1540 /* Called from main thread */
1541 void pa_source_set_volume(
1542 pa_source *s,
1543 const pa_cvolume *volume,
1544 pa_bool_t send_msg,
1545 pa_bool_t save) {
1546
1547 pa_cvolume new_reference_volume;
1548 pa_source *root_source;
1549
1550 pa_source_assert_ref(s);
1551 pa_assert_ctl_context();
1552 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1553 pa_assert(!volume || pa_cvolume_valid(volume));
1554 pa_assert(volume || pa_source_flat_volume_enabled(s));
1555 pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
1556
1557 /* make sure we don't change the volume in PASSTHROUGH mode ...
1558 * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
1559 if (pa_source_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
1560 pa_log_warn("Cannot change volume, source is monitor of a PASSTHROUGH sink");
1561 return;
1562 }
1563
1564 /* In case of volume sharing, the volume is set for the root source first,
1565 * from which it's then propagated to the sharing sources. */
1566 root_source = pa_source_get_master(s);
1567
1568 if (PA_UNLIKELY(!root_source))
1569 return;
1570
1571 /* As a special exception we accept mono volumes on all sources --
1572 * even on those with more complex channel maps */
1573
1574 if (volume) {
1575 if (pa_cvolume_compatible(volume, &s->sample_spec))
1576 new_reference_volume = *volume;
1577 else {
1578 new_reference_volume = s->reference_volume;
1579 pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
1580 }
1581
1582 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
1583
1584 if (update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save)) {
1585 if (pa_source_flat_volume_enabled(root_source)) {
1586 /* OK, propagate this volume change back to the outputs */
1587 propagate_reference_volume(root_source);
1588
1589 /* And now recalculate the real volume */
1590 compute_real_volume(root_source);
1591 } else
1592 update_real_volume(root_source, &root_source->reference_volume, &root_source->channel_map);
1593 }
1594
1595 } else {
1596 /* If volume is NULL we synchronize the source's real and
1597 * reference volumes with the stream volumes. */
1598
1599 pa_assert(pa_source_flat_volume_enabled(root_source));
1600
1601 /* Ok, let's determine the new real volume */
1602 compute_real_volume(root_source);
1603
1604 /* Let's 'push' the reference volume if necessary */
1605 pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_source->real_volume);
1606 /* If the source and it's root don't have the same number of channels, we need to remap */
1607 if (s != root_source && !pa_channel_map_equal(&s->channel_map, &root_source->channel_map))
1608 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
1609 update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save);
1610
1611 /* Now that the reference volume is updated, we can update the streams'
1612 * reference ratios. */
1613 compute_reference_ratios(root_source);
1614 }
1615
1616 if (root_source->set_volume) {
1617 /* If we have a function set_volume(), then we do not apply a
1618 * soft volume by default. However, set_volume() is free to
1619 * apply one to root_source->soft_volume */
1620
1621 pa_cvolume_reset(&root_source->soft_volume, root_source->sample_spec.channels);
1622 if (!(root_source->flags & PA_SOURCE_DEFERRED_VOLUME))
1623 root_source->set_volume(root_source);
1624
1625 } else
1626 /* If we have no function set_volume(), then the soft volume
1627 * becomes the real volume */
1628 root_source->soft_volume = root_source->real_volume;
1629
1630 /* This tells the source that soft volume and/or real volume changed */
1631 if (send_msg)
1632 pa_assert_se(pa_asyncmsgq_send(root_source->asyncmsgq, PA_MSGOBJECT(root_source), PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
1633 }
1634
1635 /* Called from the io thread if sync volume is used, otherwise from the main thread.
1636 * Only to be called by source implementor */
1637 void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
1638
1639 pa_source_assert_ref(s);
1640 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1641
1642 if (s->flags & PA_SOURCE_DEFERRED_VOLUME)
1643 pa_source_assert_io_context(s);
1644 else
1645 pa_assert_ctl_context();
1646
1647 if (!volume)
1648 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1649 else
1650 s->soft_volume = *volume;
1651
1652 if (PA_SOURCE_IS_LINKED(s->state) && !(s->flags & PA_SOURCE_DEFERRED_VOLUME))
1653 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1654 else
1655 s->thread_info.soft_volume = s->soft_volume;
1656 }
1657
1658 /* Called from the main thread. Only called for the root source in volume sharing
1659 * cases, except for internal recursive calls. */
1660 static void propagate_real_volume(pa_source *s, const pa_cvolume *old_real_volume) {
1661 pa_source_output *o;
1662 uint32_t idx;
1663
1664 pa_source_assert_ref(s);
1665 pa_assert(old_real_volume);
1666 pa_assert_ctl_context();
1667 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1668
1669 /* This is called when the hardware's real volume changes due to
1670 * some external event. We copy the real volume into our
1671 * reference volume and then rebuild the stream volumes based on
1672 * i->real_ratio which should stay fixed. */
1673
1674 if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
1675 if (pa_cvolume_equal(old_real_volume, &s->real_volume))
1676 return;
1677
1678 /* 1. Make the real volume the reference volume */
1679 update_reference_volume(s, &s->real_volume, &s->channel_map, TRUE);
1680 }
1681
1682 if (pa_source_flat_volume_enabled(s)) {
1683
1684 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1685 pa_cvolume old_volume = o->volume;
1686
1687 /* 2. Since the source's reference and real volumes are equal
1688 * now our ratios should be too. */
1689 o->reference_ratio = o->real_ratio;
1690
1691 /* 3. Recalculate the new stream reference volume based on the
1692 * reference ratio and the sink's reference volume.
1693 *
1694 * This basically calculates:
1695 *
1696 * o->volume = s->reference_volume * o->reference_ratio
1697 *
1698 * This is identical to propagate_reference_volume() */
1699 o->volume = s->reference_volume;
1700 pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
1701 pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
1702
1703 /* Notify if something changed */
1704 if (!pa_cvolume_equal(&old_volume, &o->volume)) {
1705
1706 if (o->volume_changed)
1707 o->volume_changed(o);
1708
1709 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
1710 }
1711
1712 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1713 propagate_real_volume(o->destination_source, old_real_volume);
1714 }
1715 }
1716
1717 /* Something got changed in the hardware. It probably makes sense
1718 * to save changed hw settings given that hw volume changes not
1719 * triggered by PA are almost certainly done by the user. */
1720 if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1721 s->save_volume = TRUE;
1722 }
1723
1724 /* Called from io thread */
1725 void pa_source_update_volume_and_mute(pa_source *s) {
1726 pa_assert(s);
1727 pa_source_assert_io_context(s);
1728
1729 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
1730 }
1731
1732 /* Called from main thread */
1733 const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
1734 pa_source_assert_ref(s);
1735 pa_assert_ctl_context();
1736 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1737
1738 if (s->refresh_volume || force_refresh) {
1739 struct pa_cvolume old_real_volume;
1740
1741 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1742
1743 old_real_volume = s->real_volume;
1744
1745 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume)
1746 s->get_volume(s);
1747
1748 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
1749
1750 update_real_volume(s, &s->real_volume, &s->channel_map);
1751 propagate_real_volume(s, &old_real_volume);
1752 }
1753
1754 return &s->reference_volume;
1755 }
1756
1757 /* Called from main thread. In volume sharing cases, only the root source may
1758 * call this. */
1759 void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_real_volume) {
1760 pa_cvolume old_real_volume;
1761
1762 pa_source_assert_ref(s);
1763 pa_assert_ctl_context();
1764 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1765 pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
1766
1767 /* The source implementor may call this if the volume changed to make sure everyone is notified */
1768
1769 old_real_volume = s->real_volume;
1770 update_real_volume(s, new_real_volume, &s->channel_map);
1771 propagate_real_volume(s, &old_real_volume);
1772 }
1773
1774 /* Called from main thread */
1775 void pa_source_set_mute(pa_source *s, pa_bool_t mute, pa_bool_t save) {
1776 pa_bool_t old_muted;
1777
1778 pa_source_assert_ref(s);
1779 pa_assert_ctl_context();
1780 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1781
1782 old_muted = s->muted;
1783 s->muted = mute;
1784 s->save_muted = (old_muted == s->muted && s->save_muted) || save;
1785
1786 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->set_mute)
1787 s->set_mute(s);
1788
1789 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1790
1791 if (old_muted != s->muted)
1792 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1793 }
1794
1795 /* Called from main thread */
1796 pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
1797
1798 pa_source_assert_ref(s);
1799 pa_assert_ctl_context();
1800 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1801
1802 if (s->refresh_muted || force_refresh) {
1803 pa_bool_t old_muted = s->muted;
1804
1805 if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_mute)
1806 s->get_mute(s);
1807
1808 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
1809
1810 if (old_muted != s->muted) {
1811 s->save_muted = TRUE;
1812
1813 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1814
1815 /* Make sure the soft mute status stays in sync */
1816 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1817 }
1818 }
1819
1820 return s->muted;
1821 }
1822
1823 /* Called from main thread */
1824 void pa_source_mute_changed(pa_source *s, pa_bool_t new_muted) {
1825 pa_source_assert_ref(s);
1826 pa_assert_ctl_context();
1827 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1828
1829 /* The source implementor may call this if the mute state changed to make sure everyone is notified */
1830
1831 if (s->muted == new_muted)
1832 return;
1833
1834 s->muted = new_muted;
1835 s->save_muted = TRUE;
1836
1837 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1838 }
1839
1840 /* Called from main thread */
1841 pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p) {
1842 pa_source_assert_ref(s);
1843 pa_assert_ctl_context();
1844
1845 if (p)
1846 pa_proplist_update(s->proplist, mode, p);
1847
1848 if (PA_SOURCE_IS_LINKED(s->state)) {
1849 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
1850 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1851 }
1852
1853 return TRUE;
1854 }
1855
1856 /* Called from main thread */
1857 /* FIXME -- this should be dropped and be merged into pa_source_update_proplist() */
1858 void pa_source_set_description(pa_source *s, const char *description) {
1859 const char *old;
1860 pa_source_assert_ref(s);
1861 pa_assert_ctl_context();
1862
1863 if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
1864 return;
1865
1866 old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1867
1868 if (old && description && pa_streq(old, description))
1869 return;
1870
1871 if (description)
1872 pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
1873 else
1874 pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1875
1876 if (PA_SOURCE_IS_LINKED(s->state)) {
1877 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1878 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
1879 }
1880 }
1881
1882 /* Called from main thread */
1883 unsigned pa_source_linked_by(pa_source *s) {
1884 pa_source_assert_ref(s);
1885 pa_assert_ctl_context();
1886 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1887
1888 return pa_idxset_size(s->outputs);
1889 }
1890
1891 /* Called from main thread */
1892 unsigned pa_source_used_by(pa_source *s) {
1893 unsigned ret;
1894
1895 pa_source_assert_ref(s);
1896 pa_assert_ctl_context();
1897 pa_assert(PA_SOURCE_IS_LINKED(s->state));
1898
1899 ret = pa_idxset_size(s->outputs);
1900 pa_assert(ret >= s->n_corked);
1901
1902 return ret - s->n_corked;
1903 }
1904
1905 /* Called from main thread */
1906 unsigned pa_source_check_suspend(pa_source *s) {
1907 unsigned ret;
1908 pa_source_output *o;
1909 uint32_t idx;
1910
1911 pa_source_assert_ref(s);
1912 pa_assert_ctl_context();
1913
1914 if (!PA_SOURCE_IS_LINKED(s->state))
1915 return 0;
1916
1917 ret = 0;
1918
1919 PA_IDXSET_FOREACH(o, s->outputs, idx) {
1920 pa_source_output_state_t st;
1921
1922 st = pa_source_output_get_state(o);
1923
1924 /* We do not assert here. It is perfectly valid for a source output to
1925 * be in the INIT state (i.e. created, marked done but not yet put)
1926 * and we should not care if it's unlinked as it won't contribute
1927 * towards our busy status.
1928 */
1929 if (!PA_SOURCE_OUTPUT_IS_LINKED(st))
1930 continue;
1931
1932 if (st == PA_SOURCE_OUTPUT_CORKED)
1933 continue;
1934
1935 if (o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND)
1936 continue;
1937
1938 ret ++;
1939 }
1940
1941 return ret;
1942 }
1943
1944 /* Called from the IO thread */
1945 static void sync_output_volumes_within_thread(pa_source *s) {
1946 pa_source_output *o;
1947 void *state = NULL;
1948
1949 pa_source_assert_ref(s);
1950 pa_source_assert_io_context(s);
1951
1952 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
1953 if (pa_cvolume_equal(&o->thread_info.soft_volume, &o->soft_volume))
1954 continue;
1955
1956 o->thread_info.soft_volume = o->soft_volume;
1957 //pa_source_output_request_rewind(o, 0, TRUE, FALSE, FALSE);
1958 }
1959 }
1960
1961 /* Called from the IO thread. Only called for the root source in volume sharing
1962 * cases, except for internal recursive calls. */
1963 static void set_shared_volume_within_thread(pa_source *s) {
1964 pa_source_output *o;
1965 void *state = NULL;
1966
1967 pa_source_assert_ref(s);
1968
1969 PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
1970
1971 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
1972 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
1973 set_shared_volume_within_thread(o->destination_source);
1974 }
1975 }
1976
1977 /* Called from IO thread, except when it is not */
1978 int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1979 pa_source *s = PA_SOURCE(object);
1980 pa_source_assert_ref(s);
1981
1982 switch ((pa_source_message_t) code) {
1983
1984 case PA_SOURCE_MESSAGE_ADD_OUTPUT: {
1985 pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
1986
1987 pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o));
1988
1989 if (o->direct_on_input) {
1990 o->thread_info.direct_on_input = o->direct_on_input;
1991 pa_hashmap_put(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index), o);
1992 }
1993
1994 pa_assert(!o->thread_info.attached);
1995 o->thread_info.attached = TRUE;
1996
1997 if (o->attach)
1998 o->attach(o);
1999
2000 pa_source_output_set_state_within_thread(o, o->state);
2001
2002 if (o->thread_info.requested_source_latency != (pa_usec_t) -1)
2003 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
2004
2005 pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
2006
2007 /* We don't just invalidate the requested latency here,
2008 * because if we are in a move we might need to fix up the
2009 * requested latency. */
2010 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
2011
2012 /* In flat volume mode we need to update the volume as
2013 * well */
2014 return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2015 }
2016
2017 case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: {
2018 pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
2019
2020 pa_source_output_set_state_within_thread(o, o->state);
2021
2022 if (o->detach)
2023 o->detach(o);
2024
2025 pa_assert(o->thread_info.attached);
2026 o->thread_info.attached = FALSE;
2027
2028 if (o->thread_info.direct_on_input) {
2029 pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index));
2030 o->thread_info.direct_on_input = NULL;
2031 }
2032
2033 if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
2034 pa_source_output_unref(o);
2035
2036 pa_source_invalidate_requested_latency(s, TRUE);
2037
2038 /* In flat volume mode we need to update the volume as
2039 * well */
2040 return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2041 }
2042
2043 case PA_SOURCE_MESSAGE_SET_SHARED_VOLUME: {
2044 pa_source *root_source = pa_source_get_master(s);
2045
2046 if (PA_LIKELY(root_source))
2047 set_shared_volume_within_thread(root_source);
2048
2049 return 0;
2050 }
2051
2052 case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED:
2053
2054 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
2055 s->set_volume(s);
2056 pa_source_volume_change_push(s);
2057 }
2058 /* Fall through ... */
2059
2060 case PA_SOURCE_MESSAGE_SET_VOLUME:
2061
2062 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2063 s->thread_info.soft_volume = s->soft_volume;
2064 }
2065
2066 /* Fall through ... */
2067
2068 case PA_SOURCE_MESSAGE_SYNC_VOLUMES:
2069 sync_output_volumes_within_thread(s);
2070 return 0;
2071
2072 case PA_SOURCE_MESSAGE_GET_VOLUME:
2073
2074 if ((s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume) {
2075 s->get_volume(s);
2076 pa_source_volume_change_flush(s);
2077 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2078 }
2079
2080 /* In case source implementor reset SW volume. */
2081 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2082 s->thread_info.soft_volume = s->soft_volume;
2083 }
2084
2085 return 0;
2086
2087 case PA_SOURCE_MESSAGE_SET_MUTE:
2088
2089 if (s->thread_info.soft_muted != s->muted) {
2090 s->thread_info.soft_muted = s->muted;
2091 }
2092
2093 if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->set_mute)
2094 s->set_mute(s);
2095
2096 return 0;
2097
2098 case PA_SOURCE_MESSAGE_GET_MUTE:
2099
2100 if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->get_mute)
2101 s->get_mute(s);
2102
2103 return 0;
2104
2105 case PA_SOURCE_MESSAGE_SET_STATE: {
2106
2107 pa_bool_t suspend_change =
2108 (s->thread_info.state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2109 (PA_SOURCE_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SOURCE_SUSPENDED);
2110
2111 s->thread_info.state = PA_PTR_TO_UINT(userdata);
2112
2113 if (suspend_change) {
2114 pa_source_output *o;
2115 void *state = NULL;
2116
2117 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
2118 if (o->suspend_within_thread)
2119 o->suspend_within_thread(o, s->thread_info.state == PA_SOURCE_SUSPENDED);
2120 }
2121
2122 return 0;
2123 }
2124
2125 case PA_SOURCE_MESSAGE_DETACH:
2126
2127 /* Detach all streams */
2128 pa_source_detach_within_thread(s);
2129 return 0;
2130
2131 case PA_SOURCE_MESSAGE_ATTACH:
2132
2133 /* Reattach all streams */
2134 pa_source_attach_within_thread(s);
2135 return 0;
2136
2137 case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: {
2138
2139 pa_usec_t *usec = userdata;
2140 *usec = pa_source_get_requested_latency_within_thread(s);
2141
2142 /* Yes, that's right, the IO thread will see -1 when no
2143 * explicit requested latency is configured, the main
2144 * thread will see max_latency */
2145 if (*usec == (pa_usec_t) -1)
2146 *usec = s->thread_info.max_latency;
2147
2148 return 0;
2149 }
2150
2151 case PA_SOURCE_MESSAGE_SET_LATENCY_RANGE: {
2152 pa_usec_t *r = userdata;
2153
2154 pa_source_set_latency_range_within_thread(s, r[0], r[1]);
2155
2156 return 0;
2157 }
2158
2159 case PA_SOURCE_MESSAGE_GET_LATENCY_RANGE: {
2160 pa_usec_t *r = userdata;
2161
2162 r[0] = s->thread_info.min_latency;
2163 r[1] = s->thread_info.max_latency;
2164
2165 return 0;
2166 }
2167
2168 case PA_SOURCE_MESSAGE_GET_FIXED_LATENCY:
2169
2170 *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2171 return 0;
2172
2173 case PA_SOURCE_MESSAGE_SET_FIXED_LATENCY:
2174
2175 pa_source_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2176 return 0;
2177
2178 case PA_SOURCE_MESSAGE_GET_MAX_REWIND:
2179
2180 *((size_t*) userdata) = s->thread_info.max_rewind;
2181 return 0;
2182
2183 case PA_SOURCE_MESSAGE_SET_MAX_REWIND:
2184
2185 pa_source_set_max_rewind_within_thread(s, (size_t) offset);
2186 return 0;
2187
2188 case PA_SOURCE_MESSAGE_GET_LATENCY:
2189
2190 if (s->monitor_of) {
2191 *((pa_usec_t*) userdata) = 0;
2192 return 0;
2193 }
2194
2195 /* Implementors need to overwrite this implementation! */
2196 return -1;
2197
2198 case PA_SOURCE_MESSAGE_SET_PORT:
2199
2200 pa_assert(userdata);
2201 if (s->set_port) {
2202 struct source_message_set_port *msg_data = userdata;
2203 msg_data->ret = s->set_port(s, msg_data->port);
2204 }
2205 return 0;
2206
2207 case PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2208 /* This message is sent from IO-thread and handled in main thread. */
2209 pa_assert_ctl_context();
2210
2211 /* Make sure we're not messing with main thread when no longer linked */
2212 if (!PA_SOURCE_IS_LINKED(s->state))
2213 return 0;
2214
2215 pa_source_get_volume(s, TRUE);
2216 pa_source_get_mute(s, TRUE);
2217 return 0;
2218
2219 case PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET:
2220 s->thread_info.latency_offset = offset;
2221 return 0;
2222
2223 case PA_SOURCE_MESSAGE_MAX:
2224 ;
2225 }
2226
2227 return -1;
2228 }
2229
2230 /* Called from main thread */
2231 int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
2232 pa_source *source;
2233 uint32_t idx;
2234 int ret = 0;
2235
2236 pa_core_assert_ref(c);
2237 pa_assert_ctl_context();
2238 pa_assert(cause != 0);
2239
2240 for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) {
2241 int r;
2242
2243 if (source->monitor_of)
2244 continue;
2245
2246 if ((r = pa_source_suspend(source, suspend, cause)) < 0)
2247 ret = r;
2248 }
2249
2250 return ret;
2251 }
2252
2253 /* Called from main thread */
2254 void pa_source_detach(pa_source *s) {
2255 pa_source_assert_ref(s);
2256 pa_assert_ctl_context();
2257 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2258
2259 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL) == 0);
2260 }
2261
2262 /* Called from main thread */
2263 void pa_source_attach(pa_source *s) {
2264 pa_source_assert_ref(s);
2265 pa_assert_ctl_context();
2266 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2267
2268 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
2269 }
2270
2271 /* Called from IO thread */
2272 void pa_source_detach_within_thread(pa_source *s) {
2273 pa_source_output *o;
2274 void *state = NULL;
2275
2276 pa_source_assert_ref(s);
2277 pa_source_assert_io_context(s);
2278 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
2279
2280 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2281 if (o->detach)
2282 o->detach(o);
2283 }
2284
2285 /* Called from IO thread */
2286 void pa_source_attach_within_thread(pa_source *s) {
2287 pa_source_output *o;
2288 void *state = NULL;
2289
2290 pa_source_assert_ref(s);
2291 pa_source_assert_io_context(s);
2292 pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
2293
2294 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2295 if (o->attach)
2296 o->attach(o);
2297 }
2298
2299 /* Called from IO thread */
2300 pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
2301 pa_usec_t result = (pa_usec_t) -1;
2302 pa_source_output *o;
2303 void *state = NULL;
2304
2305 pa_source_assert_ref(s);
2306 pa_source_assert_io_context(s);
2307
2308 if (!(s->flags & PA_SOURCE_DYNAMIC_LATENCY))
2309 return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2310
2311 if (s->thread_info.requested_latency_valid)
2312 return s->thread_info.requested_latency;
2313
2314 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2315 if (o->thread_info.requested_source_latency != (pa_usec_t) -1 &&
2316 (result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency))
2317 result = o->thread_info.requested_source_latency;
2318
2319 if (result != (pa_usec_t) -1)
2320 result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
2321
2322 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2323 /* Only cache this if we are fully set up */
2324 s->thread_info.requested_latency = result;
2325 s->thread_info.requested_latency_valid = TRUE;
2326 }
2327
2328 return result;
2329 }
2330
2331 /* Called from main thread */
2332 pa_usec_t pa_source_get_requested_latency(pa_source *s) {
2333 pa_usec_t usec = 0;
2334
2335 pa_source_assert_ref(s);
2336 pa_assert_ctl_context();
2337 pa_assert(PA_SOURCE_IS_LINKED(s->state));
2338
2339 if (s->state == PA_SOURCE_SUSPENDED)
2340 return 0;
2341
2342 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
2343
2344 return usec;
2345 }
2346
2347 /* Called from IO thread */
2348 void pa_source_set_max_rewind_within_thread(pa_source *s, size_t max_rewind) {
2349 pa_source_output *o;
2350 void *state = NULL;
2351
2352 pa_source_assert_ref(s);
2353 pa_source_assert_io_context(s);
2354
2355 if (max_rewind == s->thread_info.max_rewind)
2356 return;
2357
2358 s->thread_info.max_rewind = max_rewind;
2359
2360 if (PA_SOURCE_IS_LINKED(s->thread_info.state))
2361 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2362 pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
2363 }
2364
2365 /* Called from main thread */
2366 void pa_source_set_max_rewind(pa_source *s, size_t max_rewind) {
2367 pa_source_assert_ref(s);
2368 pa_assert_ctl_context();
2369
2370 if (PA_SOURCE_IS_LINKED(s->state))
2371 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
2372 else
2373 pa_source_set_max_rewind_within_thread(s, max_rewind);
2374 }
2375
2376 /* Called from IO thread */
2377 void pa_source_invalidate_requested_latency(pa_source *s, pa_bool_t dynamic) {
2378 pa_source_output *o;
2379 void *state = NULL;
2380
2381 pa_source_assert_ref(s);
2382 pa_source_assert_io_context(s);
2383
2384 if ((s->flags & PA_SOURCE_DYNAMIC_LATENCY))
2385 s->thread_info.requested_latency_valid = FALSE;
2386 else if (dynamic)
2387 return;
2388
2389 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2390
2391 if (s->update_requested_latency)
2392 s->update_requested_latency(s);
2393
2394 while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
2395 if (o->update_source_requested_latency)
2396 o->update_source_requested_latency(o);
2397 }
2398
2399 if (s->monitor_of)
2400 pa_sink_invalidate_requested_latency(s->monitor_of, dynamic);
2401 }
2402
2403 /* Called from main thread */
2404 void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2405 pa_source_assert_ref(s);
2406 pa_assert_ctl_context();
2407
2408 /* min_latency == 0: no limit
2409 * min_latency anything else: specified limit
2410 *
2411 * Similar for max_latency */
2412
2413 if (min_latency < ABSOLUTE_MIN_LATENCY)
2414 min_latency = ABSOLUTE_MIN_LATENCY;
2415
2416 if (max_latency <= 0 ||
2417 max_latency > ABSOLUTE_MAX_LATENCY)
2418 max_latency = ABSOLUTE_MAX_LATENCY;
2419
2420 pa_assert(min_latency <= max_latency);
2421
2422 /* Hmm, let's see if someone forgot to set PA_SOURCE_DYNAMIC_LATENCY here... */
2423 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2424 max_latency == ABSOLUTE_MAX_LATENCY) ||
2425 (s->flags & PA_SOURCE_DYNAMIC_LATENCY));
2426
2427 if (PA_SOURCE_IS_LINKED(s->state)) {
2428 pa_usec_t r[2];
2429
2430 r[0] = min_latency;
2431 r[1] = max_latency;
2432
2433 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
2434 } else
2435 pa_source_set_latency_range_within_thread(s, min_latency, max_latency);
2436 }
2437
2438 /* Called from main thread */
2439 void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
2440 pa_source_assert_ref(s);
2441 pa_assert_ctl_context();
2442 pa_assert(min_latency);
2443 pa_assert(max_latency);
2444
2445 if (PA_SOURCE_IS_LINKED(s->state)) {
2446 pa_usec_t r[2] = { 0, 0 };
2447
2448 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
2449
2450 *min_latency = r[0];
2451 *max_latency = r[1];
2452 } else {
2453 *min_latency = s->thread_info.min_latency;
2454 *max_latency = s->thread_info.max_latency;
2455 }
2456 }
2457
2458 /* Called from IO thread, and from main thread before pa_source_put() is called */
2459 void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2460 pa_source_assert_ref(s);
2461 pa_source_assert_io_context(s);
2462
2463 pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
2464 pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
2465 pa_assert(min_latency <= max_latency);
2466
2467 /* Hmm, let's see if someone forgot to set PA_SOURCE_DYNAMIC_LATENCY here... */
2468 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2469 max_latency == ABSOLUTE_MAX_LATENCY) ||
2470 (s->flags & PA_SOURCE_DYNAMIC_LATENCY) ||
2471 s->monitor_of);
2472
2473 if (s->thread_info.min_latency == min_latency &&
2474 s->thread_info.max_latency == max_latency)
2475 return;
2476
2477 s->thread_info.min_latency = min_latency;
2478 s->thread_info.max_latency = max_latency;
2479
2480 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2481 pa_source_output *o;
2482 void *state = NULL;
2483
2484 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2485 if (o->update_source_latency_range)
2486 o->update_source_latency_range(o);
2487 }
2488
2489 pa_source_invalidate_requested_latency(s, FALSE);
2490 }
2491
2492 /* Called from main thread, before the source is put */
2493 void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency) {
2494 pa_source_assert_ref(s);
2495 pa_assert_ctl_context();
2496
2497 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) {
2498 pa_assert(latency == 0);
2499 return;
2500 }
2501
2502 if (latency < ABSOLUTE_MIN_LATENCY)
2503 latency = ABSOLUTE_MIN_LATENCY;
2504
2505 if (latency > ABSOLUTE_MAX_LATENCY)
2506 latency = ABSOLUTE_MAX_LATENCY;
2507
2508 if (PA_SOURCE_IS_LINKED(s->state))
2509 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
2510 else
2511 s->thread_info.fixed_latency = latency;
2512 }
2513
2514 /* Called from main thread */
2515 pa_usec_t pa_source_get_fixed_latency(pa_source *s) {
2516 pa_usec_t latency;
2517
2518 pa_source_assert_ref(s);
2519 pa_assert_ctl_context();
2520
2521 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY)
2522 return 0;
2523
2524 if (PA_SOURCE_IS_LINKED(s->state))
2525 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
2526 else
2527 latency = s->thread_info.fixed_latency;
2528
2529 return latency;
2530 }
2531
2532 /* Called from IO thread */
2533 void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency) {
2534 pa_source_assert_ref(s);
2535 pa_source_assert_io_context(s);
2536
2537 if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) {
2538 pa_assert(latency == 0);
2539 s->thread_info.fixed_latency = 0;
2540
2541 return;
2542 }
2543
2544 pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
2545 pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
2546
2547 if (s->thread_info.fixed_latency == latency)
2548 return;
2549
2550 s->thread_info.fixed_latency = latency;
2551
2552 if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
2553 pa_source_output *o;
2554 void *state = NULL;
2555
2556 PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state)
2557 if (o->update_source_fixed_latency)
2558 o->update_source_fixed_latency(o);
2559 }
2560
2561 pa_source_invalidate_requested_latency(s, FALSE);
2562 }
2563
2564 /* Called from main thread */
2565 void pa_source_set_latency_offset(pa_source *s, int64_t offset) {
2566 pa_source_assert_ref(s);
2567
2568 s->latency_offset = offset;
2569
2570 if (PA_SOURCE_IS_LINKED(s->state))
2571 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
2572 else
2573 s->thread_info.latency_offset = offset;
2574 }
2575
2576 /* Called from main thread */
2577 size_t pa_source_get_max_rewind(pa_source *s) {
2578 size_t r;
2579 pa_assert_ctl_context();
2580 pa_source_assert_ref(s);
2581
2582 if (!PA_SOURCE_IS_LINKED(s->state))
2583 return s->thread_info.max_rewind;
2584
2585 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
2586
2587 return r;
2588 }
2589
2590 /* Called from main context */
2591 int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
2592 pa_device_port *port;
2593 int ret;
2594
2595 pa_source_assert_ref(s);
2596 pa_assert_ctl_context();
2597
2598 if (!s->set_port) {
2599 pa_log_debug("set_port() operation not implemented for source %u \"%s\"", s->index, s->name);
2600 return -PA_ERR_NOTIMPLEMENTED;
2601 }
2602
2603 if (!name)
2604 return -PA_ERR_NOENTITY;
2605
2606 if (!(port = pa_hashmap_get(s->ports, name)))
2607 return -PA_ERR_NOENTITY;
2608
2609 if (s->active_port == port) {
2610 s->save_port = s->save_port || save;
2611 return 0;
2612 }
2613
2614 if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
2615 struct source_message_set_port msg = { .port = port, .ret = 0 };
2616 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
2617 ret = msg.ret;
2618 }
2619 else
2620 ret = s->set_port(s, port);
2621
2622 if (ret < 0)
2623 return -PA_ERR_NOENTITY;
2624
2625 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2626
2627 pa_log_info("Changed port of source %u \"%s\" to %s", s->index, s->name, port->name);
2628
2629 s->active_port = port;
2630 s->save_port = save;
2631
2632 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
2633
2634 return 0;
2635 }
2636
2637 PA_STATIC_FLIST_DECLARE(pa_source_volume_change, 0, pa_xfree);
2638
2639 /* Called from the IO thread. */
2640 static pa_source_volume_change *pa_source_volume_change_new(pa_source *s) {
2641 pa_source_volume_change *c;
2642 if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_source_volume_change))))
2643 c = pa_xnew(pa_source_volume_change, 1);
2644
2645 PA_LLIST_INIT(pa_source_volume_change, c);
2646 c->at = 0;
2647 pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
2648 return c;
2649 }
2650
2651 /* Called from the IO thread. */
2652 static void pa_source_volume_change_free(pa_source_volume_change *c) {
2653 pa_assert(c);
2654 if (pa_flist_push(PA_STATIC_FLIST_GET(pa_source_volume_change), c) < 0)
2655 pa_xfree(c);
2656 }
2657
2658 /* Called from the IO thread. */
2659 void pa_source_volume_change_push(pa_source *s) {
2660 pa_source_volume_change *c = NULL;
2661 pa_source_volume_change *nc = NULL;
2662 uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
2663
2664 const char *direction = NULL;
2665
2666 pa_assert(s);
2667 nc = pa_source_volume_change_new(s);
2668
2669 /* NOTE: There is already more different volumes in pa_source that I can remember.
2670 * Adding one more volume for HW would get us rid of this, but I am trying
2671 * to survive with the ones we already have. */
2672 pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
2673
2674 if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
2675 pa_log_debug("Volume not changing");
2676 pa_source_volume_change_free(nc);
2677 return;
2678 }
2679
2680 nc->at = pa_source_get_latency_within_thread(s);
2681 nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
2682
2683 if (s->thread_info.volume_changes_tail) {
2684 for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
2685 /* If volume is going up let's do it a bit late. If it is going
2686 * down let's do it a bit early. */
2687 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
2688 if (nc->at + safety_margin > c->at) {
2689 nc->at += safety_margin;
2690 direction = "up";
2691 break;
2692 }
2693 }
2694 else if (nc->at - safety_margin > c->at) {
2695 nc->at -= safety_margin;
2696 direction = "down";
2697 break;
2698 }
2699 }
2700 }
2701
2702 if (c == NULL) {
2703 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
2704 nc->at += safety_margin;
2705 direction = "up";
2706 } else {
2707 nc->at -= safety_margin;
2708 direction = "down";
2709 }
2710 PA_LLIST_PREPEND(pa_source_volume_change, s->thread_info.volume_changes, nc);
2711 }
2712 else {
2713 PA_LLIST_INSERT_AFTER(pa_source_volume_change, s->thread_info.volume_changes, c, nc);
2714 }
2715
2716 pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
2717
2718 /* We can ignore volume events that came earlier but should happen later than this. */
2719 PA_LLIST_FOREACH(c, nc->next) {
2720 pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
2721 pa_source_volume_change_free(c);
2722 }
2723 nc->next = NULL;
2724 s->thread_info.volume_changes_tail = nc;
2725 }
2726
2727 /* Called from the IO thread. */
2728 static void pa_source_volume_change_flush(pa_source *s) {
2729 pa_source_volume_change *c = s->thread_info.volume_changes;
2730 pa_assert(s);
2731 s->thread_info.volume_changes = NULL;
2732 s->thread_info.volume_changes_tail = NULL;
2733 while (c) {
2734 pa_source_volume_change *next = c->next;
2735 pa_source_volume_change_free(c);
2736 c = next;
2737 }
2738 }
2739
2740 /* Called from the IO thread. */
2741 pa_bool_t pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next) {
2742 pa_usec_t now;
2743 pa_bool_t ret = FALSE;
2744
2745 pa_assert(s);
2746
2747 if (!s->thread_info.volume_changes || !PA_SOURCE_IS_LINKED(s->state)) {
2748 if (usec_to_next)
2749 *usec_to_next = 0;
2750 return ret;
2751 }
2752
2753 pa_assert(s->write_volume);
2754
2755 now = pa_rtclock_now();
2756
2757 while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
2758 pa_source_volume_change *c = s->thread_info.volume_changes;
2759 PA_LLIST_REMOVE(pa_source_volume_change, s->thread_info.volume_changes, c);
2760 pa_log_debug("Volume change to %d at %llu was written %llu usec late",
2761 pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
2762 ret = TRUE;
2763 s->thread_info.current_hw_volume = c->hw_volume;
2764 pa_source_volume_change_free(c);
2765 }
2766
2767 if (ret)
2768 s->write_volume(s);
2769
2770 if (s->thread_info.volume_changes) {
2771 if (usec_to_next)
2772 *usec_to_next = s->thread_info.volume_changes->at - now;
2773 if (pa_log_ratelimit(PA_LOG_DEBUG))
2774 pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
2775 }
2776 else {
2777 if (usec_to_next)
2778 *usec_to_next = 0;
2779 s->thread_info.volume_changes_tail = NULL;
2780 }
2781 return ret;
2782 }
2783
2784
2785 /* Called from the main thread */
2786 /* Gets the list of formats supported by the source. The members and idxset must
2787 * be freed by the caller. */
2788 pa_idxset* pa_source_get_formats(pa_source *s) {
2789 pa_idxset *ret;
2790
2791 pa_assert(s);
2792
2793 if (s->get_formats) {
2794 /* Source supports format query, all is good */
2795 ret = s->get_formats(s);
2796 } else {
2797 /* Source doesn't support format query, so assume it does PCM */
2798 pa_format_info *f = pa_format_info_new();
2799 f->encoding = PA_ENCODING_PCM;
2800
2801 ret = pa_idxset_new(NULL, NULL);
2802 pa_idxset_put(ret, f, NULL);
2803 }
2804
2805 return ret;
2806 }
2807
2808 /* Called from the main thread */
2809 /* Checks if the source can accept this format */
2810 pa_bool_t pa_source_check_format(pa_source *s, pa_format_info *f)
2811 {
2812 pa_idxset *formats = NULL;
2813 pa_bool_t ret = FALSE;
2814
2815 pa_assert(s);
2816 pa_assert(f);
2817
2818 formats = pa_source_get_formats(s);
2819
2820 if (formats) {
2821 pa_format_info *finfo_device;
2822 uint32_t i;
2823
2824 PA_IDXSET_FOREACH(finfo_device, formats, i) {
2825 if (pa_format_info_is_compatible(finfo_device, f)) {
2826 ret = TRUE;
2827 break;
2828 }
2829 }
2830
2831 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
2832 }
2833
2834 return ret;
2835 }
2836
2837 /* Called from the main thread */
2838 /* Calculates the intersection between formats supported by the source and
2839 * in_formats, and returns these, in the order of the source's formats. */
2840 pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats) {
2841 pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *source_formats = NULL;
2842 pa_format_info *f_source, *f_in;
2843 uint32_t i, j;
2844
2845 pa_assert(s);
2846
2847 if (!in_formats || pa_idxset_isempty(in_formats))
2848 goto done;
2849
2850 source_formats = pa_source_get_formats(s);
2851
2852 PA_IDXSET_FOREACH(f_source, source_formats, i) {
2853 PA_IDXSET_FOREACH(f_in, in_formats, j) {
2854 if (pa_format_info_is_compatible(f_source, f_in))
2855 pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
2856 }
2857 }
2858
2859 done:
2860 if (source_formats)
2861 pa_idxset_free(source_formats, (pa_free_cb_t) pa_format_info_free);
2862
2863 return out_formats;
2864 }