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