]> code.delx.au - pulseaudio/blob - src/modules/module-loopback.c
i18n: Update Greek translation
[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 if (pa_source_get_state(dest) == PA_SOURCE_SUSPENDED)
424 pa_sink_input_cork(u->sink_input, true);
425 else
426 pa_sink_input_cork(u->sink_input, false);
427
428 update_adjust_timer(u);
429 }
430
431 /* Called from main thread */
432 static void source_output_suspend_cb(pa_source_output *o, bool suspended) {
433 struct userdata *u;
434
435 pa_source_output_assert_ref(o);
436 pa_assert_ctl_context();
437 pa_assert_se(u = o->userdata);
438
439 pa_sink_input_cork(u->sink_input, suspended);
440
441 update_adjust_timer(u);
442 }
443
444 /* Called from output thread context */
445 static void update_min_memblockq_length(struct userdata *u) {
446 size_t length;
447
448 pa_assert(u);
449 pa_sink_input_assert_io_context(u->sink_input);
450
451 length = pa_memblockq_get_length(u->memblockq);
452
453 if (u->min_memblockq_length == (size_t) -1 ||
454 length < u->min_memblockq_length)
455 u->min_memblockq_length = length;
456 }
457
458 /* Called from output thread context */
459 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
460 struct userdata *u;
461
462 pa_sink_input_assert_ref(i);
463 pa_sink_input_assert_io_context(i);
464 pa_assert_se(u = i->userdata);
465 pa_assert(chunk);
466
467 u->in_pop = true;
468 while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
469 ;
470 u->in_pop = false;
471
472 if (pa_memblockq_peek(u->memblockq, chunk) < 0) {
473 pa_log_info("Could not peek into queue");
474 return -1;
475 }
476
477 chunk->length = PA_MIN(chunk->length, nbytes);
478 pa_memblockq_drop(u->memblockq, chunk->length);
479
480 update_min_memblockq_length(u);
481
482 return 0;
483 }
484
485 /* Called from output thread context */
486 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
487 struct userdata *u;
488
489 pa_sink_input_assert_ref(i);
490 pa_sink_input_assert_io_context(i);
491 pa_assert_se(u = i->userdata);
492
493 pa_memblockq_rewind(u->memblockq, nbytes);
494 }
495
496 /* Called from output thread context */
497 static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
498 struct userdata *u = PA_SINK_INPUT(obj)->userdata;
499
500 switch (code) {
501
502 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
503 pa_usec_t *r = data;
504
505 pa_sink_input_assert_io_context(u->sink_input);
506
507 *r = pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &u->sink_input->sample_spec);
508
509 /* Fall through, the default handler will add in the extra
510 * latency added by the resampler */
511 break;
512 }
513
514 case SINK_INPUT_MESSAGE_POST:
515
516 pa_sink_input_assert_io_context(u->sink_input);
517
518 if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
519 pa_memblockq_push_align(u->memblockq, chunk);
520 else
521 pa_memblockq_flush_write(u->memblockq, true);
522
523 update_min_memblockq_length(u);
524
525 /* Is this the end of an underrun? Then let's start things
526 * right-away */
527 if (!u->in_pop &&
528 u->sink_input->thread_info.underrun_for > 0 &&
529 pa_memblockq_is_readable(u->memblockq)) {
530
531 pa_log_debug("Requesting rewind due to end of underrun.");
532 pa_sink_input_request_rewind(u->sink_input,
533 (size_t) (u->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : u->sink_input->thread_info.underrun_for),
534 false, true, false);
535 }
536
537 u->recv_counter += (int64_t) chunk->length;
538
539 return 0;
540
541 case SINK_INPUT_MESSAGE_REWIND:
542
543 pa_sink_input_assert_io_context(u->sink_input);
544
545 if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
546 pa_memblockq_seek(u->memblockq, -offset, PA_SEEK_RELATIVE, true);
547 else
548 pa_memblockq_flush_write(u->memblockq, true);
549
550 u->recv_counter -= offset;
551
552 update_min_memblockq_length(u);
553
554 return 0;
555
556 case SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT: {
557 size_t length;
558
559 update_min_memblockq_length(u);
560
561 length = pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq);
562
563 u->latency_snapshot.recv_counter = u->recv_counter;
564 u->latency_snapshot.sink_input_buffer =
565 pa_memblockq_get_length(u->memblockq) +
566 (u->sink_input->thread_info.resampler ? pa_resampler_request(u->sink_input->thread_info.resampler, length) : length);
567 u->latency_snapshot.sink_latency = pa_sink_get_latency_within_thread(u->sink_input->sink);
568
569 u->latency_snapshot.max_request = pa_sink_input_get_max_request(u->sink_input);
570
571 u->latency_snapshot.min_memblockq_length = u->min_memblockq_length;
572 u->min_memblockq_length = (size_t) -1;
573
574 return 0;
575 }
576
577 case SINK_INPUT_MESSAGE_MAX_REQUEST_CHANGED: {
578 /* This message is sent from the IO thread to the main
579 * thread! So don't be confused. All the user cases above
580 * are executed in thread context, but this one is not! */
581
582 pa_assert_ctl_context();
583
584 if (u->time_event)
585 adjust_rates(u);
586 return 0;
587 }
588 }
589
590 return pa_sink_input_process_msg(obj, code, data, offset, chunk);
591 }
592
593 /* Called from output thread context */
594 static void sink_input_attach_cb(pa_sink_input *i) {
595 struct userdata *u;
596
597 pa_sink_input_assert_ref(i);
598 pa_sink_input_assert_io_context(i);
599 pa_assert_se(u = i->userdata);
600
601 u->rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
602 i->sink->thread_info.rtpoll,
603 PA_RTPOLL_LATE,
604 u->asyncmsgq);
605
606 pa_memblockq_set_prebuf(u->memblockq, pa_sink_input_get_max_request(i)*2);
607 pa_memblockq_set_maxrewind(u->memblockq, pa_sink_input_get_max_rewind(i));
608
609 u->min_memblockq_length = (size_t) -1;
610 }
611
612 /* Called from output thread context */
613 static void sink_input_detach_cb(pa_sink_input *i) {
614 struct userdata *u;
615
616 pa_sink_input_assert_ref(i);
617 pa_sink_input_assert_io_context(i);
618 pa_assert_se(u = i->userdata);
619
620 if (u->rtpoll_item_read) {
621 pa_rtpoll_item_free(u->rtpoll_item_read);
622 u->rtpoll_item_read = NULL;
623 }
624 }
625
626 /* Called from output thread context */
627 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
628 struct userdata *u;
629
630 pa_sink_input_assert_ref(i);
631 pa_sink_input_assert_io_context(i);
632 pa_assert_se(u = i->userdata);
633
634 pa_memblockq_set_maxrewind(u->memblockq, nbytes);
635 }
636
637 /* Called from output thread context */
638 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
639 struct userdata *u;
640
641 pa_sink_input_assert_ref(i);
642 pa_sink_input_assert_io_context(i);
643 pa_assert_se(u = i->userdata);
644
645 pa_memblockq_set_prebuf(u->memblockq, nbytes*2);
646 pa_log_info("Max request changed");
647 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_MAX_REQUEST_CHANGED, NULL, 0, NULL, NULL);
648 }
649
650 /* Called from main thread */
651 static void sink_input_kill_cb(pa_sink_input *i) {
652 struct userdata *u;
653
654 pa_sink_input_assert_ref(i);
655 pa_assert_ctl_context();
656 pa_assert_se(u = i->userdata);
657
658 teardown(u);
659 pa_module_unload_request(u->module, true);
660 }
661
662 /* Called from the output thread context */
663 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
664 struct userdata *u;
665
666 pa_sink_input_assert_ref(i);
667 pa_assert_se(u = i->userdata);
668
669 if (state == PA_SINK_INPUT_UNLINKED)
670 pa_asyncmsgq_flush(u->asyncmsgq, false);
671 }
672
673 /* Called from main thread */
674 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
675 struct userdata *u;
676 pa_proplist *p;
677 const char *n;
678
679 if (!dest)
680 return;
681
682 pa_sink_input_assert_ref(i);
683 pa_assert_ctl_context();
684 pa_assert_se(u = i->userdata);
685
686 p = pa_proplist_new();
687 pa_proplist_setf(p, PA_PROP_MEDIA_NAME, "Loopback to %s", pa_strnull(pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION)));
688
689 if ((n = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_ICON_NAME)))
690 pa_proplist_sets(p, PA_PROP_MEDIA_ICON_NAME, n);
691
692 pa_source_output_update_proplist(u->source_output, PA_UPDATE_REPLACE, p);
693 pa_proplist_free(p);
694
695 if (pa_sink_get_state(dest) == PA_SINK_SUSPENDED)
696 pa_source_output_cork(u->source_output, true);
697 else
698 pa_source_output_cork(u->source_output, false);
699
700 update_adjust_timer(u);
701 }
702
703 /* Called from main thread */
704 static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
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 if (!u->source_output || !u->source_output->source)
712 return true;
713
714 return dest != u->source_output->source->monitor_of;
715 }
716
717 /* Called from main thread */
718 static void sink_input_suspend_cb(pa_sink_input *i, bool suspended) {
719 struct userdata *u;
720
721 pa_sink_input_assert_ref(i);
722 pa_assert_ctl_context();
723 pa_assert_se(u = i->userdata);
724
725 pa_source_output_cork(u->source_output, suspended);
726
727 update_adjust_timer(u);
728 }
729
730 int pa__init(pa_module *m) {
731 pa_modargs *ma = NULL;
732 struct userdata *u;
733 pa_sink *sink = NULL;
734 pa_sink_input_new_data sink_input_data;
735 bool sink_dont_move;
736 pa_source *source = NULL;
737 pa_source_output_new_data source_output_data;
738 bool source_dont_move;
739 uint32_t latency_msec;
740 pa_sample_spec ss;
741 pa_channel_map map;
742 bool format_set = false;
743 bool rate_set = false;
744 bool channels_set = false;
745 pa_memchunk silence;
746 uint32_t adjust_time_sec;
747 const char *n;
748 bool remix = true;
749
750 pa_assert(m);
751
752 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
753 pa_log("Failed to parse module arguments");
754 goto fail;
755 }
756
757 n = pa_modargs_get_value(ma, "source", NULL);
758 if (n && !(source = pa_namereg_get(m->core, n, PA_NAMEREG_SOURCE))) {
759 pa_log("No such source.");
760 goto fail;
761 }
762
763 n = pa_modargs_get_value(ma, "sink", NULL);
764 if (n && !(sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
765 pa_log("No such sink.");
766 goto fail;
767 }
768
769 if (pa_modargs_get_value_boolean(ma, "remix", &remix) < 0) {
770 pa_log("Invalid boolean remix parameter");
771 goto fail;
772 }
773
774 if (sink) {
775 ss = sink->sample_spec;
776 map = sink->channel_map;
777 format_set = true;
778 rate_set = true;
779 channels_set = true;
780 } else if (source) {
781 ss = source->sample_spec;
782 map = source->channel_map;
783 format_set = true;
784 rate_set = true;
785 channels_set = true;
786 } else {
787 /* FIXME: Dummy stream format, needed because pa_sink_input_new()
788 * requires valid sample spec and channel map even when all the FIX_*
789 * stream flags are specified. pa_sink_input_new() should be changed
790 * to ignore the sample spec and channel map when the FIX_* flags are
791 * present. */
792 ss.format = PA_SAMPLE_U8;
793 ss.rate = 8000;
794 ss.channels = 1;
795 map.channels = 1;
796 map.map[0] = PA_CHANNEL_POSITION_MONO;
797 }
798
799 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
800 pa_log("Invalid sample format specification or channel map");
801 goto fail;
802 }
803
804 if (pa_modargs_get_value(ma, "format", NULL))
805 format_set = true;
806
807 if (pa_modargs_get_value(ma, "rate", NULL))
808 rate_set = true;
809
810 if (pa_modargs_get_value(ma, "channels", NULL) || pa_modargs_get_value(ma, "channel_map", NULL))
811 channels_set = true;
812
813 latency_msec = DEFAULT_LATENCY_MSEC;
814 if (pa_modargs_get_value_u32(ma, "latency_msec", &latency_msec) < 0 || latency_msec < 1 || latency_msec > 30000) {
815 pa_log("Invalid latency specification");
816 goto fail;
817 }
818
819 m->userdata = u = pa_xnew0(struct userdata, 1);
820 u->core = m->core;
821 u->module = m;
822 u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
823
824 adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
825 if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
826 pa_log("Failed to parse adjust_time value");
827 goto fail;
828 }
829
830 if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
831 u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
832 else
833 u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
834
835 pa_sink_input_new_data_init(&sink_input_data);
836 sink_input_data.driver = __FILE__;
837 sink_input_data.module = m;
838
839 if (sink)
840 pa_sink_input_new_data_set_sink(&sink_input_data, sink, false);
841
842 if (pa_modargs_get_proplist(ma, "sink_input_properties", sink_input_data.proplist, PA_UPDATE_REPLACE) < 0) {
843 pa_log("Failed to parse the sink_input_properties value.");
844 pa_sink_input_new_data_done(&sink_input_data);
845 goto fail;
846 }
847
848 if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ROLE))
849 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
850
851 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
852 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
853 sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE | PA_SINK_INPUT_START_CORKED;
854
855 if (!remix)
856 sink_input_data.flags |= PA_SINK_INPUT_NO_REMIX;
857
858 if (!format_set)
859 sink_input_data.flags |= PA_SINK_INPUT_FIX_FORMAT;
860
861 if (!rate_set)
862 sink_input_data.flags |= PA_SINK_INPUT_FIX_RATE;
863
864 if (!channels_set)
865 sink_input_data.flags |= PA_SINK_INPUT_FIX_CHANNELS;
866
867 sink_dont_move = false;
868 if (pa_modargs_get_value_boolean(ma, "sink_dont_move", &sink_dont_move) < 0) {
869 pa_log("sink_dont_move= expects a boolean argument.");
870 goto fail;
871 }
872
873 if (sink_dont_move)
874 sink_input_data.flags |= PA_SINK_INPUT_DONT_MOVE;
875
876 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
877 pa_sink_input_new_data_done(&sink_input_data);
878
879 if (!u->sink_input)
880 goto fail;
881
882 /* If format, rate or channels were originally unset, they are set now
883 * after the pa_sink_input_new() call. */
884 ss = u->sink_input->sample_spec;
885 map = u->sink_input->channel_map;
886
887 u->sink_input->parent.process_msg = sink_input_process_msg_cb;
888 u->sink_input->pop = sink_input_pop_cb;
889 u->sink_input->process_rewind = sink_input_process_rewind_cb;
890 u->sink_input->kill = sink_input_kill_cb;
891 u->sink_input->state_change = sink_input_state_change_cb;
892 u->sink_input->attach = sink_input_attach_cb;
893 u->sink_input->detach = sink_input_detach_cb;
894 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
895 u->sink_input->update_max_request = sink_input_update_max_request_cb;
896 u->sink_input->may_move_to = sink_input_may_move_to_cb;
897 u->sink_input->moving = sink_input_moving_cb;
898 u->sink_input->suspend = sink_input_suspend_cb;
899 u->sink_input->userdata = u;
900
901 pa_sink_input_set_requested_latency(u->sink_input, u->latency/3);
902
903 pa_source_output_new_data_init(&source_output_data);
904 source_output_data.driver = __FILE__;
905 source_output_data.module = m;
906 if (source)
907 pa_source_output_new_data_set_source(&source_output_data, source, false);
908
909 if (pa_modargs_get_proplist(ma, "source_output_properties", source_output_data.proplist, PA_UPDATE_REPLACE) < 0) {
910 pa_log("Failed to parse the source_output_properties value.");
911 pa_source_output_new_data_done(&source_output_data);
912 goto fail;
913 }
914
915 if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE))
916 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
917
918 pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
919 pa_source_output_new_data_set_channel_map(&source_output_data, &map);
920 source_output_data.flags = PA_SOURCE_OUTPUT_START_CORKED;
921
922 if (!remix)
923 source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX;
924
925 source_dont_move = false;
926 if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) {
927 pa_log("source_dont_move= expects a boolean argument.");
928 goto fail;
929 }
930
931 if (source_dont_move)
932 source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE;
933
934 pa_source_output_new(&u->source_output, m->core, &source_output_data);
935 pa_source_output_new_data_done(&source_output_data);
936
937 if (!u->source_output)
938 goto fail;
939
940 u->source_output->parent.process_msg = source_output_process_msg_cb;
941 u->source_output->push = source_output_push_cb;
942 u->source_output->process_rewind = source_output_process_rewind_cb;
943 u->source_output->kill = source_output_kill_cb;
944 u->source_output->attach = source_output_attach_cb;
945 u->source_output->detach = source_output_detach_cb;
946 u->source_output->state_change = source_output_state_change_cb;
947 u->source_output->may_move_to = source_output_may_move_to_cb;
948 u->source_output->moving = source_output_moving_cb;
949 u->source_output->suspend = source_output_suspend_cb;
950 u->source_output->userdata = u;
951
952 pa_source_output_set_requested_latency(u->source_output, u->latency/3);
953
954 pa_sink_input_get_silence(u->sink_input, &silence);
955 u->memblockq = pa_memblockq_new(
956 "module-loopback memblockq",
957 0, /* idx */
958 MEMBLOCKQ_MAXLENGTH, /* maxlength */
959 MEMBLOCKQ_MAXLENGTH, /* tlength */
960 &ss, /* sample_spec */
961 0, /* prebuf */
962 0, /* minreq */
963 0, /* maxrewind */
964 &silence); /* silence frame */
965 pa_memblock_unref(silence.memblock);
966
967 u->asyncmsgq = pa_asyncmsgq_new(0);
968
969 if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_NAME))
970 pa_proplist_setf(u->source_output->proplist, PA_PROP_MEDIA_NAME, "Loopback to %s",
971 pa_strnull(pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
972
973 if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME)
974 && (n = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_ICON_NAME)))
975 pa_proplist_sets(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME, n);
976
977 if (!pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_NAME))
978 pa_proplist_setf(u->sink_input->proplist, PA_PROP_MEDIA_NAME, "Loopback from %s",
979 pa_strnull(pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
980
981 if (source && !pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME)
982 && (n = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_ICON_NAME)))
983 pa_proplist_sets(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME, n);
984
985 pa_sink_input_put(u->sink_input);
986 pa_source_output_put(u->source_output);
987
988 if (pa_source_get_state(u->source_output->source) != PA_SOURCE_SUSPENDED)
989 pa_sink_input_cork(u->sink_input, false);
990
991 if (pa_sink_get_state(u->sink_input->sink) != PA_SINK_SUSPENDED)
992 pa_source_output_cork(u->source_output, false);
993
994 update_adjust_timer(u);
995
996 pa_modargs_free(ma);
997 return 0;
998
999 fail:
1000 if (ma)
1001 pa_modargs_free(ma);
1002
1003 pa__done(m);
1004
1005 return -1;
1006 }
1007
1008 void pa__done(pa_module*m) {
1009 struct userdata *u;
1010
1011 pa_assert(m);
1012
1013 if (!(u = m->userdata))
1014 return;
1015
1016 teardown(u);
1017
1018 if (u->memblockq)
1019 pa_memblockq_free(u->memblockq);
1020
1021 if (u->asyncmsgq)
1022 pa_asyncmsgq_unref(u->asyncmsgq);
1023
1024 pa_xfree(u);
1025 }