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