]> code.delx.au - pulseaudio/blob - src/modules/module-loopback.c
Remove pa_bool_t and replace it with bool.
[pulseaudio] / src / modules / module-loopback.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2009 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/sink-input.h>
32 #include <pulsecore/module.h>
33 #include <pulsecore/modargs.h>
34 #include <pulsecore/namereg.h>
35 #include <pulsecore/log.h>
36 #include <pulsecore/core-util.h>
37
38 #include <pulse/rtclock.h>
39 #include <pulse/timeval.h>
40
41 #include "module-loopback-symdef.h"
42
43 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
44 PA_MODULE_DESCRIPTION("Loopback from source to sink");
45 PA_MODULE_VERSION(PACKAGE_VERSION);
46 PA_MODULE_LOAD_ONCE(false);
47 PA_MODULE_USAGE(
48 "source=<source to connect to> "
49 "sink=<sink to connect to> "
50 "adjust_time=<how often to readjust rates in s> "
51 "latency_msec=<latency in ms> "
52 "format=<sample format> "
53 "rate=<sample rate> "
54 "channels=<number of channels> "
55 "channel_map=<channel map> "
56 "sink_input_properties=<proplist> "
57 "source_output_properties=<proplist> "
58 "source_dont_move=<boolean> "
59 "sink_dont_move=<boolean> "
60 "remix=<remix channels?> ");
61
62 #define DEFAULT_LATENCY_MSEC 200
63
64 #define MEMBLOCKQ_MAXLENGTH (1024*1024*16)
65
66 #define DEFAULT_ADJUST_TIME_USEC (10*PA_USEC_PER_SEC)
67
68 struct userdata {
69 pa_core *core;
70 pa_module *module;
71
72 pa_sink_input *sink_input;
73 pa_source_output *source_output;
74
75 pa_asyncmsgq *asyncmsgq;
76 pa_memblockq *memblockq;
77
78 pa_rtpoll_item *rtpoll_item_read, *rtpoll_item_write;
79
80 pa_time_event *time_event;
81 pa_usec_t adjust_time;
82
83 int64_t recv_counter;
84 int64_t send_counter;
85
86 size_t skip;
87 pa_usec_t latency;
88
89 bool in_pop;
90 size_t min_memblockq_length;
91
92 struct {
93 int64_t send_counter;
94 size_t source_output_buffer;
95 pa_usec_t source_latency;
96
97 int64_t recv_counter;
98 size_t sink_input_buffer;
99 pa_usec_t sink_latency;
100
101 size_t min_memblockq_length;
102 size_t max_request;
103 } latency_snapshot;
104 };
105
106 static const char* const valid_modargs[] = {
107 "source",
108 "sink",
109 "adjust_time",
110 "latency_msec",
111 "format",
112 "rate",
113 "channels",
114 "channel_map",
115 "sink_input_properties",
116 "source_output_properties",
117 "source_dont_move",
118 "sink_dont_move",
119 "remix",
120 NULL,
121 };
122
123 enum {
124 SINK_INPUT_MESSAGE_POST = PA_SINK_INPUT_MESSAGE_MAX,
125 SINK_INPUT_MESSAGE_REWIND,
126 SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT,
127 SINK_INPUT_MESSAGE_MAX_REQUEST_CHANGED
128 };
129
130 enum {
131 SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT
132 };
133
134 static void enable_adjust_timer(struct userdata *u, bool enable);
135
136 /* Called from main context */
137 static void teardown(struct userdata *u) {
138 pa_assert(u);
139 pa_assert_ctl_context();
140
141 u->adjust_time = 0;
142 enable_adjust_timer(u, false);
143
144 /* Handling the asyncmsgq between the source output and the sink input
145 * requires some care. When the source output is unlinked, nothing needs
146 * to be done for the asyncmsgq, because the source output is the sending
147 * end. But when the sink input is unlinked, we should ensure that the
148 * asyncmsgq is emptied, because the messages in the queue hold references
149 * to the sink input. Also, we need to ensure that new messages won't be
150 * written to the queue after we have emptied it.
151 *
152 * Emptying the queue can be done in the state_changed() callback of the
153 * sink input, when the new state is "unlinked".
154 *
155 * Preventing new messages from being written to the queue can be achieved
156 * by unlinking the source output before unlinking the sink input. There
157 * are no other writers for that queue, so this is sufficient. */
158
159 if (u->source_output) {
160 pa_source_output_unlink(u->source_output);
161 pa_source_output_unref(u->source_output);
162 u->source_output = NULL;
163 }
164
165 if (u->sink_input) {
166 pa_sink_input_unlink(u->sink_input);
167 pa_sink_input_unref(u->sink_input);
168 u->sink_input = NULL;
169 }
170 }
171
172 /* Called from main context */
173 static void adjust_rates(struct userdata *u) {
174 size_t buffer, fs;
175 uint32_t old_rate, base_rate, new_rate;
176 pa_usec_t buffer_latency;
177
178 pa_assert(u);
179 pa_assert_ctl_context();
180
181 pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
182 pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, NULL, 0, NULL);
183
184 buffer =
185 u->latency_snapshot.sink_input_buffer +
186 u->latency_snapshot.source_output_buffer;
187
188 if (u->latency_snapshot.recv_counter <= u->latency_snapshot.send_counter)
189 buffer += (size_t) (u->latency_snapshot.send_counter - u->latency_snapshot.recv_counter);
190 else
191 buffer += PA_CLIP_SUB(buffer, (size_t) (u->latency_snapshot.recv_counter - u->latency_snapshot.send_counter));
192
193 buffer_latency = pa_bytes_to_usec(buffer, &u->sink_input->sample_spec);
194
195 pa_log_debug("Loopback overall latency is %0.2f ms + %0.2f ms + %0.2f ms = %0.2f ms",
196 (double) u->latency_snapshot.sink_latency / PA_USEC_PER_MSEC,
197 (double) buffer_latency / PA_USEC_PER_MSEC,
198 (double) u->latency_snapshot.source_latency / PA_USEC_PER_MSEC,
199 ((double) u->latency_snapshot.sink_latency + buffer_latency + u->latency_snapshot.source_latency) / PA_USEC_PER_MSEC);
200
201 pa_log_debug("Should buffer %zu bytes, buffered at minimum %zu bytes",
202 u->latency_snapshot.max_request*2,
203 u->latency_snapshot.min_memblockq_length);
204
205 fs = pa_frame_size(&u->sink_input->sample_spec);
206 old_rate = u->sink_input->sample_spec.rate;
207 base_rate = u->source_output->sample_spec.rate;
208
209 if (u->latency_snapshot.min_memblockq_length < u->latency_snapshot.max_request*2)
210 new_rate = base_rate - (((u->latency_snapshot.max_request*2 - u->latency_snapshot.min_memblockq_length) / fs) *PA_USEC_PER_SEC)/u->adjust_time;
211 else
212 new_rate = base_rate + (((u->latency_snapshot.min_memblockq_length - u->latency_snapshot.max_request*2) / fs) *PA_USEC_PER_SEC)/u->adjust_time;
213
214 if (new_rate < (uint32_t) (base_rate*0.8) || new_rate > (uint32_t) (base_rate*1.25)) {
215 pa_log_warn("Sample rates too different, not adjusting (%u vs. %u).", base_rate, new_rate);
216 new_rate = base_rate;
217 } else {
218 if (base_rate < new_rate + 20 && new_rate < base_rate + 20)
219 new_rate = base_rate;
220 /* Do the adjustment in small steps; 2‰ can be considered inaudible */
221 if (new_rate < (uint32_t) (old_rate*0.998) || new_rate > (uint32_t) (old_rate*1.002)) {
222 pa_log_info("New rate of %u Hz not within 2‰ of %u Hz, forcing smaller adjustment", new_rate, old_rate);
223 new_rate = PA_CLAMP(new_rate, (uint32_t) (old_rate*0.998), (uint32_t) (old_rate*1.002));
224 }
225 }
226
227 pa_sink_input_set_rate(u->sink_input, new_rate);
228 pa_log_debug("[%s] Updated sampling rate to %lu Hz.", u->sink_input->sink->name, (unsigned long) new_rate);
229
230 pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
231 }
232
233 /* Called from main context */
234 static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
235 struct userdata *u = userdata;
236
237 pa_assert(u);
238 pa_assert(a);
239 pa_assert(u->time_event == e);
240
241 adjust_rates(u);
242 }
243
244 /* Called from main context */
245 static void enable_adjust_timer(struct userdata *u, bool enable) {
246 if (enable) {
247 if (u->time_event || u->adjust_time <= 0)
248 return;
249
250 u->time_event = pa_core_rttime_new(u->module->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
251 } else {
252 if (!u->time_event)
253 return;
254
255 u->core->mainloop->time_free(u->time_event);
256 u->time_event = NULL;
257 }
258 }
259
260 /* Called from main context */
261 static void update_adjust_timer(struct userdata *u) {
262 if (u->sink_input->state == PA_SINK_INPUT_CORKED || u->source_output->state == PA_SOURCE_OUTPUT_CORKED)
263 enable_adjust_timer(u, false);
264 else
265 enable_adjust_timer(u, true);
266 }
267
268 /* Called from input thread context */
269 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
270 struct userdata *u;
271 pa_memchunk copy;
272
273 pa_source_output_assert_ref(o);
274 pa_source_output_assert_io_context(o);
275 pa_assert_se(u = o->userdata);
276
277 if (u->skip > chunk->length) {
278 u->skip -= chunk->length;
279 return;
280 }
281
282 if (u->skip > 0) {
283 copy = *chunk;
284 copy.index += u->skip;
285 copy.length -= u->skip;
286 u->skip = 0;
287
288 chunk = &copy;
289 }
290
291 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, chunk, NULL);
292 u->send_counter += (int64_t) chunk->length;
293 }
294
295 /* Called from input thread context */
296 static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
297 struct userdata *u;
298
299 pa_source_output_assert_ref(o);
300 pa_source_output_assert_io_context(o);
301 pa_assert_se(u = o->userdata);
302
303 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_REWIND, NULL, (int64_t) nbytes, NULL, NULL);
304 u->send_counter -= (int64_t) nbytes;
305 }
306
307 /* Called from output thread context */
308 static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
309 struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;
310
311 switch (code) {
312
313 case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT: {
314 size_t length;
315
316 length = pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq);
317
318 u->latency_snapshot.send_counter = u->send_counter;
319 u->latency_snapshot.source_output_buffer = u->source_output->thread_info.resampler ? pa_resampler_result(u->source_output->thread_info.resampler, length) : length;
320 u->latency_snapshot.source_latency = pa_source_get_latency_within_thread(u->source_output->source);
321
322 return 0;
323 }
324 }
325
326 return pa_source_output_process_msg(obj, code, data, offset, chunk);
327 }
328
329 /* Called from output thread context */
330 static void source_output_attach_cb(pa_source_output *o) {
331 struct userdata *u;
332
333 pa_source_output_assert_ref(o);
334 pa_source_output_assert_io_context(o);
335 pa_assert_se(u = o->userdata);
336
337 u->rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
338 o->source->thread_info.rtpoll,
339 PA_RTPOLL_LATE,
340 u->asyncmsgq);
341 }
342
343 /* Called from output thread context */
344 static void source_output_detach_cb(pa_source_output *o) {
345 struct userdata *u;
346
347 pa_source_output_assert_ref(o);
348 pa_source_output_assert_io_context(o);
349 pa_assert_se(u = o->userdata);
350
351 if (u->rtpoll_item_write) {
352 pa_rtpoll_item_free(u->rtpoll_item_write);
353 u->rtpoll_item_write = NULL;
354 }
355 }
356
357 /* Called from output thread context */
358 static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
359 struct userdata *u;
360
361 pa_source_output_assert_ref(o);
362 pa_source_output_assert_io_context(o);
363 pa_assert_se(u = o->userdata);
364
365 if (PA_SOURCE_OUTPUT_IS_LINKED(state) && o->thread_info.state == PA_SOURCE_OUTPUT_INIT) {
366
367 u->skip = pa_usec_to_bytes(PA_CLIP_SUB(pa_source_get_latency_within_thread(o->source),
368 u->latency),
369 &o->sample_spec);
370
371 pa_log_info("Skipping %lu bytes", (unsigned long) u->skip);
372 }
373 }
374
375 /* Called from main thread */
376 static void source_output_kill_cb(pa_source_output *o) {
377 struct userdata *u;
378
379 pa_source_output_assert_ref(o);
380 pa_assert_ctl_context();
381 pa_assert_se(u = o->userdata);
382
383 teardown(u);
384 pa_module_unload_request(u->module, true);
385 }
386
387 /* Called from main thread */
388 static bool source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
389 struct userdata *u;
390
391 pa_source_output_assert_ref(o);
392 pa_assert_ctl_context();
393 pa_assert_se(u = o->userdata);
394
395 if (!u->sink_input || !u->sink_input->sink)
396 return true;
397
398 return dest != u->sink_input->sink->monitor_source;
399 }
400
401 /* Called from main thread */
402 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
403 pa_proplist *p;
404 const char *n;
405 struct userdata *u;
406
407 if (!dest)
408 return;
409
410 pa_source_output_assert_ref(o);
411 pa_assert_ctl_context();
412 pa_assert_se(u = o->userdata);
413
414 p = pa_proplist_new();
415 pa_proplist_setf(p, PA_PROP_MEDIA_NAME, "Loopback of %s", pa_strnull(pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION)));
416
417 if ((n = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_ICON_NAME)))
418 pa_proplist_sets(p, PA_PROP_MEDIA_ICON_NAME, n);
419
420 pa_sink_input_update_proplist(u->sink_input, PA_UPDATE_REPLACE, p);
421 pa_proplist_free(p);
422 }
423
424 /* Called from main thread */
425 static void source_output_suspend_cb(pa_source_output *o, bool suspended) {
426 struct userdata *u;
427
428 pa_source_output_assert_ref(o);
429 pa_assert_ctl_context();
430 pa_assert_se(u = o->userdata);
431
432 pa_sink_input_cork(u->sink_input, suspended);
433
434 update_adjust_timer(u);
435 }
436
437 /* Called from output thread context */
438 static void update_min_memblockq_length(struct userdata *u) {
439 size_t length;
440
441 pa_assert(u);
442 pa_sink_input_assert_io_context(u->sink_input);
443
444 length = pa_memblockq_get_length(u->memblockq);
445
446 if (u->min_memblockq_length == (size_t) -1 ||
447 length < u->min_memblockq_length)
448 u->min_memblockq_length = length;
449 }
450
451 /* Called from output thread context */
452 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
453 struct userdata *u;
454
455 pa_sink_input_assert_ref(i);
456 pa_sink_input_assert_io_context(i);
457 pa_assert_se(u = i->userdata);
458 pa_assert(chunk);
459
460 u->in_pop = true;
461 while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
462 ;
463 u->in_pop = false;
464
465 if (pa_memblockq_peek(u->memblockq, chunk) < 0) {
466 pa_log_info("Could not peek into queue");
467 return -1;
468 }
469
470 chunk->length = PA_MIN(chunk->length, nbytes);
471 pa_memblockq_drop(u->memblockq, chunk->length);
472
473 update_min_memblockq_length(u);
474
475 return 0;
476 }
477
478 /* Called from output thread context */
479 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
480 struct userdata *u;
481
482 pa_sink_input_assert_ref(i);
483 pa_sink_input_assert_io_context(i);
484 pa_assert_se(u = i->userdata);
485
486 pa_memblockq_rewind(u->memblockq, nbytes);
487 }
488
489 /* Called from output thread context */
490 static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
491 struct userdata *u = PA_SINK_INPUT(obj)->userdata;
492
493 switch (code) {
494
495 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
496 pa_usec_t *r = data;
497
498 pa_sink_input_assert_io_context(u->sink_input);
499
500 *r = pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &u->sink_input->sample_spec);
501
502 /* Fall through, the default handler will add in the extra
503 * latency added by the resampler */
504 break;
505 }
506
507 case SINK_INPUT_MESSAGE_POST:
508
509 pa_sink_input_assert_io_context(u->sink_input);
510
511 if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
512 pa_memblockq_push_align(u->memblockq, chunk);
513 else
514 pa_memblockq_flush_write(u->memblockq, true);
515
516 update_min_memblockq_length(u);
517
518 /* Is this the end of an underrun? Then let's start things
519 * right-away */
520 if (!u->in_pop &&
521 u->sink_input->thread_info.underrun_for > 0 &&
522 pa_memblockq_is_readable(u->memblockq)) {
523
524 pa_log_debug("Requesting rewind due to end of underrun.");
525 pa_sink_input_request_rewind(u->sink_input,
526 (size_t) (u->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : u->sink_input->thread_info.underrun_for),
527 false, true, false);
528 }
529
530 u->recv_counter += (int64_t) chunk->length;
531
532 return 0;
533
534 case SINK_INPUT_MESSAGE_REWIND:
535
536 pa_sink_input_assert_io_context(u->sink_input);
537
538 if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
539 pa_memblockq_seek(u->memblockq, -offset, PA_SEEK_RELATIVE, true);
540 else
541 pa_memblockq_flush_write(u->memblockq, true);
542
543 u->recv_counter -= offset;
544
545 update_min_memblockq_length(u);
546
547 return 0;
548
549 case SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT: {
550 size_t length;
551
552 update_min_memblockq_length(u);
553
554 length = pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq);
555
556 u->latency_snapshot.recv_counter = u->recv_counter;
557 u->latency_snapshot.sink_input_buffer =
558 pa_memblockq_get_length(u->memblockq) +
559 (u->sink_input->thread_info.resampler ? pa_resampler_request(u->sink_input->thread_info.resampler, length) : length);
560 u->latency_snapshot.sink_latency = pa_sink_get_latency_within_thread(u->sink_input->sink);
561
562 u->latency_snapshot.max_request = pa_sink_input_get_max_request(u->sink_input);
563
564 u->latency_snapshot.min_memblockq_length = u->min_memblockq_length;
565 u->min_memblockq_length = (size_t) -1;
566
567 return 0;
568 }
569
570 case SINK_INPUT_MESSAGE_MAX_REQUEST_CHANGED: {
571 /* This message is sent from the IO thread to the main
572 * thread! So don't be confused. All the user cases above
573 * are executed in thread context, but this one is not! */
574
575 pa_assert_ctl_context();
576
577 if (u->time_event)
578 adjust_rates(u);
579 return 0;
580 }
581 }
582
583 return pa_sink_input_process_msg(obj, code, data, offset, chunk);
584 }
585
586 /* Called from output thread context */
587 static void sink_input_attach_cb(pa_sink_input *i) {
588 struct userdata *u;
589
590 pa_sink_input_assert_ref(i);
591 pa_sink_input_assert_io_context(i);
592 pa_assert_se(u = i->userdata);
593
594 u->rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
595 i->sink->thread_info.rtpoll,
596 PA_RTPOLL_LATE,
597 u->asyncmsgq);
598
599 pa_memblockq_set_prebuf(u->memblockq, pa_sink_input_get_max_request(i)*2);
600 pa_memblockq_set_maxrewind(u->memblockq, pa_sink_input_get_max_rewind(i));
601
602 u->min_memblockq_length = (size_t) -1;
603 }
604
605 /* Called from output thread context */
606 static void sink_input_detach_cb(pa_sink_input *i) {
607 struct userdata *u;
608
609 pa_sink_input_assert_ref(i);
610 pa_sink_input_assert_io_context(i);
611 pa_assert_se(u = i->userdata);
612
613 if (u->rtpoll_item_read) {
614 pa_rtpoll_item_free(u->rtpoll_item_read);
615 u->rtpoll_item_read = NULL;
616 }
617 }
618
619 /* Called from output thread context */
620 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
621 struct userdata *u;
622
623 pa_sink_input_assert_ref(i);
624 pa_sink_input_assert_io_context(i);
625 pa_assert_se(u = i->userdata);
626
627 pa_memblockq_set_maxrewind(u->memblockq, nbytes);
628 }
629
630 /* Called from output thread context */
631 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
632 struct userdata *u;
633
634 pa_sink_input_assert_ref(i);
635 pa_sink_input_assert_io_context(i);
636 pa_assert_se(u = i->userdata);
637
638 pa_memblockq_set_prebuf(u->memblockq, nbytes*2);
639 pa_log_info("Max request changed");
640 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_MAX_REQUEST_CHANGED, NULL, 0, NULL, NULL);
641 }
642
643 /* Called from main thread */
644 static void sink_input_kill_cb(pa_sink_input *i) {
645 struct userdata *u;
646
647 pa_sink_input_assert_ref(i);
648 pa_assert_ctl_context();
649 pa_assert_se(u = i->userdata);
650
651 teardown(u);
652 pa_module_unload_request(u->module, true);
653 }
654
655 /* Called from the output thread context */
656 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
657 struct userdata *u;
658
659 pa_sink_input_assert_ref(i);
660 pa_assert_se(u = i->userdata);
661
662 if (state == PA_SINK_INPUT_UNLINKED)
663 pa_asyncmsgq_flush(u->asyncmsgq, false);
664 }
665
666 /* Called from main thread */
667 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
668 struct userdata *u;
669 pa_proplist *p;
670 const char *n;
671
672 if (!dest)
673 return;
674
675 pa_sink_input_assert_ref(i);
676 pa_assert_ctl_context();
677 pa_assert_se(u = i->userdata);
678
679 p = pa_proplist_new();
680 pa_proplist_setf(p, PA_PROP_MEDIA_NAME, "Loopback to %s", pa_strnull(pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION)));
681
682 if ((n = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_ICON_NAME)))
683 pa_proplist_sets(p, PA_PROP_MEDIA_ICON_NAME, n);
684
685 pa_source_output_update_proplist(u->source_output, PA_UPDATE_REPLACE, p);
686 pa_proplist_free(p);
687 }
688
689 /* Called from main thread */
690 static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
691 struct userdata *u;
692
693 pa_sink_input_assert_ref(i);
694 pa_assert_ctl_context();
695 pa_assert_se(u = i->userdata);
696
697 if (!u->source_output || !u->source_output->source)
698 return true;
699
700 return dest != u->source_output->source->monitor_of;
701 }
702
703 /* Called from main thread */
704 static void sink_input_suspend_cb(pa_sink_input *i, bool suspended) {
705 struct userdata *u;
706
707 pa_sink_input_assert_ref(i);
708 pa_assert_ctl_context();
709 pa_assert_se(u = i->userdata);
710
711 pa_source_output_cork(u->source_output, suspended);
712
713 update_adjust_timer(u);
714 }
715
716 int pa__init(pa_module *m) {
717 pa_modargs *ma = NULL;
718 struct userdata *u;
719 pa_sink *sink = NULL;
720 pa_sink_input_new_data sink_input_data;
721 bool sink_dont_move;
722 pa_source *source = NULL;
723 pa_source_output_new_data source_output_data;
724 bool source_dont_move;
725 uint32_t latency_msec;
726 pa_sample_spec ss;
727 pa_channel_map map;
728 bool format_set = false;
729 bool rate_set = false;
730 bool channels_set = false;
731 pa_memchunk silence;
732 uint32_t adjust_time_sec;
733 const char *n;
734 bool remix = true;
735
736 pa_assert(m);
737
738 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
739 pa_log("Failed to parse module arguments");
740 goto fail;
741 }
742
743 n = pa_modargs_get_value(ma, "source", NULL);
744 if (n && !(source = pa_namereg_get(m->core, n, PA_NAMEREG_SOURCE))) {
745 pa_log("No such source.");
746 goto fail;
747 }
748
749 n = pa_modargs_get_value(ma, "sink", NULL);
750 if (n && !(sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
751 pa_log("No such sink.");
752 goto fail;
753 }
754
755 if (pa_modargs_get_value_boolean(ma, "remix", &remix) < 0) {
756 pa_log("Invalid boolean remix parameter");
757 goto fail;
758 }
759
760 if (sink) {
761 ss = sink->sample_spec;
762 map = sink->channel_map;
763 format_set = true;
764 rate_set = true;
765 channels_set = true;
766 } else if (source) {
767 ss = source->sample_spec;
768 map = source->channel_map;
769 format_set = true;
770 rate_set = true;
771 channels_set = true;
772 } else {
773 /* FIXME: Dummy stream format, needed because pa_sink_input_new()
774 * requires valid sample spec and channel map even when all the FIX_*
775 * stream flags are specified. pa_sink_input_new() should be changed
776 * to ignore the sample spec and channel map when the FIX_* flags are
777 * present. */
778 ss.format = PA_SAMPLE_U8;
779 ss.rate = 8000;
780 ss.channels = 1;
781 map.channels = 1;
782 map.map[0] = PA_CHANNEL_POSITION_MONO;
783 }
784
785 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
786 pa_log("Invalid sample format specification or channel map");
787 goto fail;
788 }
789
790 if (pa_modargs_get_value(ma, "format", NULL))
791 format_set = true;
792
793 if (pa_modargs_get_value(ma, "rate", NULL))
794 rate_set = true;
795
796 if (pa_modargs_get_value(ma, "channels", NULL) || pa_modargs_get_value(ma, "channel_map", NULL))
797 channels_set = true;
798
799 latency_msec = DEFAULT_LATENCY_MSEC;
800 if (pa_modargs_get_value_u32(ma, "latency_msec", &latency_msec) < 0 || latency_msec < 1 || latency_msec > 2000) {
801 pa_log("Invalid latency specification");
802 goto fail;
803 }
804
805 m->userdata = u = pa_xnew0(struct userdata, 1);
806 u->core = m->core;
807 u->module = m;
808 u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
809
810 adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
811 if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
812 pa_log("Failed to parse adjust_time value");
813 goto fail;
814 }
815
816 if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
817 u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
818 else
819 u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
820
821 pa_sink_input_new_data_init(&sink_input_data);
822 sink_input_data.driver = __FILE__;
823 sink_input_data.module = m;
824
825 if (sink)
826 pa_sink_input_new_data_set_sink(&sink_input_data, sink, false);
827
828 if (pa_modargs_get_proplist(ma, "sink_input_properties", sink_input_data.proplist, PA_UPDATE_REPLACE) < 0) {
829 pa_log("Failed to parse the sink_input_properties value.");
830 pa_sink_input_new_data_done(&sink_input_data);
831 goto fail;
832 }
833
834 if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ROLE))
835 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
836
837 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
838 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
839 sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE | PA_SINK_INPUT_START_CORKED;
840
841 if (!remix)
842 sink_input_data.flags |= PA_SINK_INPUT_NO_REMIX;
843
844 if (!format_set)
845 sink_input_data.flags |= PA_SINK_INPUT_FIX_FORMAT;
846
847 if (!rate_set)
848 sink_input_data.flags |= PA_SINK_INPUT_FIX_RATE;
849
850 if (!channels_set)
851 sink_input_data.flags |= PA_SINK_INPUT_FIX_CHANNELS;
852
853 sink_dont_move = false;
854 if (pa_modargs_get_value_boolean(ma, "sink_dont_move", &sink_dont_move) < 0) {
855 pa_log("sink_dont_move= expects a boolean argument.");
856 goto fail;
857 }
858
859 if (sink_dont_move)
860 sink_input_data.flags |= PA_SINK_INPUT_DONT_MOVE;
861
862 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
863 pa_sink_input_new_data_done(&sink_input_data);
864
865 if (!u->sink_input)
866 goto fail;
867
868 /* If format, rate or channels were originally unset, they are set now
869 * after the pa_sink_input_new() call. */
870 ss = u->sink_input->sample_spec;
871 map = u->sink_input->channel_map;
872
873 u->sink_input->parent.process_msg = sink_input_process_msg_cb;
874 u->sink_input->pop = sink_input_pop_cb;
875 u->sink_input->process_rewind = sink_input_process_rewind_cb;
876 u->sink_input->kill = sink_input_kill_cb;
877 u->sink_input->state_change = sink_input_state_change_cb;
878 u->sink_input->attach = sink_input_attach_cb;
879 u->sink_input->detach = sink_input_detach_cb;
880 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
881 u->sink_input->update_max_request = sink_input_update_max_request_cb;
882 u->sink_input->may_move_to = sink_input_may_move_to_cb;
883 u->sink_input->moving = sink_input_moving_cb;
884 u->sink_input->suspend = sink_input_suspend_cb;
885 u->sink_input->userdata = u;
886
887 pa_sink_input_set_requested_latency(u->sink_input, u->latency/3);
888
889 pa_source_output_new_data_init(&source_output_data);
890 source_output_data.driver = __FILE__;
891 source_output_data.module = m;
892 if (source)
893 pa_source_output_new_data_set_source(&source_output_data, source, false);
894
895 if (pa_modargs_get_proplist(ma, "source_output_properties", source_output_data.proplist, PA_UPDATE_REPLACE) < 0) {
896 pa_log("Failed to parse the source_output_properties value.");
897 pa_source_output_new_data_done(&source_output_data);
898 goto fail;
899 }
900
901 if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE))
902 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
903
904 pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
905 pa_source_output_new_data_set_channel_map(&source_output_data, &map);
906 source_output_data.flags = PA_SOURCE_OUTPUT_START_CORKED;
907
908 if (!remix)
909 source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX;
910
911 source_dont_move = false;
912 if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) {
913 pa_log("source_dont_move= expects a boolean argument.");
914 goto fail;
915 }
916
917 if (source_dont_move)
918 source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE;
919
920 pa_source_output_new(&u->source_output, m->core, &source_output_data);
921 pa_source_output_new_data_done(&source_output_data);
922
923 if (!u->source_output)
924 goto fail;
925
926 u->source_output->parent.process_msg = source_output_process_msg_cb;
927 u->source_output->push = source_output_push_cb;
928 u->source_output->process_rewind = source_output_process_rewind_cb;
929 u->source_output->kill = source_output_kill_cb;
930 u->source_output->attach = source_output_attach_cb;
931 u->source_output->detach = source_output_detach_cb;
932 u->source_output->state_change = source_output_state_change_cb;
933 u->source_output->may_move_to = source_output_may_move_to_cb;
934 u->source_output->moving = source_output_moving_cb;
935 u->source_output->suspend = source_output_suspend_cb;
936 u->source_output->userdata = u;
937
938 pa_source_output_set_requested_latency(u->source_output, u->latency/3);
939
940 pa_sink_input_get_silence(u->sink_input, &silence);
941 u->memblockq = pa_memblockq_new(
942 "module-loopback memblockq",
943 0, /* idx */
944 MEMBLOCKQ_MAXLENGTH, /* maxlength */
945 MEMBLOCKQ_MAXLENGTH, /* tlength */
946 &ss, /* sample_spec */
947 0, /* prebuf */
948 0, /* minreq */
949 0, /* maxrewind */
950 &silence); /* silence frame */
951 pa_memblock_unref(silence.memblock);
952
953 u->asyncmsgq = pa_asyncmsgq_new(0);
954
955 if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_NAME))
956 pa_proplist_setf(u->source_output->proplist, PA_PROP_MEDIA_NAME, "Loopback to %s",
957 pa_strnull(pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
958
959 if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME)
960 && (n = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_ICON_NAME)))
961 pa_proplist_sets(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME, n);
962
963 if (!pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_NAME))
964 pa_proplist_setf(u->sink_input->proplist, PA_PROP_MEDIA_NAME, "Loopback from %s",
965 pa_strnull(pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
966
967 if (source && !pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME)
968 && (n = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_ICON_NAME)))
969 pa_proplist_sets(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME, n);
970
971 pa_sink_input_put(u->sink_input);
972 pa_source_output_put(u->source_output);
973
974 if (pa_source_get_state(u->source_output->source) != PA_SOURCE_SUSPENDED)
975 pa_sink_input_cork(u->sink_input, false);
976
977 if (pa_sink_get_state(u->sink_input->sink) != PA_SINK_SUSPENDED)
978 pa_source_output_cork(u->source_output, false);
979
980 update_adjust_timer(u);
981
982 pa_modargs_free(ma);
983 return 0;
984
985 fail:
986 if (ma)
987 pa_modargs_free(ma);
988
989 pa__done(m);
990
991 return -1;
992 }
993
994 void pa__done(pa_module*m) {
995 struct userdata *u;
996
997 pa_assert(m);
998
999 if (!(u = m->userdata))
1000 return;
1001
1002 teardown(u);
1003
1004 if (u->memblockq)
1005 pa_memblockq_free(u->memblockq);
1006
1007 if (u->asyncmsgq)
1008 pa_asyncmsgq_unref(u->asyncmsgq);
1009
1010 pa_xfree(u);
1011 }