2 This file is part of PulseAudio.
4 Copyright 2010 Intel Corporation
5 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 /* TODO: Some plugins cause latency, and some even report it by using a control
24 out port. We don't currently use the latency information. */
30 #include <pulse/gccmacro.h>
31 #include <pulse/xmalloc.h>
32 #include <pulse/i18n.h>
34 #include <pulsecore/namereg.h>
35 #include <pulsecore/sink.h>
36 #include <pulsecore/module.h>
37 #include <pulsecore/core-util.h>
38 #include <pulsecore/modargs.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/rtpoll.h>
41 #include <pulsecore/sample-util.h>
42 #include <pulsecore/ltdl-helper.h>
44 #include "module-virtual-sink-symdef.h"
46 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
47 PA_MODULE_DESCRIPTION(_("Virtual sink"));
48 PA_MODULE_VERSION(PACKAGE_VERSION
);
49 PA_MODULE_LOAD_ONCE(FALSE
);
51 _("sink_name=<name for the sink> "
52 "sink_properties=<properties for the sink> "
53 "master=<name of sink to filter> "
54 "format=<sample format> "
56 "channels=<number of channels> "
57 "channel_map=<channel map> "
58 "use_volume_sharing=<yes or no> "
59 "force_flat_volume=<yes or no> "
62 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
67 /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
68 /* pa_bool_t autoloaded; */
71 pa_sink_input
*sink_input
;
73 pa_memblockq
*memblockq
;
79 static const char* const valid_modargs
[] = {
92 /* Called from I/O thread context */
93 static int sink_process_msg_cb(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
94 struct userdata
*u
= PA_SINK(o
)->userdata
;
98 case PA_SINK_MESSAGE_GET_LATENCY
:
100 /* The sink is _put() before the sink input is, so let's
101 * make sure we don't access it in that time. Also, the
102 * sink input is first shut down, the sink second. */
103 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
104 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
)) {
105 *((pa_usec_t
*) data
) = 0;
109 *((pa_usec_t
*) data
) =
111 /* Get the latency of the master sink */
112 pa_sink_get_latency_within_thread(u
->sink_input
->sink
) +
114 /* Add the latency internal to our sink input on top */
115 pa_bytes_to_usec(pa_memblockq_get_length(u
->sink_input
->thread_info
.render_memblockq
), &u
->sink_input
->sink
->sample_spec
);
120 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
123 /* Called from main context */
124 static int sink_set_state_cb(pa_sink
*s
, pa_sink_state_t state
) {
127 pa_sink_assert_ref(s
);
128 pa_assert_se(u
= s
->userdata
);
130 if (!PA_SINK_IS_LINKED(state
) ||
131 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
134 pa_sink_input_cork(u
->sink_input
, state
== PA_SINK_SUSPENDED
);
138 /* Called from I/O thread context */
139 static void sink_request_rewind_cb(pa_sink
*s
) {
142 pa_sink_assert_ref(s
);
143 pa_assert_se(u
= s
->userdata
);
145 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
146 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
149 /* Just hand this one over to the master sink */
150 pa_sink_input_request_rewind(u
->sink_input
,
151 s
->thread_info
.rewind_nbytes
+
152 pa_memblockq_get_length(u
->memblockq
), TRUE
, FALSE
, FALSE
);
155 /* Called from I/O thread context */
156 static void sink_update_requested_latency_cb(pa_sink
*s
) {
159 pa_sink_assert_ref(s
);
160 pa_assert_se(u
= s
->userdata
);
162 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
163 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
166 /* Just hand this one over to the master sink */
167 pa_sink_input_set_requested_latency_within_thread(
169 pa_sink_get_requested_latency_within_thread(s
));
172 /* Called from main context */
173 static void sink_set_volume_cb(pa_sink
*s
) {
176 pa_sink_assert_ref(s
);
177 pa_assert_se(u
= s
->userdata
);
179 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
180 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
183 pa_sink_input_set_volume(u
->sink_input
, &s
->real_volume
, s
->save_volume
, TRUE
);
186 /* Called from main context */
187 static void sink_set_mute_cb(pa_sink
*s
) {
190 pa_sink_assert_ref(s
);
191 pa_assert_se(u
= s
->userdata
);
193 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
194 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
197 pa_sink_input_set_mute(u
->sink_input
, s
->muted
, s
->save_muted
);
200 /* Called from I/O thread context */
201 static int sink_input_pop_cb(pa_sink_input
*i
, size_t nbytes
, pa_memchunk
*chunk
) {
207 pa_usec_t current_latency PA_GCC_UNUSED
;
209 pa_sink_input_assert_ref(i
);
211 pa_assert_se(u
= i
->userdata
);
213 /* Hmm, process any rewind request that might be queued up */
214 pa_sink_process_rewind(u
->sink
, 0);
216 /* (1) IF YOU NEED A FIXED BLOCK SIZE USE
217 * pa_memblockq_peek_fixed_size() HERE INSTEAD. NOTE THAT FILTERS
218 * WHICH CAN DEAL WITH DYNAMIC BLOCK SIZES ARE HIGHLY
220 while (pa_memblockq_peek(u
->memblockq
, &tchunk
) < 0) {
223 pa_sink_render(u
->sink
, nbytes
, &nchunk
);
224 pa_memblockq_push(u
->memblockq
, &nchunk
);
225 pa_memblock_unref(nchunk
.memblock
);
228 /* (2) IF YOU NEED A FIXED BLOCK SIZE, THIS NEXT LINE IS NOT
230 tchunk
.length
= PA_MIN(nbytes
, tchunk
.length
);
231 pa_assert(tchunk
.length
> 0);
233 fs
= pa_frame_size(&i
->sample_spec
);
234 n
= (unsigned) (tchunk
.length
/ fs
);
239 chunk
->length
= n
*fs
;
240 chunk
->memblock
= pa_memblock_new(i
->sink
->core
->mempool
, chunk
->length
);
242 pa_memblockq_drop(u
->memblockq
, chunk
->length
);
244 src
= (float*) ((uint8_t*) pa_memblock_acquire(tchunk
.memblock
) + tchunk
.index
);
245 dst
= (float*) pa_memblock_acquire(chunk
->memblock
);
247 /* (3) PUT YOUR CODE HERE TO DO SOMETHING WITH THE DATA */
249 /* As an example, copy input to output */
250 for (c
= 0; c
< u
->channels
; c
++) {
251 pa_sample_clamp(PA_SAMPLE_FLOAT32NE
,
252 dst
+c
, u
->channels
* sizeof(float),
253 src
+c
, u
->channels
* sizeof(float),
257 pa_memblock_release(tchunk
.memblock
);
258 pa_memblock_release(chunk
->memblock
);
260 pa_memblock_unref(tchunk
.memblock
);
262 /* (4) IF YOU NEED THE LATENCY FOR SOMETHING ACQUIRE IT LIKE THIS: */
264 /* Get the latency of the master sink */
265 pa_sink_get_latency_within_thread(i
->sink
) +
267 /* Add the latency internal to our sink input on top */
268 pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
273 /* Called from I/O thread context */
274 static void sink_input_process_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
278 pa_sink_input_assert_ref(i
);
279 pa_assert_se(u
= i
->userdata
);
281 if (u
->sink
->thread_info
.rewind_nbytes
> 0) {
284 max_rewrite
= nbytes
+ pa_memblockq_get_length(u
->memblockq
);
285 amount
= PA_MIN(u
->sink
->thread_info
.rewind_nbytes
, max_rewrite
);
286 u
->sink
->thread_info
.rewind_nbytes
= 0;
289 pa_memblockq_seek(u
->memblockq
, - (int64_t) amount
, PA_SEEK_RELATIVE
, TRUE
);
291 /* (5) PUT YOUR CODE HERE TO RESET YOUR FILTER */
295 pa_sink_process_rewind(u
->sink
, amount
);
296 pa_memblockq_rewind(u
->memblockq
, nbytes
);
299 /* Called from I/O thread context */
300 static void sink_input_update_max_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
303 pa_sink_input_assert_ref(i
);
304 pa_assert_se(u
= i
->userdata
);
306 pa_memblockq_set_maxrewind(u
->memblockq
, nbytes
);
307 pa_sink_set_max_rewind_within_thread(u
->sink
, nbytes
);
310 /* Called from I/O thread context */
311 static void sink_input_update_max_request_cb(pa_sink_input
*i
, size_t nbytes
) {
314 pa_sink_input_assert_ref(i
);
315 pa_assert_se(u
= i
->userdata
);
317 /* (6) IF YOU NEED A FIXED BLOCK SIZE ROUND nbytes UP TO MULTIPLES
318 * OF IT HERE. THE PA_ROUND_UP MACRO IS USEFUL FOR THAT. */
320 pa_sink_set_max_request_within_thread(u
->sink
, nbytes
);
323 /* Called from I/O thread context */
324 static void sink_input_update_sink_latency_range_cb(pa_sink_input
*i
) {
327 pa_sink_input_assert_ref(i
);
328 pa_assert_se(u
= i
->userdata
);
330 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
333 /* Called from I/O thread context */
334 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input
*i
) {
337 pa_sink_input_assert_ref(i
);
338 pa_assert_se(u
= i
->userdata
);
340 /* (7) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
341 * BLOCK MINUS ONE SAMPLE HERE. pa_usec_to_bytes_round_up() IS
342 * USEFUL FOR THAT. */
344 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
347 /* Called from I/O thread context */
348 static void sink_input_detach_cb(pa_sink_input
*i
) {
351 pa_sink_input_assert_ref(i
);
352 pa_assert_se(u
= i
->userdata
);
354 pa_sink_detach_within_thread(u
->sink
);
356 pa_sink_set_rtpoll(u
->sink
, NULL
);
359 /* Called from I/O thread context */
360 static void sink_input_attach_cb(pa_sink_input
*i
) {
363 pa_sink_input_assert_ref(i
);
364 pa_assert_se(u
= i
->userdata
);
366 pa_sink_set_rtpoll(u
->sink
, i
->sink
->thread_info
.rtpoll
);
367 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
369 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
370 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
371 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
373 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
374 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
376 pa_sink_set_max_request_within_thread(u
->sink
, pa_sink_input_get_max_request(i
));
377 pa_sink_set_max_rewind_within_thread(u
->sink
, pa_sink_input_get_max_rewind(i
));
379 pa_sink_attach_within_thread(u
->sink
);
382 /* Called from main context */
383 static void sink_input_kill_cb(pa_sink_input
*i
) {
386 pa_sink_input_assert_ref(i
);
387 pa_assert_se(u
= i
->userdata
);
389 /* The order here matters! We first kill the sink input, followed
390 * by the sink. That means the sink callbacks must be protected
391 * against an unconnected sink input! */
392 pa_sink_input_unlink(u
->sink_input
);
393 pa_sink_unlink(u
->sink
);
395 pa_sink_input_unref(u
->sink_input
);
396 u
->sink_input
= NULL
;
398 pa_sink_unref(u
->sink
);
401 pa_module_unload_request(u
->module
, TRUE
);
404 /* Called from IO thread context */
405 static void sink_input_state_change_cb(pa_sink_input
*i
, pa_sink_input_state_t state
) {
408 pa_sink_input_assert_ref(i
);
409 pa_assert_se(u
= i
->userdata
);
411 /* If we are added for the first time, ask for a rewinding so that
412 * we are heard right-away. */
413 if (PA_SINK_INPUT_IS_LINKED(state
) &&
414 i
->thread_info
.state
== PA_SINK_INPUT_INIT
) {
415 pa_log_debug("Requesting rewind due to state change.");
416 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
420 /* Called from main context */
421 static pa_bool_t
sink_input_may_move_to_cb(pa_sink_input
*i
, pa_sink
*dest
) {
424 pa_sink_input_assert_ref(i
);
425 pa_assert_se(u
= i
->userdata
);
427 return u
->sink
!= dest
;
430 /* Called from main context */
431 static void sink_input_moving_cb(pa_sink_input
*i
, pa_sink
*dest
) {
434 pa_sink_input_assert_ref(i
);
435 pa_assert_se(u
= i
->userdata
);
438 pa_sink_set_asyncmsgq(u
->sink
, dest
->asyncmsgq
);
439 pa_sink_update_flags(u
->sink
, PA_SINK_LATENCY
|PA_SINK_DYNAMIC_LATENCY
, dest
->flags
);
441 pa_sink_set_asyncmsgq(u
->sink
, NULL
);
443 if (u
->auto_desc
&& dest
) {
447 pl
= pa_proplist_new();
448 z
= pa_proplist_gets(dest
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
449 pa_proplist_setf(pl
, PA_PROP_DEVICE_DESCRIPTION
, "Virtual Sink %s on %s",
450 pa_proplist_gets(u
->sink
->proplist
, "device.vsink.name"), z
? z
: dest
->name
);
452 pa_sink_update_proplist(u
->sink
, PA_UPDATE_REPLACE
, pl
);
453 pa_proplist_free(pl
);
457 /* Called from main context */
458 static void sink_input_volume_changed_cb(pa_sink_input
*i
) {
461 pa_sink_input_assert_ref(i
);
462 pa_assert_se(u
= i
->userdata
);
464 pa_sink_volume_changed(u
->sink
, &i
->volume
);
467 /* Called from main context */
468 static void sink_input_mute_changed_cb(pa_sink_input
*i
) {
471 pa_sink_input_assert_ref(i
);
472 pa_assert_se(u
= i
->userdata
);
474 pa_sink_mute_changed(u
->sink
, i
->muted
);
477 int pa__init(pa_module
*m
) {
482 pa_sink
*master
=NULL
;
483 pa_sink_input_new_data sink_input_data
;
484 pa_sink_new_data sink_data
;
485 pa_bool_t use_volume_sharing
= FALSE
;
486 pa_bool_t force_flat_volume
= FALSE
;
491 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
492 pa_log("Failed to parse module arguments.");
496 if (!(master
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "master", NULL
), PA_NAMEREG_SINK
))) {
497 pa_log("Master sink not found");
503 ss
= master
->sample_spec
;
504 ss
.format
= PA_SAMPLE_FLOAT32
;
505 map
= master
->channel_map
;
506 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_DEFAULT
) < 0) {
507 pa_log("Invalid sample format specification or channel map");
511 if (pa_modargs_get_value_boolean(ma
, "use_volume_sharing", &use_volume_sharing
) < 0) {
512 pa_log("use_volume_sharing= expects a boolean argument");
516 if (pa_modargs_get_value_boolean(ma
, "force_flat_volume", &force_flat_volume
) < 0) {
517 pa_log("force_flat_volume= expects a boolean argument");
521 if (use_volume_sharing
&& force_flat_volume
) {
522 pa_log("Flat volume can't be forced when using volume sharing.");
526 u
= pa_xnew0(struct userdata
, 1);
529 u
->channels
= ss
.channels
;
532 pa_sink_new_data_init(&sink_data
);
533 sink_data
.driver
= __FILE__
;
534 sink_data
.module
= m
;
535 if (!(sink_data
.name
= pa_xstrdup(pa_modargs_get_value(ma
, "sink_name", NULL
))))
536 sink_data
.name
= pa_sprintf_malloc("%s.vsink", master
->name
);
537 pa_sink_new_data_set_sample_spec(&sink_data
, &ss
);
538 pa_sink_new_data_set_channel_map(&sink_data
, &map
);
539 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_MASTER_DEVICE
, master
->name
);
540 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_CLASS
, "filter");
541 pa_proplist_sets(sink_data
.proplist
, "device.vsink.name", sink_data
.name
);
543 if (pa_modargs_get_proplist(ma
, "sink_properties", sink_data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
544 pa_log("Invalid properties");
545 pa_sink_new_data_done(&sink_data
);
549 if ((u
->auto_desc
= !pa_proplist_contains(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
))) {
552 z
= pa_proplist_gets(master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
553 pa_proplist_setf(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, "Virtual Sink %s on %s", sink_data
.name
, z
? z
: master
->name
);
556 u
->sink
= pa_sink_new(m
->core
, &sink_data
, (master
->flags
& (PA_SINK_LATENCY
|PA_SINK_DYNAMIC_LATENCY
))
557 | (use_volume_sharing
? PA_SINK_SHARE_VOLUME_WITH_MASTER
: 0)
558 | (force_flat_volume
? PA_SINK_FLAT_VOLUME
: 0));
559 pa_sink_new_data_done(&sink_data
);
562 pa_log("Failed to create sink.");
566 u
->sink
->parent
.process_msg
= sink_process_msg_cb
;
567 u
->sink
->set_state
= sink_set_state_cb
;
568 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
569 u
->sink
->request_rewind
= sink_request_rewind_cb
;
570 u
->sink
->set_volume
= use_volume_sharing
? NULL
: sink_set_volume_cb
;
571 u
->sink
->set_mute
= sink_set_mute_cb
;
572 u
->sink
->userdata
= u
;
574 pa_sink_set_asyncmsgq(u
->sink
, master
->asyncmsgq
);
576 /* Create sink input */
577 pa_sink_input_new_data_init(&sink_input_data
);
578 sink_input_data
.driver
= __FILE__
;
579 sink_input_data
.module
= m
;
580 pa_sink_input_new_data_set_sink(&sink_input_data
, master
, FALSE
);
581 sink_input_data
.origin_sink
= u
->sink
;
582 pa_proplist_setf(sink_input_data
.proplist
, PA_PROP_MEDIA_NAME
, "Virtual Sink Stream from %s", pa_proplist_gets(u
->sink
->proplist
, PA_PROP_DEVICE_DESCRIPTION
));
583 pa_proplist_sets(sink_input_data
.proplist
, PA_PROP_MEDIA_ROLE
, "filter");
584 pa_sink_input_new_data_set_sample_spec(&sink_input_data
, &ss
);
585 pa_sink_input_new_data_set_channel_map(&sink_input_data
, &map
);
587 pa_sink_input_new(&u
->sink_input
, m
->core
, &sink_input_data
);
588 pa_sink_input_new_data_done(&sink_input_data
);
593 u
->sink_input
->pop
= sink_input_pop_cb
;
594 u
->sink_input
->process_rewind
= sink_input_process_rewind_cb
;
595 u
->sink_input
->update_max_rewind
= sink_input_update_max_rewind_cb
;
596 u
->sink_input
->update_max_request
= sink_input_update_max_request_cb
;
597 u
->sink_input
->update_sink_latency_range
= sink_input_update_sink_latency_range_cb
;
598 u
->sink_input
->update_sink_fixed_latency
= sink_input_update_sink_fixed_latency_cb
;
599 u
->sink_input
->kill
= sink_input_kill_cb
;
600 u
->sink_input
->attach
= sink_input_attach_cb
;
601 u
->sink_input
->detach
= sink_input_detach_cb
;
602 u
->sink_input
->state_change
= sink_input_state_change_cb
;
603 u
->sink_input
->may_move_to
= sink_input_may_move_to_cb
;
604 u
->sink_input
->moving
= sink_input_moving_cb
;
605 u
->sink_input
->volume_changed
= use_volume_sharing
? NULL
: sink_input_volume_changed_cb
;
606 u
->sink_input
->mute_changed
= sink_input_mute_changed_cb
;
607 u
->sink_input
->userdata
= u
;
609 u
->sink
->input_to_master
= u
->sink_input
;
611 pa_sink_input_get_silence(u
->sink_input
, &silence
);
612 u
->memblockq
= pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH
, 0, pa_frame_size(&ss
), 1, 1, 0, &silence
);
613 pa_memblock_unref(silence
.memblock
);
615 /* (9) INITIALIZE ANYTHING ELSE YOU NEED HERE */
617 pa_sink_put(u
->sink
);
618 pa_sink_input_put(u
->sink_input
);
633 int pa__get_n_used(pa_module
*m
) {
637 pa_assert_se(u
= m
->userdata
);
639 return pa_sink_linked_by(u
->sink
);
642 void pa__done(pa_module
*m
) {
647 if (!(u
= m
->userdata
))
650 /* See comments in sink_input_kill_cb() above regarding
651 * destruction order! */
654 pa_sink_input_unlink(u
->sink_input
);
657 pa_sink_unlink(u
->sink
);
660 pa_sink_input_unref(u
->sink_input
);
663 pa_sink_unref(u
->sink
);
666 pa_memblockq_free(u
->memblockq
);