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