Git init
[framework/multimedia/pulseaudio.git] / src / modules / module-virtual-source.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 <stdio.h>
28 #include <math.h>
29
30 #include <pulse/xmalloc.h>
31 #include <pulse/i18n.h>
32
33 #include <pulsecore/macro.h>
34 #include <pulsecore/core-error.h>
35 #include <pulsecore/namereg.h>
36 #include <pulsecore/sink.h>
37 #include <pulsecore/module.h>
38 #include <pulsecore/core-rtclock.h>
39 #include <pulsecore/core-util.h>
40 #include <pulsecore/core-error.h>
41 #include <pulsecore/modargs.h>
42 #include <pulsecore/log.h>
43 #include <pulsecore/thread.h>
44 #include <pulsecore/thread-mq.h>
45 #include <pulsecore/rtpoll.h>
46 #include <pulsecore/sample-util.h>
47 #include <pulsecore/ltdl-helper.h>
48
49 #include "module-virtual-source-symdef.h"
50
51 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
52 PA_MODULE_DESCRIPTION("Virtual source");
53 PA_MODULE_VERSION(PACKAGE_VERSION);
54 PA_MODULE_LOAD_ONCE(FALSE);
55 PA_MODULE_USAGE(
56         _("source_name=<name for the source> "
57           "source_properties=<properties for the source> "
58           "master=<name of source to filter> "
59           "uplink_sink=<name> (optional)"
60           "format=<sample format> "
61           "rate=<sample rate> "
62           "channels=<number of channels> "
63           "channel_map=<channel map> "
64         ));
65
66 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
67 #define BLOCK_USEC 1000 /* FIXME */
68
69 struct userdata {
70     pa_module *module;
71
72     pa_source *source;
73     pa_source_output *source_output;
74
75     pa_memblockq *memblockq;
76
77     pa_bool_t auto_desc;
78     unsigned channels;
79
80     /* optional fields for uplink sink */
81     pa_sink *sink;
82     pa_usec_t block_usec;
83     pa_memblockq *sink_memblockq;
84
85 };
86
87 static const char* const valid_modargs[] = {
88     "source_name",
89     "source_properties",
90     "master",
91     "uplink_sink",
92     "format",
93     "rate",
94     "channels",
95     "channel_map",
96     NULL
97 };
98
99 /* Called from I/O thread context */
100 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
101
102     switch (code) {
103
104         case PA_SINK_MESSAGE_GET_LATENCY:
105
106             /* there's no real latency here */
107             *((pa_usec_t*) data) = 0;
108
109             return 0;
110     }
111
112     return pa_sink_process_msg(o, code, data, offset, chunk);
113 }
114
115 /* Called from main context */
116 static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
117     struct userdata *u;
118
119     pa_sink_assert_ref(s);
120     pa_assert_se(u = s->userdata);
121
122     if (!PA_SINK_IS_LINKED(state)) {
123         return 0;
124     }
125
126     if (state == PA_SINK_RUNNING) {
127         /* need to wake-up source if it was suspended */
128         pa_source_suspend(u->source, FALSE, PA_SUSPEND_ALL);
129
130         /* FIXME: if there's no client connected, the source will suspend
131            and playback will be stuck. You'd want to prevent the source from
132            sleeping when the uplink sink is active; even if the audio is
133            discarded at least the app isn't stuck */
134
135     } else {
136         /* nothing to do, if the sink becomes idle or suspended let
137            module-suspend-idle handle the sources later */
138     }
139
140     return 0;
141 }
142
143 static void sink_update_requested_latency_cb(pa_sink *s) {
144     struct userdata *u;
145
146     pa_sink_assert_ref(s);
147     pa_assert_se(u = s->userdata);
148
149     /* FIXME: there's no latency support */
150
151 }
152
153
154 /* Called from I/O thread context */
155 static void sink_request_rewind_cb(pa_sink *s) {
156     struct userdata *u;
157
158     pa_sink_assert_ref(s);
159     pa_assert_se(u = s->userdata);
160
161     /* Do nothing */
162     pa_sink_process_rewind(u->sink, 0);
163
164 }
165
166 /* Called from I/O thread context */
167 static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
168     struct userdata *u = PA_SOURCE(o)->userdata;
169
170     switch (code) {
171
172         case PA_SOURCE_MESSAGE_GET_LATENCY:
173
174             /* The source is _put() before the source output is, so let's
175              * make sure we don't access it in that time. Also, the
176              * source output is first shut down, the source second. */
177             if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
178                 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) {
179                 *((pa_usec_t*) data) = 0;
180                 return 0;
181             }
182
183             *((pa_usec_t*) data) =
184
185                 /* Get the latency of the master source */
186                 pa_source_get_latency_within_thread(u->source_output->source) +
187
188                 /* Add the latency internal to our source output on top */
189                 /* FIXME, no idea what I am doing here */
190                 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec);
191
192             return 0;
193     }
194
195     return pa_source_process_msg(o, code, data, offset, chunk);
196 }
197
198 /* Called from main context */
199 static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
200     struct userdata *u;
201
202     pa_source_assert_ref(s);
203     pa_assert_se(u = s->userdata);
204
205     if (!PA_SOURCE_IS_LINKED(state) ||
206         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
207         return 0;
208
209     pa_source_output_cork(u->source_output, state == PA_SOURCE_SUSPENDED);
210     return 0;
211 }
212
213 /* Called from I/O thread context */
214 static void source_update_requested_latency_cb(pa_source *s) {
215     struct userdata *u;
216
217     pa_source_assert_ref(s);
218     pa_assert_se(u = s->userdata);
219
220     if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
221         !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state))
222         return;
223
224     /* Just hand this one over to the master source */
225     pa_source_output_set_requested_latency_within_thread(
226             u->source_output,
227             pa_source_get_requested_latency_within_thread(s));
228 }
229
230 /* Called from main context */
231 static void source_set_volume_cb(pa_source *s) {
232     struct userdata *u;
233
234     pa_source_assert_ref(s);
235     pa_assert_se(u = s->userdata);
236
237     if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
238         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
239         return;
240
241     /* FIXME, no volume control in source_output, set volume at the master */
242     pa_source_set_volume(u->source_output->source, &s->volume, TRUE);
243 }
244
245 static void source_get_volume_cb(pa_source *s) {
246     struct userdata *u;
247
248     pa_source_assert_ref(s);
249     pa_assert_se(u = s->userdata);
250
251     if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
252         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
253         return;
254
255     /* FIXME, no volume control in source_output, get the info from the master */
256     pa_source_get_volume(u->source_output->source, TRUE);
257
258     if (pa_cvolume_equal(&s->volume,&u->source_output->source->volume))
259         /* no change */
260         return;
261
262     s->volume = u->source_output->source->volume;
263     pa_source_set_soft_volume(s, NULL);
264 }
265
266
267 /* Called from main context */
268 static void source_set_mute_cb(pa_source *s) {
269     struct userdata *u;
270
271     pa_source_assert_ref(s);
272     pa_assert_se(u = s->userdata);
273
274     if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
275         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
276         return;
277
278     /* FIXME, no volume control in source_output, set mute at the master */
279     pa_source_set_mute(u->source_output->source, TRUE, TRUE);
280 }
281
282 /* Called from main context */
283 static void source_get_mute_cb(pa_source *s) {
284     struct userdata *u;
285
286     pa_source_assert_ref(s);
287     pa_assert_se(u = s->userdata);
288
289     if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
290         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
291         return;
292
293     /* FIXME, no volume control in source_output, get the info from the master */
294     pa_source_get_mute(u->source_output->source, TRUE);
295 }
296
297 /* Called from input thread context */
298 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
299     struct userdata *u;
300
301     pa_source_output_assert_ref(o);
302     pa_source_output_assert_io_context(o);
303     pa_assert_se(u = o->userdata);
304
305     if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) {
306         pa_log("push when no link?");
307         return;
308     }
309
310     /* PUT YOUR CODE HERE TO DO SOMETHING WITH THE SOURCE DATA */
311
312     /* if uplink sink exists, pull data from there; simplify by using
313        same length as chunk provided by source */
314     if(u->sink && (pa_sink_get_state(u->sink) == PA_SINK_RUNNING)) {
315         pa_memchunk tchunk;
316         size_t nbytes = chunk->length;
317         pa_mix_info streams[2];
318         pa_memchunk target_chunk;
319         void *target;
320         int ch;
321
322         /* Hmm, process any rewind request that might be queued up */
323         pa_sink_process_rewind(u->sink, 0);
324
325         /* get data from the sink */
326         while (pa_memblockq_peek(u->sink_memblockq, &tchunk) < 0) {
327             pa_memchunk nchunk;
328
329             /* make sure we get nbytes from the sink with render_full,
330                otherwise we cannot mix with the uplink */
331             pa_sink_render_full(u->sink, nbytes, &nchunk);
332             pa_memblockq_push(u->sink_memblockq, &nchunk);
333             pa_memblock_unref(nchunk.memblock);
334         }
335         pa_assert(tchunk.length == chunk->length);
336
337         /* move the read pointer for sink memblockq */
338         pa_memblockq_drop(u->sink_memblockq, tchunk.length);
339
340         /* allocate target chunk */
341         /* this could probably be done in-place, but having chunk as both
342            the input and output creates issues with reference counts */
343         target_chunk.index = 0;
344         target_chunk.length = chunk->length;
345         pa_assert(target_chunk.length == chunk->length);
346
347         target_chunk.memblock = pa_memblock_new(o->source->core->mempool,
348                                                 target_chunk.length);
349         pa_assert( target_chunk.memblock );
350
351         /* get target pointer */
352         target = (void*)((uint8_t*)pa_memblock_acquire(target_chunk.memblock)
353                          + target_chunk.index);
354
355         /* set-up mixing structure
356            volume was taken care of in sink and source already */
357         streams[0].chunk = *chunk;
358         for(ch=0;ch<o->sample_spec.channels;ch++)
359             streams[0].volume.values[ch] = PA_VOLUME_NORM; /* FIXME */
360         streams[0].volume.channels = o->sample_spec.channels;
361
362         streams[1].chunk = tchunk;
363         for(ch=0;ch<o->sample_spec.channels;ch++)
364             streams[1].volume.values[ch] = PA_VOLUME_NORM; /* FIXME */
365         streams[1].volume.channels = o->sample_spec.channels;
366
367         /* do mixing */
368         pa_mix(streams,                /* 2 streams to be mixed */
369                2,
370                target,                 /* put result in target chunk */
371                chunk->length,          /* same length as input */
372                (const pa_sample_spec *)&o->sample_spec, /* same sample spec for input and output */
373                NULL,                   /* no volume information */
374                FALSE);                 /* no mute */
375
376         pa_memblock_release(target_chunk.memblock);
377         pa_memblock_unref(tchunk.memblock); /* clean-up */
378
379         /* forward the data to the virtual source */
380         pa_source_post(u->source, &target_chunk);
381
382         pa_memblock_unref(target_chunk.memblock); /* clean-up */
383
384     } else {
385         /* forward the data to the virtual source */
386         pa_source_post(u->source, chunk);
387     }
388
389
390 }
391
392 /* Called from input thread context */
393 static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
394     struct userdata *u;
395
396     pa_source_output_assert_ref(o);
397     pa_source_output_assert_io_context(o);
398     pa_assert_se(u = o->userdata);
399
400     /* FIXME, no idea what I am doing here */
401 #if 0
402     pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_REWIND, NULL, (int64_t) nbytes, NULL, NULL);
403     u->send_counter -= (int64_t) nbytes;
404 #endif
405 }
406
407 /* Called from output thread context */
408 static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
409
410     /* FIXME, nothing to do here ? */
411
412     return pa_source_output_process_msg(obj, code, data, offset, chunk);
413 }
414
415 /* Called from output thread context */
416 static void source_output_attach_cb(pa_source_output *o) {
417     struct userdata *u;
418
419     pa_source_output_assert_ref(o);
420     pa_source_output_assert_io_context(o);
421     pa_assert_se(u = o->userdata);
422
423     pa_source_set_rtpoll(u->source, o->source->thread_info.rtpoll);
424     pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
425     pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
426     pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
427
428     pa_source_attach_within_thread(u->source);
429 }
430
431 /* Called from output thread context */
432 static void source_output_detach_cb(pa_source_output *o) {
433     struct userdata *u;
434
435     pa_source_output_assert_ref(o);
436     pa_source_output_assert_io_context(o);
437     pa_assert_se(u = o->userdata);
438
439     pa_source_detach_within_thread(u->source);
440     pa_source_set_rtpoll(u->source, NULL);
441 }
442
443 /* Called from output thread context */
444 static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
445     struct userdata *u;
446
447     pa_source_output_assert_ref(o);
448     pa_source_output_assert_io_context(o);
449     pa_assert_se(u = o->userdata);
450
451     /* FIXME */
452 #if 0
453     if (PA_SOURCE_OUTPUT_IS_LINKED(state) && o->thread_info.state == PA_SOURCE_OUTPUT_INIT) {
454
455         u->skip = pa_usec_to_bytes(PA_CLIP_SUB(pa_source_get_latency_within_thread(o->source),
456                                                u->latency),
457                                    &o->sample_spec);
458
459         pa_log_info("Skipping %lu bytes", (unsigned long) u->skip);
460     }
461 #endif
462 }
463
464 /* Called from main thread */
465 static void source_output_kill_cb(pa_source_output *o) {
466     struct userdata *u;
467
468     pa_source_output_assert_ref(o);
469     pa_assert_ctl_context();
470     pa_assert_se(u = o->userdata);
471
472     /* The order here matters! We first kill the source output, followed
473      * by the source. That means the source callbacks must be protected
474      * against an unconnected source output! */
475     pa_source_output_unlink(u->source_output);
476     pa_source_unlink(u->source);
477
478     pa_source_output_unref(u->source_output);
479     u->source_output = NULL;
480
481     pa_source_unref(u->source);
482     u->source = NULL;
483
484     pa_module_unload_request(u->module, TRUE);
485 }
486
487 /* Called from main thread */
488 static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
489     struct userdata *u;
490
491     pa_source_output_assert_ref(o);
492     pa_assert_ctl_context();
493     pa_assert_se(u = o->userdata);
494
495     /* FIXME */
496     //return dest != u->source_input->source->monitor_source;
497
498     return TRUE;
499 }
500
501 /* Called from main thread */
502 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
503     struct userdata *u;
504
505     pa_source_output_assert_ref(o);
506     pa_assert_ctl_context();
507     pa_assert_se(u = o->userdata);
508
509     if (dest) {
510         pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
511         pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
512     } else
513         pa_source_set_asyncmsgq(u->source, NULL);
514
515     if (u->auto_desc && dest) {
516         const char *z;
517         pa_proplist *pl;
518
519         pl = pa_proplist_new();
520         z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
521         pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Virtual Source %s on %s",
522                          pa_proplist_gets(u->source->proplist, "device.vsource.name"), z ? z : dest->name);
523
524         pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
525         pa_proplist_free(pl);
526     }
527 }
528
529
530 int pa__init(pa_module*m) {
531     struct userdata *u;
532     pa_sample_spec ss;
533     pa_channel_map map;
534     pa_modargs *ma;
535     pa_source *master=NULL;
536     pa_source_output_new_data source_output_data;
537     pa_source_new_data source_data;
538     pa_bool_t *use_default = NULL;
539
540     /* optional for uplink_sink */
541     pa_sink_new_data sink_data;
542     size_t nbytes;
543
544     pa_assert(m);
545
546     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
547         pa_log("Failed to parse module arguments.");
548         goto fail;
549     }
550
551     if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SOURCE))) {
552         pa_log("Master source not found");
553         goto fail;
554     }
555
556     pa_assert(master);
557
558     ss = master->sample_spec;
559     ss.format = PA_SAMPLE_FLOAT32;
560     map = master->channel_map;
561     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
562         pa_log("Invalid sample format specification or channel map");
563         goto fail;
564     }
565
566
567     u = pa_xnew0(struct userdata, 1);
568     if (!u) {
569         pa_log("Failed to alloc userdata");
570         goto fail;
571     }
572     u->module = m;
573     m->userdata = u;
574     u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
575     if (!u->memblockq) {
576         pa_log("Failed to create source memblockq.");
577         goto fail;
578     }
579     u->channels = ss.channels;
580
581     /* Create source */
582     pa_source_new_data_init(&source_data);
583     source_data.driver = __FILE__;
584     source_data.module = m;
585     if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
586         source_data.name = pa_sprintf_malloc("%s.vsource", master->name);
587     pa_source_new_data_set_sample_spec(&source_data, &ss);
588     pa_source_new_data_set_channel_map(&source_data, &map);
589     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
590     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
591     pa_proplist_sets(source_data.proplist, "device.vsource.name", source_data.name);
592
593     if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
594         pa_log("Invalid properties");
595         pa_source_new_data_done(&source_data);
596         goto fail;
597     }
598
599     if ((u->auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
600         const char *z;
601
602         z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
603         pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Source %s on %s", source_data.name, z ? z : master->name);
604     }
605
606     u->source = pa_source_new(m->core, &source_data,
607                           PA_SOURCE_HW_MUTE_CTRL|PA_SOURCE_HW_VOLUME_CTRL|PA_SOURCE_DECIBEL_VOLUME|
608                           (master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)));
609     pa_source_new_data_done(&source_data);
610
611     if (!u->source) {
612         pa_log("Failed to create source.");
613         goto fail;
614     }
615
616     u->source->parent.process_msg = source_process_msg_cb;
617     u->source->set_state = source_set_state_cb;
618     u->source->update_requested_latency = source_update_requested_latency_cb;
619     u->source->set_volume = source_set_volume_cb;
620     u->source->set_mute = source_set_mute_cb;
621     u->source->get_volume = source_get_volume_cb;
622     u->source->get_mute = source_get_mute_cb;
623     u->source->userdata = u;
624
625     pa_source_set_asyncmsgq(u->source, master->asyncmsgq);
626
627     /* Create source output */
628     pa_source_output_new_data_init(&source_output_data);
629     source_output_data.driver = __FILE__;
630     source_output_data.module = m;
631     source_output_data.source = master;
632     /* FIXME
633        source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */
634
635     pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Source Stream");
636     pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
637     pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
638     pa_source_output_new_data_set_channel_map(&source_output_data, &map);
639
640     pa_source_output_new(&u->source_output, m->core, &source_output_data);
641     pa_source_output_new_data_done(&source_output_data);
642
643     if (!u->source_output)
644         goto fail;
645
646     u->source_output->parent.process_msg = source_output_process_msg_cb;
647     u->source_output->push = source_output_push_cb;
648     u->source_output->process_rewind = source_output_process_rewind_cb;
649     u->source_output->kill = source_output_kill_cb;
650     u->source_output->attach = source_output_attach_cb;
651     u->source_output->detach = source_output_detach_cb;
652     u->source_output->state_change = source_output_state_change_cb;
653     u->source_output->may_move_to = source_output_may_move_to_cb;
654     u->source_output->moving = source_output_moving_cb;
655     u->source_output->userdata = u;
656
657     pa_source_put(u->source);
658     pa_source_output_put(u->source_output);
659
660     /* Create optional uplink sink */
661     pa_sink_new_data_init(&sink_data);
662     sink_data.driver = __FILE__;
663     sink_data.module = m;
664     if ((sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "uplink_sink", NULL)))) {
665         pa_sink_new_data_set_sample_spec(&sink_data, &ss);
666         pa_sink_new_data_set_channel_map(&sink_data, &map);
667         pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
668         pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "uplink sink");
669         pa_proplist_sets(sink_data.proplist, "device.uplink_sink.name", sink_data.name);
670
671         if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
672             const char *z;
673
674             z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
675             pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Uplink Sink %s on %s", sink_data.name, z ? z : master->name);
676         }
677
678         u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
679         if (!u->sink_memblockq) {
680             pa_log("Failed to create sink memblockq.");
681             goto fail;
682         }
683
684         u->sink = pa_sink_new(m->core, &sink_data, 0);  /* FIXME, sink has no capabilities */
685         pa_sink_new_data_done(&sink_data);
686
687         if (!u->sink) {
688             pa_log("Failed to create sink.");
689             goto fail;
690         }
691
692         u->sink->parent.process_msg = sink_process_msg_cb;
693         u->sink->update_requested_latency = sink_update_requested_latency_cb;
694         u->sink->request_rewind = sink_request_rewind_cb;
695         u->sink->set_state = sink_set_state_cb;
696         u->sink->userdata = u;
697
698         pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
699
700         /* FIXME: no idea what I am doing here */
701         u->block_usec = BLOCK_USEC;
702         nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec);
703         pa_sink_set_max_rewind(u->sink, nbytes);
704         pa_sink_set_max_request(u->sink, nbytes);
705
706         pa_sink_put(u->sink);
707     } else {
708         /* optional uplink sink not enabled */
709         u->sink = NULL;
710     }
711
712     pa_modargs_free(ma);
713
714     pa_xfree(use_default);
715
716     return 0;
717
718  fail:
719     if (ma)
720         pa_modargs_free(ma);
721
722     pa_xfree(use_default);
723
724     pa__done(m);
725
726     return -1;
727 }
728
729 int pa__get_n_used(pa_module *m) {
730     struct userdata *u;
731
732     pa_assert(m);
733     pa_assert_se(u = m->userdata);
734
735     return pa_source_linked_by(u->source);
736 }
737
738 void pa__done(pa_module*m) {
739     struct userdata *u;
740
741     pa_assert(m);
742
743     if (!(u = m->userdata))
744         return;
745
746     /* See comments in source_output_kill_cb() above regarding
747      * destruction order! */
748
749     if (u->source_output)
750         pa_source_output_unlink(u->source_output);
751
752     if (u->source)
753         pa_source_unlink(u->source);
754
755     if (u->source_output)
756         pa_source_output_unref(u->source_output);
757
758     if (u->source)
759         pa_source_unref(u->source);
760
761     if (u->sink)
762         pa_sink_unref(u->sink);
763
764     if (u->memblockq)
765         pa_memblockq_free(u->memblockq);
766
767     if (u->sink_memblockq)
768          pa_memblockq_free(u->sink_memblockq);
769
770     pa_xfree(u);
771 }