add functions that modules can call whenever they now the volume changed
[platform/upstream/pulseaudio.git] / src / pulsecore / source.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7   PulseAudio is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as published
9   by the Free Software Foundation; either version 2.1 of the License,
10   or (at your option) any later version.
11
12   PulseAudio is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with PulseAudio; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/timeval.h>
34 #include <pulse/util.h>
35
36 #include <pulsecore/source-output.h>
37 #include <pulsecore/namereg.h>
38 #include <pulsecore/core-subscribe.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/sample-util.h>
41
42 #include "source.h"
43
44 #define DEFAULT_MIN_LATENCY (4*PA_USEC_PER_MSEC)
45
46 static PA_DEFINE_CHECK_TYPE(pa_source, pa_msgobject);
47
48 static void source_free(pa_object *o);
49
50 pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
51     pa_assert(data);
52
53     memset(data, 0, sizeof(*data));
54     data->proplist = pa_proplist_new();
55
56     return data;
57 }
58
59 void pa_source_new_data_set_name(pa_source_new_data *data, const char *name) {
60     pa_assert(data);
61
62     pa_xfree(data->name);
63     data->name = pa_xstrdup(name);
64 }
65
66 void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec) {
67     pa_assert(data);
68
69     if ((data->sample_spec_is_set = !!spec))
70         data->sample_spec = *spec;
71 }
72
73 void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map) {
74     pa_assert(data);
75
76     if ((data->channel_map_is_set = !!map))
77         data->channel_map = *map;
78 }
79
80 void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {
81     pa_assert(data);
82
83     if ((data->volume_is_set = !!volume))
84         data->volume = *volume;
85 }
86
87 void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute) {
88     pa_assert(data);
89
90     data->muted_is_set = TRUE;
91     data->muted = !!mute;
92 }
93
94 void pa_source_new_data_done(pa_source_new_data *data) {
95     pa_assert(data);
96
97     pa_xfree(data->name);
98     pa_proplist_free(data->proplist);
99 }
100
101 /* Called from main context */
102 static void reset_callbacks(pa_source *s) {
103     pa_assert(s);
104
105     s->set_state = NULL;
106     s->get_volume = NULL;
107     s->set_volume = NULL;
108     s->get_mute = NULL;
109     s->set_mute = NULL;
110     s->update_requested_latency = NULL;
111 }
112
113 /* Called from main context */
114 pa_source* pa_source_new(
115         pa_core *core,
116         pa_source_new_data *data,
117         pa_source_flags_t flags) {
118
119     pa_source *s;
120     const char *name;
121     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
122     char *pt;
123
124     pa_assert(core);
125     pa_assert(data);
126     pa_assert(data->name);
127
128     s = pa_msgobject_new(pa_source);
129
130     if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SOURCE, s, data->namereg_fail))) {
131         pa_xfree(s);
132         return NULL;
133     }
134
135     pa_source_new_data_set_name(data, name);
136
137     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW], data) < 0) {
138         pa_xfree(s);
139         pa_namereg_unregister(core, name);
140         return NULL;
141     }
142
143     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
144     pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
145
146     pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
147
148     if (!data->channel_map_is_set)
149         pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
150
151     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
152     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
153
154     if (!data->volume_is_set)
155         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
156
157     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
158     pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
159
160     if (!data->muted_is_set)
161         data->muted = FALSE;
162
163     if (data->card)
164         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
165
166     pa_device_init_description(data->proplist);
167     pa_device_init_icon(data->proplist, FALSE);
168
169     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
170         pa_xfree(s);
171         pa_namereg_unregister(core, name);
172         return NULL;
173     }
174
175     s->parent.parent.free = source_free;
176     s->parent.process_msg = pa_source_process_msg;
177
178     s->core = core;
179     s->state = PA_SOURCE_INIT;
180     s->flags = flags;
181     s->name = pa_xstrdup(name);
182     s->proplist = pa_proplist_copy(data->proplist);
183     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
184     s->module = data->module;
185     s->card = data->card;
186
187     s->sample_spec = data->sample_spec;
188     s->channel_map = data->channel_map;
189
190     s->outputs = pa_idxset_new(NULL, NULL);
191     s->n_corked = 0;
192     s->monitor_of = NULL;
193
194     s->virtual_volume = data->volume;
195     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
196     s->base_volume = PA_VOLUME_NORM;
197     s->n_volume_steps = PA_VOLUME_NORM+1;
198     s->muted = data->muted;
199     s->refresh_volume = s->refresh_muted = FALSE;
200
201     reset_callbacks(s);
202     s->userdata = NULL;
203
204     s->asyncmsgq = NULL;
205     s->rtpoll = NULL;
206
207     pa_silence_memchunk_get(
208             &core->silence_cache,
209             core->mempool,
210             &s->silence,
211             &s->sample_spec,
212             0);
213
214     s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
215     s->thread_info.soft_volume = s->soft_volume;
216     s->thread_info.soft_muted = s->muted;
217     s->thread_info.state = s->state;
218     s->thread_info.max_rewind = 0;
219     s->thread_info.requested_latency_valid = FALSE;
220     s->thread_info.requested_latency = 0;
221     s->thread_info.min_latency = DEFAULT_MIN_LATENCY;
222     s->thread_info.max_latency = 0;
223
224     pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
225
226     if (s->card)
227         pa_assert_se(pa_idxset_put(s->card->sources, s, NULL) >= 0);
228
229     pt = pa_proplist_to_string_sep(s->proplist, "\n    ");
230     pa_log_info("Created source %u \"%s\" with sample spec %s and channel map %s\n    %s",
231                 s->index,
232                 s->name,
233                 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
234                 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
235                 pt);
236     pa_xfree(pt);
237
238     return s;
239 }
240
241 /* Called from main context */
242 static int source_set_state(pa_source *s, pa_source_state_t state) {
243     int ret;
244     pa_bool_t suspend_change;
245     pa_source_state_t original_state;
246
247     pa_assert(s);
248
249     if (s->state == state)
250         return 0;
251
252     original_state = s->state;
253
254     suspend_change =
255         (original_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) ||
256         (PA_SOURCE_IS_OPENED(original_state) && state == PA_SOURCE_SUSPENDED);
257
258     if (s->set_state)
259         if ((ret = s->set_state(s, state)) < 0)
260             return ret;
261
262     if (s->asyncmsgq)
263         if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
264
265             if (s->set_state)
266                 s->set_state(s, original_state);
267
268             return ret;
269         }
270
271     s->state = state;
272
273     if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */
274         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
275         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
276     }
277
278     if (suspend_change) {
279         pa_source_output *o;
280         uint32_t idx;
281
282         /* We're suspending or resuming, tell everyone about it */
283
284         for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx)))
285             if (s->state == PA_SOURCE_SUSPENDED &&
286                 (o->flags & PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND))
287                 pa_source_output_kill(o);
288             else if (o->suspend)
289                 o->suspend(o, state == PA_SOURCE_SUSPENDED);
290     }
291
292
293     return 0;
294 }
295
296 /* Called from main context */
297 void pa_source_put(pa_source *s) {
298     pa_source_assert_ref(s);
299
300     pa_assert(s->state == PA_SOURCE_INIT);
301
302     /* The following fields must be initialized properly when calling _put() */
303     pa_assert(s->asyncmsgq);
304     pa_assert(s->rtpoll);
305     pa_assert(!s->thread_info.min_latency || !s->thread_info.max_latency ||
306               s->thread_info.min_latency <= s->thread_info.max_latency);
307
308     if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL)) {
309         s->flags |= PA_SOURCE_DECIBEL_VOLUME;
310
311         s->thread_info.soft_volume = s->soft_volume;
312         s->thread_info.soft_muted = s->muted;
313     }
314
315     if (s->flags & PA_SOURCE_DECIBEL_VOLUME)
316         s->n_volume_steps = PA_VOLUME_NORM+1;
317
318     pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
319
320     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
321     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
322 }
323
324 /* Called from main context */
325 void pa_source_unlink(pa_source *s) {
326     pa_bool_t linked;
327     pa_source_output *o, *j = NULL;
328
329     pa_assert(s);
330
331     /* See pa_sink_unlink() for a couple of comments how this function
332      * works. */
333
334     linked = PA_SOURCE_IS_LINKED(s->state);
335
336     if (linked)
337         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s);
338
339     if (s->state != PA_SOURCE_UNLINKED)
340         pa_namereg_unregister(s->core, s->name);
341     pa_idxset_remove_by_data(s->core->sources, s, NULL);
342
343     if (s->card)
344         pa_idxset_remove_by_data(s->card->sources, s, NULL);
345
346     while ((o = pa_idxset_first(s->outputs, NULL))) {
347         pa_assert(o != j);
348         pa_source_output_kill(o);
349         j = o;
350     }
351
352     if (linked)
353         source_set_state(s, PA_SOURCE_UNLINKED);
354     else
355         s->state = PA_SOURCE_UNLINKED;
356
357     reset_callbacks(s);
358
359     if (linked) {
360         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
361         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s);
362     }
363 }
364
365 /* Called from main context */
366 static void source_free(pa_object *o) {
367     pa_source_output *so;
368     pa_source *s = PA_SOURCE(o);
369
370     pa_assert(s);
371     pa_assert(pa_source_refcnt(s) == 0);
372
373     if (PA_SOURCE_IS_LINKED(s->state))
374         pa_source_unlink(s);
375
376     pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
377
378     pa_idxset_free(s->outputs, NULL, NULL);
379
380     while ((so = pa_hashmap_steal_first(s->thread_info.outputs)))
381         pa_source_output_unref(so);
382
383     pa_hashmap_free(s->thread_info.outputs, NULL, NULL);
384
385     if (s->silence.memblock)
386         pa_memblock_unref(s->silence.memblock);
387
388     pa_xfree(s->name);
389     pa_xfree(s->driver);
390
391     if (s->proplist)
392         pa_proplist_free(s->proplist);
393
394     pa_xfree(s);
395 }
396
397 /* Called from main context */
398 void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
399     pa_source_assert_ref(s);
400
401     s->asyncmsgq = q;
402 }
403
404 /* Called from main context */
405 void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) {
406     pa_source_assert_ref(s);
407
408     s->rtpoll = p;
409 }
410
411 /* Called from main context */
412 int pa_source_update_status(pa_source*s) {
413     pa_source_assert_ref(s);
414     pa_assert(PA_SOURCE_IS_LINKED(s->state));
415
416     if (s->state == PA_SOURCE_SUSPENDED)
417         return 0;
418
419     return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
420 }
421
422 /* Called from main context */
423 int pa_source_suspend(pa_source *s, pa_bool_t suspend) {
424     pa_source_assert_ref(s);
425     pa_assert(PA_SOURCE_IS_LINKED(s->state));
426
427     if (s->monitor_of)
428         return -PA_ERR_NOTSUPPORTED;
429
430     if (suspend)
431         return source_set_state(s, PA_SOURCE_SUSPENDED);
432     else
433         return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
434 }
435
436 /* Called from main context */
437 int pa_source_sync_suspend(pa_source *s) {
438     pa_sink_state_t state;
439
440     pa_source_assert_ref(s);
441     pa_assert(PA_SOURCE_IS_LINKED(s->state));
442     pa_assert(s->monitor_of);
443
444     state = pa_sink_get_state(s->monitor_of);
445
446     if (state == PA_SINK_SUSPENDED)
447         return source_set_state(s, PA_SOURCE_SUSPENDED);
448
449     pa_assert(PA_SINK_IS_OPENED(state));
450
451     return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
452 }
453
454 /* Called from main context */
455 pa_queue *pa_source_move_all_start(pa_source *s) {
456     pa_queue *q;
457     pa_source_output *o, *n;
458     uint32_t idx;
459
460     pa_source_assert_ref(s);
461     pa_assert(PA_SOURCE_IS_LINKED(s->state));
462
463     q = pa_queue_new();
464
465     for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = n) {
466         n = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx));
467
468         if (pa_source_output_start_move(o) >= 0)
469             pa_queue_push(q, pa_source_output_ref(o));
470     }
471
472     return q;
473 }
474
475 /* Called from main context */
476 void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
477     pa_source_output *o;
478
479     pa_source_assert_ref(s);
480     pa_assert(PA_SOURCE_IS_LINKED(s->state));
481     pa_assert(q);
482
483     while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
484         if (pa_source_output_finish_move(o, s, save) < 0)
485             pa_source_output_kill(o);
486
487         pa_source_output_unref(o);
488     }
489
490     pa_queue_free(q, NULL, NULL);
491 }
492
493 /* Called from main context */
494 void pa_source_move_all_fail(pa_queue *q) {
495     pa_source_output *o;
496     pa_assert(q);
497
498     while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
499         if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL], o) == PA_HOOK_OK) {
500             pa_source_output_kill(o);
501             pa_source_output_unref(o);
502         }
503     }
504
505     pa_queue_free(q, NULL, NULL);
506 }
507
508 /* Called from IO thread context */
509 void pa_source_process_rewind(pa_source *s, size_t nbytes) {
510     pa_source_output *o;
511     void *state = NULL;
512
513     pa_source_assert_ref(s);
514     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
515
516     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
517         return;
518
519     if (nbytes <= 0)
520         return;
521
522     pa_log_debug("Processing rewind...");
523
524     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
525         pa_source_output_assert_ref(o);
526         pa_source_output_process_rewind(o, nbytes);
527     }
528 }
529
530 /* Called from IO thread context */
531 void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
532     pa_source_output *o;
533     void *state = NULL;
534
535     pa_source_assert_ref(s);
536     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
537     pa_assert(chunk);
538
539     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
540         return;
541
542     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
543         pa_memchunk vchunk = *chunk;
544
545         pa_memblock_ref(vchunk.memblock);
546         pa_memchunk_make_writable(&vchunk, 0);
547
548         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
549             pa_silence_memchunk(&vchunk, &s->sample_spec);
550         else
551             pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
552
553         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
554             pa_source_output_assert_ref(o);
555
556             if (!o->thread_info.direct_on_input)
557                 pa_source_output_push(o, &vchunk);
558         }
559
560         pa_memblock_unref(vchunk.memblock);
561     } else {
562
563         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
564             pa_source_output_assert_ref(o);
565
566             if (!o->thread_info.direct_on_input)
567                 pa_source_output_push(o, chunk);
568         }
569     }
570 }
571
572 /* Called from IO thread context */
573 void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *chunk) {
574     pa_source_assert_ref(s);
575     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
576     pa_source_output_assert_ref(o);
577     pa_assert(o->thread_info.direct_on_input);
578     pa_assert(chunk);
579
580     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
581         return;
582
583     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
584         pa_memchunk vchunk = *chunk;
585
586         pa_memblock_ref(vchunk.memblock);
587         pa_memchunk_make_writable(&vchunk, 0);
588
589         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
590             pa_silence_memchunk(&vchunk, &s->sample_spec);
591         else
592             pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
593
594         pa_source_output_push(o, &vchunk);
595
596         pa_memblock_unref(vchunk.memblock);
597     } else
598         pa_source_output_push(o, chunk);
599 }
600
601 /* Called from main thread */
602 pa_usec_t pa_source_get_latency(pa_source *s) {
603     pa_usec_t usec;
604
605     pa_source_assert_ref(s);
606     pa_assert(PA_SOURCE_IS_LINKED(s->state));
607
608     if (s->state == PA_SOURCE_SUSPENDED)
609         return 0;
610
611     if (!(s->flags & PA_SOURCE_LATENCY))
612         return 0;
613
614     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
615
616     return usec;
617 }
618
619 /* Called from main thread */
620 void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) {
621     pa_cvolume old_virtual_volume;
622     pa_bool_t virtual_volume_changed;
623
624     pa_source_assert_ref(s);
625     pa_assert(PA_SOURCE_IS_LINKED(s->state));
626     pa_assert(volume);
627     pa_assert(pa_cvolume_valid(volume));
628     pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
629
630     old_virtual_volume = s->virtual_volume;
631     s->virtual_volume = *volume;
632     virtual_volume_changed = !pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume);
633
634     if (s->set_volume) {
635         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
636         s->set_volume(s);
637     } else
638         s->soft_volume = s->virtual_volume;
639
640     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
641
642     if (virtual_volume_changed)
643         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
644 }
645
646 /* Called from main thread. Only to be called by source implementor */
647 void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
648     pa_source_assert_ref(s);
649     pa_assert(volume);
650
651     if (PA_SOURCE_IS_LINKED(s->state))
652         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
653     else
654         s->thread_info.soft_volume = *volume;
655 }
656
657 /* Called from main thread */
658 const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
659     pa_source_assert_ref(s);
660     pa_assert(PA_SOURCE_IS_LINKED(s->state));
661
662     if (s->refresh_volume || force_refresh) {
663         pa_cvolume old_virtual_volume = s->virtual_volume;
664
665         if (s->get_volume)
666             s->get_volume(s);
667
668         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
669
670         if (!pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume))
671             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
672     }
673
674     return &s->virtual_volume;
675 }
676
677 /* Called from main thread */
678 void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_volume) {
679     pa_source_assert_ref(s);
680
681     /* The source implementor may call this if the volume changed to make sure everyone is notified */
682
683     if (pa_cvolume_equal(&s->virtual_volume, new_volume))
684         return;
685
686     s->virtual_volume = *new_volume;
687     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
688 }
689
690 /* Called from main thread */
691 void pa_source_set_mute(pa_source *s, pa_bool_t mute) {
692     pa_bool_t old_muted;
693
694     pa_source_assert_ref(s);
695     pa_assert(PA_SOURCE_IS_LINKED(s->state));
696
697     old_muted = s->muted;
698     s->muted = mute;
699
700     if (s->set_mute)
701         s->set_mute(s);
702
703     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
704
705     if (old_muted != s->muted)
706         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
707 }
708
709 /* Called from main thread */
710 pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
711     pa_source_assert_ref(s);
712     pa_assert(PA_SOURCE_IS_LINKED(s->state));
713
714     if (s->refresh_muted || force_refresh) {
715         pa_bool_t old_muted = s->muted;
716
717         if (s->get_mute)
718             s->get_mute(s);
719
720         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
721
722         if (old_muted != s->muted)
723             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
724     }
725
726     return s->muted;
727 }
728
729 /* Called from main thread */
730 void pa_source_mute_changed(pa_source *s, pa_bool_t new_muted) {
731     pa_source_assert_ref(s);
732
733     /* The source implementor may call this if the mute state changed to make sure everyone is notified */
734
735     if (s->muted == new_muted)
736         return;
737
738     s->muted = new_muted;
739     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
740 }
741
742 /* Called from main thread */
743 pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p) {
744     pa_source_assert_ref(s);
745     pa_assert(p);
746
747     pa_proplist_update(s->proplist, mode, p);
748
749     if (PA_SOURCE_IS_LINKED(s->state)) {
750         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
751         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
752     }
753
754     return TRUE;
755 }
756
757 /* Called from main thread */
758 void pa_source_set_description(pa_source *s, const char *description) {
759     const char *old;
760     pa_source_assert_ref(s);
761
762     if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
763         return;
764
765     old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
766
767     if (old && description && !strcmp(old, description))
768         return;
769
770     if (description)
771         pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
772     else
773         pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
774
775     if (PA_SOURCE_IS_LINKED(s->state)) {
776         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
777         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
778     }
779 }
780
781 /* Called from main thread */
782 unsigned pa_source_linked_by(pa_source *s) {
783     pa_source_assert_ref(s);
784     pa_assert(PA_SOURCE_IS_LINKED(s->state));
785
786     return pa_idxset_size(s->outputs);
787 }
788
789 /* Called from main thread */
790 unsigned pa_source_used_by(pa_source *s) {
791     unsigned ret;
792
793     pa_source_assert_ref(s);
794     pa_assert(PA_SOURCE_IS_LINKED(s->state));
795
796     ret = pa_idxset_size(s->outputs);
797     pa_assert(ret >= s->n_corked);
798
799     return ret - s->n_corked;
800 }
801
802 /* Called from main thread */
803 unsigned pa_source_check_suspend(pa_source *s) {
804     unsigned ret;
805     pa_source_output *o;
806     uint32_t idx;
807
808     pa_source_assert_ref(s);
809
810     if (!PA_SOURCE_IS_LINKED(s->state))
811         return 0;
812
813     ret = 0;
814
815     for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) {
816         pa_source_output_state_t st;
817
818         st = pa_source_output_get_state(o);
819         pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(st));
820
821         if (st == PA_SOURCE_OUTPUT_CORKED)
822             continue;
823
824         if (o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND)
825             continue;
826
827         ret ++;
828     }
829
830     return ret;
831 }
832
833 /* Called from IO thread, except when it is not */
834 int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
835     pa_source *s = PA_SOURCE(object);
836     pa_source_assert_ref(s);
837
838     switch ((pa_source_message_t) code) {
839
840         case PA_SOURCE_MESSAGE_ADD_OUTPUT: {
841             pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
842
843             pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o));
844
845             if (o->direct_on_input) {
846                 o->thread_info.direct_on_input = o->direct_on_input;
847                 pa_hashmap_put(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index), o);
848             }
849
850             pa_assert(!o->thread_info.attached);
851             o->thread_info.attached = TRUE;
852
853             if (o->attach)
854                 o->attach(o);
855
856             pa_source_output_set_state_within_thread(o, o->state);
857
858             if (o->thread_info.requested_source_latency != (pa_usec_t) -1)
859                 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
860
861             pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
862
863             /* We don't just invalidate the requested latency here,
864              * because if we are in a move we might need to fix up the
865              * requested latency. */
866             pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
867
868             return 0;
869         }
870
871         case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: {
872             pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
873
874             pa_source_output_set_state_within_thread(o, o->state);
875
876             if (o->detach)
877                 o->detach(o);
878
879             pa_assert(o->thread_info.attached);
880             o->thread_info.attached = FALSE;
881
882             if (o->thread_info.direct_on_input) {
883                 pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index));
884                 o->thread_info.direct_on_input = NULL;
885             }
886
887             if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
888                 pa_source_output_unref(o);
889
890             pa_source_invalidate_requested_latency(s);
891
892             return 0;
893         }
894
895         case PA_SOURCE_MESSAGE_SET_VOLUME:
896             s->thread_info.soft_volume = s->soft_volume;
897             return 0;
898
899         case PA_SOURCE_MESSAGE_GET_VOLUME:
900             return 0;
901
902         case PA_SOURCE_MESSAGE_SET_MUTE:
903             s->thread_info.soft_muted = s->muted;
904             return 0;
905
906         case PA_SOURCE_MESSAGE_GET_MUTE:
907             return 0;
908
909         case PA_SOURCE_MESSAGE_SET_STATE:
910             s->thread_info.state = PA_PTR_TO_UINT(userdata);
911             return 0;
912
913         case PA_SOURCE_MESSAGE_DETACH:
914
915             /* Detach all streams */
916             pa_source_detach_within_thread(s);
917             return 0;
918
919         case PA_SOURCE_MESSAGE_ATTACH:
920
921             /* Reattach all streams */
922             pa_source_attach_within_thread(s);
923             return 0;
924
925         case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: {
926
927             pa_usec_t *usec = userdata;
928             *usec = pa_source_get_requested_latency_within_thread(s);
929
930             if (*usec == (pa_usec_t) -1)
931                 *usec = s->thread_info.max_latency;
932
933             return 0;
934         }
935
936         case PA_SOURCE_MESSAGE_SET_LATENCY_RANGE: {
937             pa_usec_t *r = userdata;
938
939             pa_source_update_latency_range(s, r[0], r[1]);
940
941             return 0;
942         }
943
944         case PA_SOURCE_MESSAGE_GET_LATENCY_RANGE: {
945             pa_usec_t *r = userdata;
946
947             r[0] = s->thread_info.min_latency;
948             r[1] = s->thread_info.max_latency;
949
950             return 0;
951         }
952
953         case PA_SOURCE_MESSAGE_GET_MAX_REWIND:
954
955             *((size_t*) userdata) = s->thread_info.max_rewind;
956             return 0;
957
958         case PA_SOURCE_MESSAGE_GET_LATENCY:
959
960             if (s->monitor_of) {
961                 *((pa_usec_t*) userdata) = 0;
962                 return 0;
963             }
964
965             /* Implementors need to overwrite this implementation! */
966             return -1;
967
968         case PA_SOURCE_MESSAGE_MAX:
969             ;
970     }
971
972     return -1;
973 }
974
975 /* Called from main thread */
976 int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) {
977     uint32_t idx;
978     pa_source *source;
979     int ret = 0;
980
981     pa_core_assert_ref(c);
982
983     for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) {
984         int r;
985
986         if (source->monitor_of)
987             continue;
988
989         if ((r = pa_source_suspend(source, suspend)) < 0)
990             ret = r;
991     }
992
993     return ret;
994 }
995
996 /* Called from main thread */
997 void pa_source_detach(pa_source *s) {
998     pa_source_assert_ref(s);
999     pa_assert(PA_SOURCE_IS_LINKED(s->state));
1000
1001     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL) == 0);
1002 }
1003
1004 /* Called from main thread */
1005 void pa_source_attach(pa_source *s) {
1006     pa_source_assert_ref(s);
1007     pa_assert(PA_SOURCE_IS_LINKED(s->state));
1008
1009     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
1010 }
1011
1012 /* Called from IO thread */
1013 void pa_source_detach_within_thread(pa_source *s) {
1014     pa_source_output *o;
1015     void *state = NULL;
1016
1017     pa_source_assert_ref(s);
1018     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
1019
1020     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1021         if (o->detach)
1022             o->detach(o);
1023 }
1024
1025 /* Called from IO thread */
1026 void pa_source_attach_within_thread(pa_source *s) {
1027     pa_source_output *o;
1028     void *state = NULL;
1029
1030     pa_source_assert_ref(s);
1031     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
1032
1033     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1034         if (o->attach)
1035             o->attach(o);
1036 }
1037
1038 /* Called from IO thread */
1039 pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
1040     pa_usec_t result = (pa_usec_t) -1;
1041     pa_source_output *o;
1042     void *state = NULL;
1043
1044     pa_source_assert_ref(s);
1045
1046     if (s->thread_info.requested_latency_valid)
1047         return s->thread_info.requested_latency;
1048
1049     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1050
1051         if (o->thread_info.requested_source_latency != (pa_usec_t) -1 &&
1052             (result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency))
1053             result = o->thread_info.requested_source_latency;
1054
1055     if (result != (pa_usec_t) -1) {
1056         if (s->thread_info.max_latency > 0 && result > s->thread_info.max_latency)
1057             result = s->thread_info.max_latency;
1058
1059         if (s->thread_info.min_latency > 0 && result < s->thread_info.min_latency)
1060             result = s->thread_info.min_latency;
1061     }
1062
1063     s->thread_info.requested_latency = result;
1064     s->thread_info.requested_latency_valid = TRUE;
1065
1066     return result;
1067 }
1068
1069 /* Called from main thread */
1070 pa_usec_t pa_source_get_requested_latency(pa_source *s) {
1071     pa_usec_t usec;
1072
1073     pa_source_assert_ref(s);
1074     pa_assert(PA_SOURCE_IS_LINKED(s->state));
1075
1076     if (s->state == PA_SOURCE_SUSPENDED)
1077         return 0;
1078
1079     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1080
1081     return usec;
1082 }
1083
1084 /* Called from IO thread */
1085 void pa_source_set_max_rewind(pa_source *s, size_t max_rewind) {
1086     pa_source_output *o;
1087     void *state = NULL;
1088
1089     pa_source_assert_ref(s);
1090
1091     if (max_rewind == s->thread_info.max_rewind)
1092         return;
1093
1094     s->thread_info.max_rewind = max_rewind;
1095
1096     if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
1097         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1098             pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
1099     }
1100 }
1101
1102 void pa_source_invalidate_requested_latency(pa_source *s) {
1103     pa_source_output *o;
1104     void *state = NULL;
1105
1106     pa_source_assert_ref(s);
1107
1108     s->thread_info.requested_latency_valid = FALSE;
1109
1110     if (s->update_requested_latency)
1111         s->update_requested_latency(s);
1112
1113     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1114         if (o->update_source_requested_latency)
1115             o->update_source_requested_latency(o);
1116
1117     if (s->monitor_of)
1118         pa_sink_invalidate_requested_latency(s->monitor_of);
1119 }
1120
1121 void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1122     pa_source_assert_ref(s);
1123
1124     /* min_latency == 0:           no limit
1125      * min_latency == (size_t) -1: default limit
1126      * min_latency anything else:  specified limit
1127      *
1128      * Similar for max_latency */
1129
1130     if (min_latency == (pa_usec_t) -1)
1131         min_latency = DEFAULT_MIN_LATENCY;
1132
1133     if (max_latency == (pa_usec_t) -1)
1134         max_latency = min_latency;
1135
1136     pa_assert(!min_latency || !max_latency ||
1137               min_latency <= max_latency);
1138
1139     if (PA_SOURCE_IS_LINKED(s->state)) {
1140         pa_usec_t r[2];
1141
1142         r[0] = min_latency;
1143         r[1] = max_latency;
1144
1145         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
1146     } else {
1147         s->thread_info.min_latency = min_latency;
1148         s->thread_info.max_latency = max_latency;
1149
1150         s->thread_info.requested_latency_valid = FALSE;
1151     }
1152 }
1153
1154 void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
1155    pa_source_assert_ref(s);
1156    pa_assert(min_latency);
1157    pa_assert(max_latency);
1158
1159    if (PA_SOURCE_IS_LINKED(s->state)) {
1160        pa_usec_t r[2] = { 0, 0 };
1161
1162        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
1163
1164        *min_latency = r[0];
1165        *max_latency = r[1];
1166    } else {
1167        *min_latency = s->thread_info.min_latency;
1168        *max_latency = s->thread_info.max_latency;
1169    }
1170 }
1171
1172 /* Called from IO thread */
1173 void pa_source_update_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1174     pa_source_output *o;
1175     void *state = NULL;
1176
1177     pa_source_assert_ref(s);
1178
1179     pa_assert(!min_latency || !max_latency ||
1180               min_latency <= max_latency);
1181
1182     s->thread_info.min_latency = min_latency;
1183     s->thread_info.max_latency = max_latency;
1184
1185     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1186         if (o->update_source_latency_range)
1187             o->update_source_latency_range(o);
1188
1189     pa_source_invalidate_requested_latency(s);
1190 }
1191
1192 size_t pa_source_get_max_rewind(pa_source *s) {
1193     size_t r;
1194     pa_source_assert_ref(s);
1195
1196     if (!PA_SOURCE_IS_LINKED(s->state))
1197         return s->thread_info.max_rewind;
1198
1199     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
1200
1201     return r;
1202 }