esd,simple: use pa_memblockq_pop_missing()
[pulseaudio-mirror.git] / src / modules / module-virtual-sink.c
blob4fe4867e352269bb023e4f8f3a383a3f847db5be
1 /***
2 This file is part of PulseAudio.
4 Copyright 2010 Intel Corporation
5 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
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.
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.
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 ***/
23 /* TODO: Some plugins cause latency, and some even report it by using a control
24 out port. We don't currently use the latency information. */
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include <pulse/xmalloc.h>
31 #include <pulse/i18n.h>
33 #include <pulsecore/core-error.h>
34 #include <pulsecore/namereg.h>
35 #include <pulsecore/sink.h>
36 #include <pulsecore/module.h>
37 #include <pulsecore/core-util.h>
38 #include <pulsecore/modargs.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/thread.h>
41 #include <pulsecore/thread-mq.h>
42 #include <pulsecore/rtpoll.h>
43 #include <pulsecore/sample-util.h>
44 #include <pulsecore/ltdl-helper.h>
46 #include "module-virtual-sink-symdef.h"
48 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
49 PA_MODULE_DESCRIPTION(_("Virtual sink"));
50 PA_MODULE_VERSION(PACKAGE_VERSION);
51 PA_MODULE_LOAD_ONCE(FALSE);
52 PA_MODULE_USAGE(
53 _("sink_name=<name for the sink> "
54 "sink_properties=<properties for the sink> "
55 "master=<name of sink to filter> "
56 "format=<sample format> "
57 "rate=<sample rate> "
58 "channels=<number of channels> "
59 "channel_map=<channel map> "
60 ));
62 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
64 struct userdata {
65 pa_module *module;
67 pa_sink *sink;
68 pa_sink_input *sink_input;
70 pa_memblockq *memblockq;
72 pa_bool_t auto_desc;
73 unsigned channels;
76 static const char* const valid_modargs[] = {
77 "sink_name",
78 "sink_properties",
79 "master",
80 "format",
81 "rate",
82 "channels",
83 "channel_map",
84 NULL
87 /* Called from I/O thread context */
88 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
89 struct userdata *u = PA_SINK(o)->userdata;
91 switch (code) {
93 case PA_SINK_MESSAGE_GET_LATENCY:
95 /* The sink is _put() before the sink input is, so let's
96 * make sure we don't access it in that time. Also, the
97 * sink input is first shut down, the sink second. */
98 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
99 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
100 *((pa_usec_t*) data) = 0;
101 return 0;
104 *((pa_usec_t*) data) =
106 /* Get the latency of the master sink */
107 pa_sink_get_latency_within_thread(u->sink_input->sink) +
109 /* Add the latency internal to our sink input on top */
110 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
112 return 0;
115 return pa_sink_process_msg(o, code, data, offset, chunk);
118 /* Called from main context */
119 static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
120 struct userdata *u;
122 pa_sink_assert_ref(s);
123 pa_assert_se(u = s->userdata);
125 if (!PA_SINK_IS_LINKED(state) ||
126 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
127 return 0;
129 pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
130 return 0;
133 /* Called from I/O thread context */
134 static void sink_request_rewind_cb(pa_sink *s) {
135 struct userdata *u;
137 pa_sink_assert_ref(s);
138 pa_assert_se(u = s->userdata);
140 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
141 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
142 return;
144 /* Just hand this one over to the master sink */
145 pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes + pa_memblockq_get_length(u->memblockq), TRUE, FALSE, FALSE);
148 /* Called from I/O thread context */
149 static void sink_update_requested_latency_cb(pa_sink *s) {
150 struct userdata *u;
152 pa_sink_assert_ref(s);
153 pa_assert_se(u = s->userdata);
155 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
156 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
157 return;
159 /* Just hand this one over to the master sink */
160 pa_sink_input_set_requested_latency_within_thread(
161 u->sink_input,
162 pa_sink_get_requested_latency_within_thread(s));
165 /* Called from main context */
166 static void sink_set_volume_cb(pa_sink *s) {
167 struct userdata *u;
169 pa_sink_assert_ref(s);
170 pa_assert_se(u = s->userdata);
172 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
173 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
174 return;
176 pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
179 /* Called from main context */
180 static void sink_set_mute_cb(pa_sink *s) {
181 struct userdata *u;
183 pa_sink_assert_ref(s);
184 pa_assert_se(u = s->userdata);
186 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
187 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
188 return;
190 pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
193 /* Called from I/O thread context */
194 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
195 struct userdata *u;
196 float *src, *dst;
197 size_t fs;
198 unsigned n, c;
199 pa_memchunk tchunk;
200 pa_usec_t curr_latency;
202 pa_sink_input_assert_ref(i);
203 pa_assert(chunk);
204 pa_assert_se(u = i->userdata);
206 /* Hmm, process any rewind request that might be queued up */
207 pa_sink_process_rewind(u->sink, 0);
209 while (pa_memblockq_peek(u->memblockq, &tchunk) < 0) {
210 pa_memchunk nchunk;
212 pa_sink_render(u->sink, nbytes, &nchunk);
213 pa_memblockq_push(u->memblockq, &nchunk);
214 pa_memblock_unref(nchunk.memblock);
217 tchunk.length = PA_MIN(nbytes, tchunk.length);
218 pa_assert(tchunk.length > 0);
220 fs = pa_frame_size(&i->sample_spec);
221 //n = (unsigned) (PA_MIN(tchunk.length, u->block_size) / fs);
222 n = (unsigned) (tchunk.length / fs);
224 pa_assert(n > 0);
226 chunk->index = 0;
227 chunk->length = n*fs;
228 chunk->memblock = pa_memblock_new(i->sink->core->mempool, chunk->length);
229 pa_assert( chunk->memblock );
231 pa_memblockq_drop(u->memblockq, chunk->length);
233 src = (float*) ((uint8_t*) pa_memblock_acquire(tchunk.memblock) + tchunk.index);
234 dst = (float*) pa_memblock_acquire(chunk->memblock);
236 /* PUT YOUR CODE HERE TO DO SOMETHING WITH THE DATA */
237 /* example, copy input to output */
238 for (c = 0; c < u->channels; c++) {
239 pa_sample_clamp(PA_SAMPLE_FLOAT32NE,dst+c, u->channels*sizeof(float),
240 src+c, u->channels*sizeof(float),n);
242 pa_memblock_release(tchunk.memblock);
243 pa_memblock_release(chunk->memblock);
245 pa_memblock_unref(tchunk.memblock);
248 curr_latency =
249 /* Get the latency of the master sink */
250 pa_sink_get_latency_within_thread(i->sink) +
252 /* Add the latency internal to our sink input on top */
253 pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
255 /* FIXME: do something with the latency */
258 return 0;
261 /* Called from I/O thread context */
262 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
263 struct userdata *u;
264 size_t amount = 0;
266 pa_sink_input_assert_ref(i);
267 pa_assert_se(u = i->userdata);
269 if (u->sink->thread_info.rewind_nbytes > 0) {
270 size_t max_rewrite;
272 max_rewrite = nbytes + pa_memblockq_get_length(u->memblockq);
273 amount = PA_MIN(u->sink->thread_info.rewind_nbytes, max_rewrite);
274 u->sink->thread_info.rewind_nbytes = 0;
276 if (amount > 0) {
277 pa_memblockq_seek(u->memblockq, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
278 /* NEED TO RESET POST-PROCESSING HERE */
283 pa_sink_process_rewind(u->sink, amount);
284 pa_memblockq_rewind(u->memblockq, nbytes);
287 /* Called from I/O thread context */
288 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
289 struct userdata *u;
291 pa_sink_input_assert_ref(i);
292 pa_assert_se(u = i->userdata);
294 pa_memblockq_set_maxrewind(u->memblockq, nbytes);
295 pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
298 /* Called from I/O thread context */
299 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
300 struct userdata *u;
302 pa_sink_input_assert_ref(i);
303 pa_assert_se(u = i->userdata);
305 pa_sink_set_max_request_within_thread(u->sink, nbytes);
308 /* Called from I/O thread context */
309 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
310 struct userdata *u;
312 pa_sink_input_assert_ref(i);
313 pa_assert_se(u = i->userdata);
315 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
318 /* Called from I/O thread context */
319 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
320 struct userdata *u;
322 pa_sink_input_assert_ref(i);
323 pa_assert_se(u = i->userdata);
325 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
328 /* Called from I/O thread context */
329 static void sink_input_detach_cb(pa_sink_input *i) {
330 struct userdata *u;
332 pa_sink_input_assert_ref(i);
333 pa_assert_se(u = i->userdata);
335 pa_sink_detach_within_thread(u->sink);
337 pa_sink_set_rtpoll(u->sink, NULL);
340 /* Called from I/O thread context */
341 static void sink_input_attach_cb(pa_sink_input *i) {
342 struct userdata *u;
344 pa_sink_input_assert_ref(i);
345 pa_assert_se(u = i->userdata);
347 pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
348 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
349 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
350 pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
351 pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
353 pa_sink_attach_within_thread(u->sink);
356 /* Called from main context */
357 static void sink_input_kill_cb(pa_sink_input *i) {
358 struct userdata *u;
360 pa_sink_input_assert_ref(i);
361 pa_assert_se(u = i->userdata);
363 /* The order here matters! We first kill the sink input, followed
364 * by the sink. That means the sink callbacks must be protected
365 * against an unconnected sink input! */
366 pa_sink_input_unlink(u->sink_input);
367 pa_sink_unlink(u->sink);
369 pa_sink_input_unref(u->sink_input);
370 u->sink_input = NULL;
372 pa_sink_unref(u->sink);
373 u->sink = NULL;
375 pa_module_unload_request(u->module, TRUE);
378 /* Called from IO thread context */
379 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
380 struct userdata *u;
382 pa_sink_input_assert_ref(i);
383 pa_assert_se(u = i->userdata);
385 /* If we are added for the first time, ask for a rewinding so that
386 * we are heard right-away. */
387 if (PA_SINK_INPUT_IS_LINKED(state) &&
388 i->thread_info.state == PA_SINK_INPUT_INIT) {
389 pa_log_debug("Requesting rewind due to state change.");
390 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
394 /* Called from main context */
395 static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
396 struct userdata *u;
398 pa_sink_input_assert_ref(i);
399 pa_assert_se(u = i->userdata);
401 return u->sink != dest;
404 /* Called from main context */
405 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
406 struct userdata *u;
408 pa_sink_input_assert_ref(i);
409 pa_assert_se(u = i->userdata);
411 if (dest) {
412 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
413 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
414 } else
415 pa_sink_set_asyncmsgq(u->sink, NULL);
417 if (u->auto_desc && dest) {
418 const char *z;
419 pa_proplist *pl;
421 pl = pa_proplist_new();
422 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
423 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s",
424 pa_proplist_gets(u->sink->proplist, "device.vsink.name"), z ? z : dest->name);
426 pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
427 pa_proplist_free(pl);
431 /* Called from main context */
432 static void sink_input_volume_changed_cb(pa_sink_input *i) {
433 struct userdata *u;
435 pa_sink_input_assert_ref(i);
436 pa_assert_se(u = i->userdata);
438 pa_sink_volume_changed(u->sink, &i->volume);
441 /* Called from main context */
442 static void sink_input_mute_changed_cb(pa_sink_input *i) {
443 struct userdata *u;
445 pa_sink_input_assert_ref(i);
446 pa_assert_se(u = i->userdata);
448 pa_sink_mute_changed(u->sink, i->muted);
451 int pa__init(pa_module*m) {
452 struct userdata *u;
453 pa_sample_spec ss;
454 pa_channel_map map;
455 pa_modargs *ma;
456 pa_sink *master=NULL;
457 pa_sink_input_new_data sink_input_data;
458 pa_sink_new_data sink_data;
459 pa_bool_t *use_default = NULL;
461 pa_assert(m);
463 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
464 pa_log("Failed to parse module arguments.");
465 goto fail;
468 if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
469 pa_log("Master sink not found");
470 goto fail;
473 pa_assert(master);
475 ss = master->sample_spec;
476 ss.format = PA_SAMPLE_FLOAT32;
477 map = master->channel_map;
478 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
479 pa_log("Invalid sample format specification or channel map");
480 goto fail;
484 u = pa_xnew0(struct userdata, 1);
485 if (!u) {
486 pa_log("Failed to alloc userdata");
487 goto fail;
489 u->module = m;
490 m->userdata = u;
491 u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
492 if (!u->memblockq) {
493 pa_log("Failed to create sink memblockq.");
494 goto fail;
496 u->channels = ss.channels;
498 /* Create sink */
499 pa_sink_new_data_init(&sink_data);
500 sink_data.driver = __FILE__;
501 sink_data.module = m;
502 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
503 sink_data.name = pa_sprintf_malloc("%s.vsink", master->name);
504 pa_sink_new_data_set_sample_spec(&sink_data, &ss);
505 pa_sink_new_data_set_channel_map(&sink_data, &map);
506 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
507 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
508 pa_proplist_sets(sink_data.proplist, "device.vsink.name", sink_data.name);
510 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
511 pa_log("Invalid properties");
512 pa_sink_new_data_done(&sink_data);
513 goto fail;
516 if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
517 const char *z;
519 z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
520 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s", sink_data.name, z ? z : master->name);
523 u->sink = pa_sink_new(m->core, &sink_data,
524 PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
525 (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
526 pa_sink_new_data_done(&sink_data);
528 if (!u->sink) {
529 pa_log("Failed to create sink.");
530 goto fail;
533 u->sink->parent.process_msg = sink_process_msg_cb;
534 u->sink->set_state = sink_set_state_cb;
535 u->sink->update_requested_latency = sink_update_requested_latency_cb;
536 u->sink->request_rewind = sink_request_rewind_cb;
537 u->sink->set_volume = sink_set_volume_cb;
538 u->sink->set_mute = sink_set_mute_cb;
539 u->sink->userdata = u;
541 pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
543 /* Create sink input */
544 pa_sink_input_new_data_init(&sink_input_data);
545 sink_input_data.driver = __FILE__;
546 sink_input_data.module = m;
547 sink_input_data.sink = master;
548 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream");
549 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
550 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
551 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
553 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
554 pa_sink_input_new_data_done(&sink_input_data);
556 if (!u->sink_input)
557 goto fail;
559 u->sink_input->pop = sink_input_pop_cb;
560 u->sink_input->process_rewind = sink_input_process_rewind_cb;
561 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
562 u->sink_input->update_max_request = sink_input_update_max_request_cb;
563 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
564 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
565 u->sink_input->kill = sink_input_kill_cb;
566 u->sink_input->attach = sink_input_attach_cb;
567 u->sink_input->detach = sink_input_detach_cb;
568 u->sink_input->state_change = sink_input_state_change_cb;
569 u->sink_input->may_move_to = sink_input_may_move_to_cb;
570 u->sink_input->moving = sink_input_moving_cb;
571 u->sink_input->volume_changed = sink_input_volume_changed_cb;
572 u->sink_input->mute_changed = sink_input_mute_changed_cb;
573 u->sink_input->userdata = u;
575 //pa_sink_input_set_requested_latency(u->sink_input, 5000);
577 pa_sink_put(u->sink);
578 pa_sink_input_put(u->sink_input);
580 pa_modargs_free(ma);
582 pa_xfree(use_default);
584 return 0;
586 fail:
587 if (ma)
588 pa_modargs_free(ma);
590 pa_xfree(use_default);
592 pa__done(m);
594 return -1;
597 int pa__get_n_used(pa_module *m) {
598 struct userdata *u;
600 pa_assert(m);
601 pa_assert_se(u = m->userdata);
603 return pa_sink_linked_by(u->sink);
606 void pa__done(pa_module*m) {
607 struct userdata *u;
609 pa_assert(m);
611 if (!(u = m->userdata))
612 return;
614 /* See comments in sink_input_kill_cb() above regarding
615 * destruction order! */
617 if (u->sink_input)
618 pa_sink_input_unlink(u->sink_input);
620 if (u->sink)
621 pa_sink_unlink(u->sink);
623 if (u->sink_input)
624 pa_sink_input_unref(u->sink_input);
626 if (u->sink)
627 pa_sink_unref(u->sink);
630 if (u->memblockq)
631 pa_memblockq_free(u->memblockq);
634 pa_xfree(u);