]> code.delx.au - pulseaudio/blob - src/modules/module-virtual-sink.c
alsa-mixer: Add surround 2.1 profile
[pulseaudio] / src / modules / module-virtual-sink.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2010 Intel Corporation
5 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
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 <pulse/gccmacro.h>
28 #include <pulse/xmalloc.h>
29
30 #include <pulsecore/i18n.h>
31 #include <pulsecore/namereg.h>
32 #include <pulsecore/sink.h>
33 #include <pulsecore/module.h>
34 #include <pulsecore/core-util.h>
35 #include <pulsecore/modargs.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/rtpoll.h>
38 #include <pulsecore/sample-util.h>
39 #include <pulsecore/ltdl-helper.h>
40
41 #include "module-virtual-sink-symdef.h"
42
43 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
44 PA_MODULE_DESCRIPTION(_("Virtual sink"));
45 PA_MODULE_VERSION(PACKAGE_VERSION);
46 PA_MODULE_LOAD_ONCE(false);
47 PA_MODULE_USAGE(
48 _("sink_name=<name for the sink> "
49 "sink_properties=<properties for the sink> "
50 "master=<name of sink to filter> "
51 "rate=<sample rate> "
52 "channels=<number of channels> "
53 "channel_map=<channel map> "
54 "use_volume_sharing=<yes or no> "
55 "force_flat_volume=<yes or no> "
56 ));
57
58 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
59
60 struct userdata {
61 pa_module *module;
62
63 /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
64 /* bool autoloaded; */
65
66 pa_sink *sink;
67 pa_sink_input *sink_input;
68
69 pa_memblockq *memblockq;
70
71 bool auto_desc;
72 unsigned channels;
73 };
74
75 static const char* const valid_modargs[] = {
76 "sink_name",
77 "sink_properties",
78 "master",
79 "rate",
80 "channels",
81 "channel_map",
82 "use_volume_sharing",
83 "force_flat_volume",
84 NULL
85 };
86
87 /* Called from I/O thread context */
88 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
89 struct userdata *u = PA_SINK(o)->userdata;
90
91 switch (code) {
92
93 case PA_SINK_MESSAGE_GET_LATENCY:
94
95 /* The sink is _put() before the sink input is, so let's
96 * make sure we don't access it in that time. Also, the
97 * sink input is first shut down, the sink second. */
98 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
99 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
100 *((pa_usec_t*) data) = 0;
101 return 0;
102 }
103
104 *((pa_usec_t*) data) =
105
106 /* Get the latency of the master sink */
107 pa_sink_get_latency_within_thread(u->sink_input->sink) +
108
109 /* Add the latency internal to our sink input on top */
110 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
111
112 return 0;
113 }
114
115 return pa_sink_process_msg(o, code, data, offset, chunk);
116 }
117
118 /* Called from main context */
119 static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
120 struct userdata *u;
121
122 pa_sink_assert_ref(s);
123 pa_assert_se(u = s->userdata);
124
125 if (!PA_SINK_IS_LINKED(state) ||
126 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
127 return 0;
128
129 pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
130 return 0;
131 }
132
133 /* Called from I/O thread context */
134 static void sink_request_rewind_cb(pa_sink *s) {
135 struct userdata *u;
136
137 pa_sink_assert_ref(s);
138 pa_assert_se(u = s->userdata);
139
140 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
141 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
142 return;
143
144 /* Just hand this one over to the master sink */
145 pa_sink_input_request_rewind(u->sink_input,
146 s->thread_info.rewind_nbytes +
147 pa_memblockq_get_length(u->memblockq), true, false, false);
148 }
149
150 /* Called from I/O thread context */
151 static void sink_update_requested_latency_cb(pa_sink *s) {
152 struct userdata *u;
153
154 pa_sink_assert_ref(s);
155 pa_assert_se(u = s->userdata);
156
157 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
158 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
159 return;
160
161 /* Just hand this one over to the master sink */
162 pa_sink_input_set_requested_latency_within_thread(
163 u->sink_input,
164 pa_sink_get_requested_latency_within_thread(s));
165 }
166
167 /* Called from main context */
168 static void sink_set_volume_cb(pa_sink *s) {
169 struct userdata *u;
170
171 pa_sink_assert_ref(s);
172 pa_assert_se(u = s->userdata);
173
174 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
175 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
176 return;
177
178 pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true);
179 }
180
181 /* Called from main context */
182 static void sink_set_mute_cb(pa_sink *s) {
183 struct userdata *u;
184
185 pa_sink_assert_ref(s);
186 pa_assert_se(u = s->userdata);
187
188 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
189 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
190 return;
191
192 pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
193 }
194
195 /* Called from I/O thread context */
196 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
197 struct userdata *u;
198 float *src, *dst;
199 size_t fs;
200 unsigned n, c;
201 pa_memchunk tchunk;
202 pa_usec_t current_latency PA_GCC_UNUSED;
203
204 pa_sink_input_assert_ref(i);
205 pa_assert(chunk);
206 pa_assert_se(u = i->userdata);
207
208 /* Hmm, process any rewind request that might be queued up */
209 pa_sink_process_rewind(u->sink, 0);
210
211 /* (1) IF YOU NEED A FIXED BLOCK SIZE USE
212 * pa_memblockq_peek_fixed_size() HERE INSTEAD. NOTE THAT FILTERS
213 * WHICH CAN DEAL WITH DYNAMIC BLOCK SIZES ARE HIGHLY
214 * PREFERRED. */
215 while (pa_memblockq_peek(u->memblockq, &tchunk) < 0) {
216 pa_memchunk nchunk;
217
218 pa_sink_render(u->sink, nbytes, &nchunk);
219 pa_memblockq_push(u->memblockq, &nchunk);
220 pa_memblock_unref(nchunk.memblock);
221 }
222
223 /* (2) IF YOU NEED A FIXED BLOCK SIZE, THIS NEXT LINE IS NOT
224 * NECESSARY */
225 tchunk.length = PA_MIN(nbytes, tchunk.length);
226 pa_assert(tchunk.length > 0);
227
228 fs = pa_frame_size(&i->sample_spec);
229 n = (unsigned) (tchunk.length / fs);
230
231 pa_assert(n > 0);
232
233 chunk->index = 0;
234 chunk->length = n*fs;
235 chunk->memblock = pa_memblock_new(i->sink->core->mempool, chunk->length);
236
237 pa_memblockq_drop(u->memblockq, chunk->length);
238
239 src = pa_memblock_acquire_chunk(&tchunk);
240 dst = pa_memblock_acquire(chunk->memblock);
241
242 /* (3) PUT YOUR CODE HERE TO DO SOMETHING WITH THE DATA */
243
244 /* As an example, copy input to output */
245 for (c = 0; c < u->channels; c++) {
246 pa_sample_clamp(PA_SAMPLE_FLOAT32NE,
247 dst+c, u->channels * sizeof(float),
248 src+c, u->channels * sizeof(float),
249 n);
250 }
251
252 pa_memblock_release(tchunk.memblock);
253 pa_memblock_release(chunk->memblock);
254
255 pa_memblock_unref(tchunk.memblock);
256
257 /* (4) IF YOU NEED THE LATENCY FOR SOMETHING ACQUIRE IT LIKE THIS: */
258 current_latency =
259 /* Get the latency of the master sink */
260 pa_sink_get_latency_within_thread(i->sink) +
261
262 /* Add the latency internal to our sink input on top */
263 pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
264
265 return 0;
266 }
267
268 /* Called from I/O thread context */
269 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
270 struct userdata *u;
271 size_t amount = 0;
272
273 pa_sink_input_assert_ref(i);
274 pa_assert_se(u = i->userdata);
275
276 if (u->sink->thread_info.rewind_nbytes > 0) {
277 size_t max_rewrite;
278
279 max_rewrite = nbytes + pa_memblockq_get_length(u->memblockq);
280 amount = PA_MIN(u->sink->thread_info.rewind_nbytes, max_rewrite);
281 u->sink->thread_info.rewind_nbytes = 0;
282
283 if (amount > 0) {
284 pa_memblockq_seek(u->memblockq, - (int64_t) amount, PA_SEEK_RELATIVE, true);
285
286 /* (5) PUT YOUR CODE HERE TO RESET YOUR FILTER */
287 }
288 }
289
290 pa_sink_process_rewind(u->sink, amount);
291 pa_memblockq_rewind(u->memblockq, nbytes);
292 }
293
294 /* Called from I/O thread context */
295 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
296 struct userdata *u;
297
298 pa_sink_input_assert_ref(i);
299 pa_assert_se(u = i->userdata);
300
301 /* FIXME: Too small max_rewind:
302 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
303 pa_memblockq_set_maxrewind(u->memblockq, nbytes);
304 pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
305 }
306
307 /* Called from I/O thread context */
308 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
309 struct userdata *u;
310
311 pa_sink_input_assert_ref(i);
312 pa_assert_se(u = i->userdata);
313
314 /* (6) IF YOU NEED A FIXED BLOCK SIZE ROUND nbytes UP TO MULTIPLES
315 * OF IT HERE. THE PA_ROUND_UP MACRO IS USEFUL FOR THAT. */
316
317 pa_sink_set_max_request_within_thread(u->sink, nbytes);
318 }
319
320 /* Called from I/O thread context */
321 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
322 struct userdata *u;
323
324 pa_sink_input_assert_ref(i);
325 pa_assert_se(u = i->userdata);
326
327 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
328 }
329
330 /* Called from I/O thread context */
331 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
332 struct userdata *u;
333
334 pa_sink_input_assert_ref(i);
335 pa_assert_se(u = i->userdata);
336
337 /* (7) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
338 * BLOCK MINUS ONE SAMPLE HERE. pa_usec_to_bytes_round_up() IS
339 * USEFUL FOR THAT. */
340
341 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
342 }
343
344 /* Called from I/O thread context */
345 static void sink_input_detach_cb(pa_sink_input *i) {
346 struct userdata *u;
347
348 pa_sink_input_assert_ref(i);
349 pa_assert_se(u = i->userdata);
350
351 pa_sink_detach_within_thread(u->sink);
352
353 pa_sink_set_rtpoll(u->sink, NULL);
354 }
355
356 /* Called from I/O thread context */
357 static void sink_input_attach_cb(pa_sink_input *i) {
358 struct userdata *u;
359
360 pa_sink_input_assert_ref(i);
361 pa_assert_se(u = i->userdata);
362
363 pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
364 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
365
366 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
367 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
368 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
369
370 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
371 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
372 * HERE. SEE (6) */
373 pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
374
375 /* FIXME: Too small max_rewind:
376 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
377 pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
378
379 pa_sink_attach_within_thread(u->sink);
380 }
381
382 /* Called from main context */
383 static void sink_input_kill_cb(pa_sink_input *i) {
384 struct userdata *u;
385
386 pa_sink_input_assert_ref(i);
387 pa_assert_se(u = i->userdata);
388
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);
394
395 pa_sink_input_unref(u->sink_input);
396 u->sink_input = NULL;
397
398 pa_sink_unref(u->sink);
399 u->sink = NULL;
400
401 pa_module_unload_request(u->module, true);
402 }
403
404 /* Called from IO thread context */
405 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
406 struct userdata *u;
407
408 pa_sink_input_assert_ref(i);
409 pa_assert_se(u = i->userdata);
410
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);
417 }
418 }
419
420 /* Called from main context */
421 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
422 struct userdata *u;
423
424 pa_sink_input_assert_ref(i);
425 pa_assert_se(u = i->userdata);
426
427 if (dest) {
428 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
429 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
430 } else
431 pa_sink_set_asyncmsgq(u->sink, NULL);
432
433 if (u->auto_desc && dest) {
434 const char *z;
435 pa_proplist *pl;
436
437 pl = pa_proplist_new();
438 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
439 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s",
440 pa_proplist_gets(u->sink->proplist, "device.vsink.name"), z ? z : dest->name);
441
442 pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
443 pa_proplist_free(pl);
444 }
445 }
446
447 /* Called from main context */
448 static void sink_input_volume_changed_cb(pa_sink_input *i) {
449 struct userdata *u;
450
451 pa_sink_input_assert_ref(i);
452 pa_assert_se(u = i->userdata);
453
454 pa_sink_volume_changed(u->sink, &i->volume);
455 }
456
457 /* Called from main context */
458 static void sink_input_mute_changed_cb(pa_sink_input *i) {
459 struct userdata *u;
460
461 pa_sink_input_assert_ref(i);
462 pa_assert_se(u = i->userdata);
463
464 pa_sink_mute_changed(u->sink, i->muted);
465 }
466
467 int pa__init(pa_module*m) {
468 struct userdata *u;
469 pa_sample_spec ss;
470 pa_channel_map map;
471 pa_modargs *ma;
472 pa_sink *master=NULL;
473 pa_sink_input_new_data sink_input_data;
474 pa_sink_new_data sink_data;
475 bool use_volume_sharing = true;
476 bool force_flat_volume = false;
477 pa_memchunk silence;
478
479 pa_assert(m);
480
481 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
482 pa_log("Failed to parse module arguments.");
483 goto fail;
484 }
485
486 if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
487 pa_log("Master sink not found");
488 goto fail;
489 }
490
491 pa_assert(master);
492
493 ss = master->sample_spec;
494 ss.format = PA_SAMPLE_FLOAT32;
495 map = master->channel_map;
496 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
497 pa_log("Invalid sample format specification or channel map");
498 goto fail;
499 }
500
501 if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
502 pa_log("use_volume_sharing= expects a boolean argument");
503 goto fail;
504 }
505
506 if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) {
507 pa_log("force_flat_volume= expects a boolean argument");
508 goto fail;
509 }
510
511 if (use_volume_sharing && force_flat_volume) {
512 pa_log("Flat volume can't be forced when using volume sharing.");
513 goto fail;
514 }
515
516 u = pa_xnew0(struct userdata, 1);
517 u->module = m;
518 m->userdata = u;
519 u->channels = ss.channels;
520
521 /* Create sink */
522 pa_sink_new_data_init(&sink_data);
523 sink_data.driver = __FILE__;
524 sink_data.module = m;
525 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
526 sink_data.name = pa_sprintf_malloc("%s.vsink", master->name);
527 pa_sink_new_data_set_sample_spec(&sink_data, &ss);
528 pa_sink_new_data_set_channel_map(&sink_data, &map);
529 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
530 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
531 pa_proplist_sets(sink_data.proplist, "device.vsink.name", sink_data.name);
532
533 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
534 pa_log("Invalid properties");
535 pa_sink_new_data_done(&sink_data);
536 goto fail;
537 }
538
539 if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
540 const char *z;
541
542 z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
543 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s", sink_data.name, z ? z : master->name);
544 }
545
546 u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))
547 | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
548 pa_sink_new_data_done(&sink_data);
549
550 if (!u->sink) {
551 pa_log("Failed to create sink.");
552 goto fail;
553 }
554
555 u->sink->parent.process_msg = sink_process_msg_cb;
556 u->sink->set_state = sink_set_state_cb;
557 u->sink->update_requested_latency = sink_update_requested_latency_cb;
558 u->sink->request_rewind = sink_request_rewind_cb;
559 pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
560 if (!use_volume_sharing) {
561 pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
562 pa_sink_enable_decibel_volume(u->sink, true);
563 }
564 /* Normally this flag would be enabled automatically be we can force it. */
565 if (force_flat_volume)
566 u->sink->flags |= PA_SINK_FLAT_VOLUME;
567 u->sink->userdata = u;
568
569 pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
570
571 /* Create sink input */
572 pa_sink_input_new_data_init(&sink_input_data);
573 sink_input_data.driver = __FILE__;
574 sink_input_data.module = m;
575 pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
576 sink_input_data.origin_sink = u->sink;
577 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));
578 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
579 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
580 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
581
582 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
583 pa_sink_input_new_data_done(&sink_input_data);
584
585 if (!u->sink_input)
586 goto fail;
587
588 u->sink_input->pop = sink_input_pop_cb;
589 u->sink_input->process_rewind = sink_input_process_rewind_cb;
590 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
591 u->sink_input->update_max_request = sink_input_update_max_request_cb;
592 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
593 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
594 u->sink_input->kill = sink_input_kill_cb;
595 u->sink_input->attach = sink_input_attach_cb;
596 u->sink_input->detach = sink_input_detach_cb;
597 u->sink_input->state_change = sink_input_state_change_cb;
598 u->sink_input->moving = sink_input_moving_cb;
599 u->sink_input->volume_changed = use_volume_sharing ? NULL : sink_input_volume_changed_cb;
600 u->sink_input->mute_changed = sink_input_mute_changed_cb;
601 u->sink_input->userdata = u;
602
603 u->sink->input_to_master = u->sink_input;
604
605 pa_sink_input_get_silence(u->sink_input, &silence);
606 u->memblockq = pa_memblockq_new("module-virtual-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence);
607 pa_memblock_unref(silence.memblock);
608
609 /* (9) INITIALIZE ANYTHING ELSE YOU NEED HERE */
610
611 pa_sink_put(u->sink);
612 pa_sink_input_put(u->sink_input);
613
614 pa_modargs_free(ma);
615
616 return 0;
617
618 fail:
619 if (ma)
620 pa_modargs_free(ma);
621
622 pa__done(m);
623
624 return -1;
625 }
626
627 int pa__get_n_used(pa_module *m) {
628 struct userdata *u;
629
630 pa_assert(m);
631 pa_assert_se(u = m->userdata);
632
633 return pa_sink_linked_by(u->sink);
634 }
635
636 void pa__done(pa_module*m) {
637 struct userdata *u;
638
639 pa_assert(m);
640
641 if (!(u = m->userdata))
642 return;
643
644 /* See comments in sink_input_kill_cb() above regarding
645 * destruction order! */
646
647 if (u->sink_input)
648 pa_sink_input_unlink(u->sink_input);
649
650 if (u->sink)
651 pa_sink_unlink(u->sink);
652
653 if (u->sink_input)
654 pa_sink_input_unref(u->sink_input);
655
656 if (u->sink)
657 pa_sink_unref(u->sink);
658
659 if (u->memblockq)
660 pa_memblockq_free(u->memblockq);
661
662 pa_xfree(u);
663 }