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