virtual-sink/source: Remove an unused variable.
[profile/ivi/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
539     /* optional for uplink_sink */
540     pa_sink_new_data sink_data;
541     size_t nbytes;
542
543     pa_assert(m);
544
545     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
546         pa_log("Failed to parse module arguments.");
547         goto fail;
548     }
549
550     if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SOURCE))) {
551         pa_log("Master source not found");
552         goto fail;
553     }
554
555     pa_assert(master);
556
557     ss = master->sample_spec;
558     ss.format = PA_SAMPLE_FLOAT32;
559     map = master->channel_map;
560     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
561         pa_log("Invalid sample format specification or channel map");
562         goto fail;
563     }
564
565
566     u = pa_xnew0(struct userdata, 1);
567     if (!u) {
568         pa_log("Failed to alloc userdata");
569         goto fail;
570     }
571     u->module = m;
572     m->userdata = u;
573     u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
574     if (!u->memblockq) {
575         pa_log("Failed to create source memblockq.");
576         goto fail;
577     }
578     u->channels = ss.channels;
579
580     /* Create source */
581     pa_source_new_data_init(&source_data);
582     source_data.driver = __FILE__;
583     source_data.module = m;
584     if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
585         source_data.name = pa_sprintf_malloc("%s.vsource", master->name);
586     pa_source_new_data_set_sample_spec(&source_data, &ss);
587     pa_source_new_data_set_channel_map(&source_data, &map);
588     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
589     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
590     pa_proplist_sets(source_data.proplist, "device.vsource.name", source_data.name);
591
592     if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
593         pa_log("Invalid properties");
594         pa_source_new_data_done(&source_data);
595         goto fail;
596     }
597
598     if ((u->auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
599         const char *z;
600
601         z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
602         pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Source %s on %s", source_data.name, z ? z : master->name);
603     }
604
605     u->source = pa_source_new(m->core, &source_data,
606                           PA_SOURCE_HW_MUTE_CTRL|PA_SOURCE_HW_VOLUME_CTRL|PA_SOURCE_DECIBEL_VOLUME|
607                           (master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)));
608     pa_source_new_data_done(&source_data);
609
610     if (!u->source) {
611         pa_log("Failed to create source.");
612         goto fail;
613     }
614
615     u->source->parent.process_msg = source_process_msg_cb;
616     u->source->set_state = source_set_state_cb;
617     u->source->update_requested_latency = source_update_requested_latency_cb;
618     u->source->set_volume = source_set_volume_cb;
619     u->source->set_mute = source_set_mute_cb;
620     u->source->get_volume = source_get_volume_cb;
621     u->source->get_mute = source_get_mute_cb;
622     u->source->userdata = u;
623
624     pa_source_set_asyncmsgq(u->source, master->asyncmsgq);
625
626     /* Create source output */
627     pa_source_output_new_data_init(&source_output_data);
628     source_output_data.driver = __FILE__;
629     source_output_data.module = m;
630     source_output_data.source = master;
631     source_output_data.destination_source = u->source;
632     /* FIXME
633        source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */
634
635     pa_proplist_setf(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Source Stream of %s", pa_proplist_gets(u->source->proplist, PA_PROP_DEVICE_DESCRIPTION));
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     u->source->output_from_master = u->source_output;
658
659     pa_source_put(u->source);
660     pa_source_output_put(u->source_output);
661
662     /* Create optional uplink sink */
663     pa_sink_new_data_init(&sink_data);
664     sink_data.driver = __FILE__;
665     sink_data.module = m;
666     if ((sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "uplink_sink", NULL)))) {
667         pa_sink_new_data_set_sample_spec(&sink_data, &ss);
668         pa_sink_new_data_set_channel_map(&sink_data, &map);
669         pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
670         pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "uplink sink");
671         pa_proplist_sets(sink_data.proplist, "device.uplink_sink.name", sink_data.name);
672
673         if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
674             const char *z;
675
676             z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
677             pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Uplink Sink %s on %s", sink_data.name, z ? z : master->name);
678         }
679
680         u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
681         if (!u->sink_memblockq) {
682             pa_log("Failed to create sink memblockq.");
683             goto fail;
684         }
685
686         u->sink = pa_sink_new(m->core, &sink_data, 0);  /* FIXME, sink has no capabilities */
687         pa_sink_new_data_done(&sink_data);
688
689         if (!u->sink) {
690             pa_log("Failed to create sink.");
691             goto fail;
692         }
693
694         u->sink->parent.process_msg = sink_process_msg_cb;
695         u->sink->update_requested_latency = sink_update_requested_latency_cb;
696         u->sink->request_rewind = sink_request_rewind_cb;
697         u->sink->set_state = sink_set_state_cb;
698         u->sink->userdata = u;
699
700         pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
701
702         /* FIXME: no idea what I am doing here */
703         u->block_usec = BLOCK_USEC;
704         nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec);
705         pa_sink_set_max_rewind(u->sink, nbytes);
706         pa_sink_set_max_request(u->sink, nbytes);
707
708         pa_sink_put(u->sink);
709     } else {
710         /* optional uplink sink not enabled */
711         u->sink = NULL;
712     }
713
714     pa_modargs_free(ma);
715
716     return 0;
717
718  fail:
719     if (ma)
720         pa_modargs_free(ma);
721
722     pa__done(m);
723
724     return -1;
725 }
726
727 int pa__get_n_used(pa_module *m) {
728     struct userdata *u;
729
730     pa_assert(m);
731     pa_assert_se(u = m->userdata);
732
733     return pa_source_linked_by(u->source);
734 }
735
736 void pa__done(pa_module*m) {
737     struct userdata *u;
738
739     pa_assert(m);
740
741     if (!(u = m->userdata))
742         return;
743
744     /* See comments in source_output_kill_cb() above regarding
745      * destruction order! */
746
747     if (u->source_output)
748         pa_source_output_unlink(u->source_output);
749
750     if (u->source)
751         pa_source_unlink(u->source);
752
753     if (u->source_output)
754         pa_source_output_unref(u->source_output);
755
756     if (u->source)
757         pa_source_unref(u->source);
758
759     if (u->sink)
760         pa_sink_unref(u->sink);
761
762     if (u->memblockq)
763         pa_memblockq_free(u->memblockq);
764
765     if (u->sink_memblockq)
766          pa_memblockq_free(u->sink_memblockq);
767
768     pa_xfree(u);
769 }