]> code.delx.au - pulseaudio/blob - src/modules/echo-cancel/module-echo-cancel.c
4df77c30b81ad464a609409061e55cf4a893cf64
[pulseaudio] / src / modules / echo-cancel / module-echo-cancel.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2010 Wim Taymans <wim.taymans@gmail.com>
5
6 Based on module-virtual-sink.c
7 module-virtual-source.c
8 module-loopback.c
9
10 Copyright 2010 Intel Corporation
11 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
12
13 PulseAudio is free software; you can redistribute it and/or modify
14 it under the terms of the GNU Lesser General Public License as published
15 by the Free Software Foundation; either version 2.1 of the License,
16 or (at your option) any later version.
17
18 PulseAudio is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public License
24 along with PulseAudio; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 USA.
27 ***/
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <stdio.h>
34 #include <math.h>
35
36 #include "echo-cancel.h"
37
38 #include <pulse/xmalloc.h>
39 #include <pulse/i18n.h>
40 #include <pulse/timeval.h>
41 #include <pulse/rtclock.h>
42
43 #include <pulsecore/atomic.h>
44 #include <pulsecore/macro.h>
45 #include <pulsecore/core-error.h>
46 #include <pulsecore/namereg.h>
47 #include <pulsecore/sink.h>
48 #include <pulsecore/module.h>
49 #include <pulsecore/core-rtclock.h>
50 #include <pulsecore/core-util.h>
51 #include <pulsecore/core-error.h>
52 #include <pulsecore/modargs.h>
53 #include <pulsecore/log.h>
54 #include <pulsecore/thread.h>
55 #include <pulsecore/thread-mq.h>
56 #include <pulsecore/rtpoll.h>
57 #include <pulsecore/sample-util.h>
58 #include <pulsecore/ltdl-helper.h>
59
60 #include "module-echo-cancel-symdef.h"
61
62 PA_MODULE_AUTHOR("Wim Taymans");
63 PA_MODULE_DESCRIPTION("Echo Cancelation");
64 PA_MODULE_VERSION(PACKAGE_VERSION);
65 PA_MODULE_LOAD_ONCE(FALSE);
66 PA_MODULE_USAGE(
67 _("source_name=<name for the source> "
68 "source_properties=<properties for the source> "
69 "source_master=<name of source to filter> "
70 "sink_name=<name for the sink> "
71 "sink_properties=<properties for the sink> "
72 "sink_master=<name of sink to filter> "
73 "adjust_time=<how often to readjust rates in s> "
74 "format=<sample format> "
75 "rate=<sample rate> "
76 "channels=<number of channels> "
77 "channel_map=<channel map> "
78 "aec_method=<implementation to use> "
79 "aec_args=<parameters for the AEC engine> "
80 "save_aec=<save AEC data in /tmp> "
81 ));
82
83 /* NOTE: Make sure the enum and ec_table are maintained in the correct order */
84 typedef enum {
85 PA_ECHO_CANCELLER_INVALID = -1,
86 PA_ECHO_CANCELLER_SPEEX = 0,
87 PA_ECHO_CANCELLER_ADRIAN,
88 } pa_echo_canceller_method_t;
89
90 #define DEFAULT_ECHO_CANCELLER "speex"
91
92 static const pa_echo_canceller ec_table[] = {
93 {
94 /* Speex */
95 .init = pa_speex_ec_init,
96 .run = pa_speex_ec_run,
97 .done = pa_speex_ec_done,
98 },
99 {
100 /* Adrian Andre's NLMS implementation */
101 .init = pa_adrian_ec_init,
102 .run = pa_adrian_ec_run,
103 .done = pa_adrian_ec_done,
104 },
105 };
106
107 #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC)
108 #define DEFAULT_SAVE_AEC 0
109
110 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
111
112 /* This module creates a new (virtual) source and sink.
113 *
114 * The data sent to the new sink is kept in a memblockq before being
115 * forwarded to the real sink_master.
116 *
117 * Data read from source_master is matched against the saved sink data and
118 * echo canceled data is then pushed onto the new source.
119 *
120 * Both source and sink masters have their own threads to push/pull data
121 * respectively. We however perform all our actions in the source IO thread.
122 * To do this we send all played samples to the source IO thread where they
123 * are then pushed into the memblockq.
124 *
125 * Alignment is performed in two steps:
126 *
127 * 1) when something happens that requires quick adjustement of the alignment of
128 * capture and playback samples, we perform a resync. This adjusts the
129 * position in the playback memblock to the requested sample. Quick
130 * adjustements include moving the playback samples before the capture
131 * samples (because else the echo canceler does not work) or when the
132 * playback pointer drifts too far away.
133 *
134 * 2) periodically check the difference between capture and playback. we use a
135 * low and high watermark for adjusting the alignment. playback should always
136 * be before capture and the difference should not be bigger than one frame
137 * size. We would ideally like to resample the sink_input but most driver
138 * don't give enough accuracy to be able to do that right now.
139 */
140
141 struct snapshot {
142 pa_usec_t sink_now;
143 pa_usec_t sink_latency;
144 size_t sink_delay;
145 int64_t send_counter;
146
147 pa_usec_t source_now;
148 pa_usec_t source_latency;
149 size_t source_delay;
150 int64_t recv_counter;
151 size_t rlen;
152 size_t plen;
153 };
154
155 struct userdata {
156 pa_core *core;
157 pa_module *module;
158
159 uint32_t save_aec;
160
161 pa_echo_canceller *ec;
162 uint32_t blocksize;
163
164 pa_bool_t need_realign;
165
166 /* to wakeup the source I/O thread */
167 pa_bool_t in_push;
168 pa_asyncmsgq *asyncmsgq;
169 pa_rtpoll_item *rtpoll_item_read, *rtpoll_item_write;
170
171 pa_source *source;
172 pa_bool_t source_auto_desc;
173 pa_source_output *source_output;
174 pa_memblockq *source_memblockq; /* echo canceler needs fixed sized chunks */
175 pa_atomic_t source_active;
176 size_t source_skip;
177
178 pa_sink *sink;
179 pa_bool_t sink_auto_desc;
180 pa_sink_input *sink_input;
181 pa_memblockq *sink_memblockq;
182 int64_t send_counter; /* updated in sink IO thread */
183 int64_t recv_counter;
184 pa_atomic_t sink_active;
185 size_t sink_skip;
186
187 pa_atomic_t request_resync;
188
189 pa_time_event *time_event;
190 pa_usec_t adjust_time;
191
192 FILE *captured_file;
193 FILE *played_file;
194 FILE *canceled_file;
195 };
196
197 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot);
198
199 static const char* const valid_modargs[] = {
200 "source_name",
201 "source_properties",
202 "source_master",
203 "sink_name",
204 "sink_properties",
205 "sink_master",
206 "adjust_time",
207 "format",
208 "rate",
209 "channels",
210 "channel_map",
211 "aec_method",
212 "aec_args",
213 "save_aec",
214 NULL
215 };
216
217 enum {
218 SOURCE_OUTPUT_MESSAGE_POST = PA_SOURCE_OUTPUT_MESSAGE_MAX,
219 SOURCE_OUTPUT_MESSAGE_REWIND,
220 SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT,
221 SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
222 };
223
224 enum {
225 SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
226 };
227
228 static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
229 int64_t buffer, diff_time, buffer_latency;
230
231 /* get the number of samples between capture and playback */
232 if (snapshot->plen > snapshot->rlen)
233 buffer = snapshot->plen - snapshot->rlen;
234 else
235 buffer = 0;
236
237 buffer += snapshot->source_delay + snapshot->sink_delay;
238
239 /* add the amount of samples not yet transfered to the source context */
240 if (snapshot->recv_counter <= snapshot->send_counter)
241 buffer += (int64_t) (snapshot->send_counter - snapshot->recv_counter);
242 else
243 buffer += PA_CLIP_SUB(buffer, (int64_t) (snapshot->recv_counter - snapshot->send_counter));
244
245 /* convert to time */
246 buffer_latency = pa_bytes_to_usec(buffer, &u->source_output->sample_spec);
247
248 /* capture and playback samples are perfectly aligned when diff_time is 0 */
249 diff_time = (snapshot->sink_now + snapshot->sink_latency - buffer_latency) -
250 (snapshot->source_now - snapshot->source_latency);
251
252 pa_log_debug("diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time,
253 (long long) snapshot->sink_latency,
254 (long long) buffer_latency, (long long) snapshot->source_latency,
255 (long long) snapshot->source_delay, (long long) snapshot->sink_delay,
256 (long long) (snapshot->send_counter - snapshot->recv_counter),
257 (long long) (snapshot->sink_now - snapshot->source_now));
258
259 return diff_time;
260 }
261
262 /* Called from main context */
263 static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
264 struct userdata *u = userdata;
265 uint32_t old_rate, base_rate, new_rate;
266 int64_t diff_time;
267 size_t fs;
268 struct snapshot latency_snapshot;
269
270 pa_assert(u);
271 pa_assert(a);
272 pa_assert(u->time_event == e);
273 pa_assert_ctl_context();
274
275 if (pa_atomic_load (&u->sink_active) == 0 || pa_atomic_load (&u->source_active) == 0)
276 goto done;
277
278 /* update our snapshots */
279 pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
280 pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
281
282 /* calculate drift between capture and playback */
283 diff_time = calc_diff(u, &latency_snapshot);
284
285 fs = pa_frame_size(&u->source_output->sample_spec);
286 old_rate = u->sink_input->sample_spec.rate;
287 base_rate = u->source_output->sample_spec.rate;
288
289 if (diff_time < 0) {
290 /* recording before playback, we need to adjust quickly. The echo
291 * canceler does not work in this case. */
292 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
293 NULL, diff_time, NULL, NULL);
294 //new_rate = base_rate - ((pa_usec_to_bytes (-diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;
295 new_rate = base_rate;
296 }
297 else {
298 if (diff_time > 4000) {
299 /* diff too big, quickly adjust */
300 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
301 NULL, diff_time, NULL, NULL);
302 }
303
304 /* recording behind playback, we need to slowly adjust the rate to match */
305 //new_rate = base_rate + ((pa_usec_to_bytes (diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;
306
307 /* assume equal samplerates for now */
308 new_rate = base_rate;
309 }
310
311 /* make sure we don't make too big adjustements because that sounds horrible */
312 if (new_rate > base_rate * 1.1 || new_rate < base_rate * 0.9)
313 new_rate = base_rate;
314
315 if (new_rate != old_rate) {
316 pa_log_info("Old rate %lu Hz, new rate %lu Hz", (unsigned long) old_rate, (unsigned long) new_rate);
317
318 pa_sink_input_set_rate(u->sink_input, new_rate);
319 }
320
321 done:
322 pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
323 }
324
325 /* Called from source I/O thread context */
326 static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
327 struct userdata *u = PA_SOURCE(o)->userdata;
328
329 switch (code) {
330
331 case PA_SOURCE_MESSAGE_GET_LATENCY:
332
333 /* The source is _put() before the source output is, so let's
334 * make sure we don't access it in that time. Also, the
335 * source output is first shut down, the source second. */
336 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
337 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) {
338 *((pa_usec_t*) data) = 0;
339 return 0;
340 }
341
342 *((pa_usec_t*) data) =
343
344 /* Get the latency of the master source */
345 pa_source_get_latency_within_thread(u->source_output->source) +
346 /* Add the latency internal to our source output on top */
347 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec) +
348 /* and the buffering we do on the source */
349 pa_bytes_to_usec(u->blocksize, &u->source_output->source->sample_spec);
350
351 return 0;
352
353 }
354
355 return pa_source_process_msg(o, code, data, offset, chunk);
356 }
357
358 /* Called from sink I/O thread context */
359 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
360 struct userdata *u = PA_SINK(o)->userdata;
361
362 switch (code) {
363
364 case PA_SINK_MESSAGE_GET_LATENCY:
365
366 /* The sink is _put() before the sink input is, so let's
367 * make sure we don't access it in that time. Also, the
368 * sink input is first shut down, the sink second. */
369 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
370 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
371 *((pa_usec_t*) data) = 0;
372 return 0;
373 }
374
375 *((pa_usec_t*) data) =
376
377 /* Get the latency of the master sink */
378 pa_sink_get_latency_within_thread(u->sink_input->sink) +
379
380 /* Add the latency internal to our sink input on top */
381 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
382
383 return 0;
384 }
385
386 return pa_sink_process_msg(o, code, data, offset, chunk);
387 }
388
389
390 /* Called from main context */
391 static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
392 struct userdata *u;
393
394 pa_source_assert_ref(s);
395 pa_assert_se(u = s->userdata);
396
397 if (!PA_SOURCE_IS_LINKED(state) ||
398 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
399 return 0;
400
401 pa_log_debug("Source state %d", state);
402
403 if (state == PA_SOURCE_RUNNING) {
404 pa_atomic_store (&u->source_active, 1);
405 pa_atomic_store (&u->request_resync, 1);
406 pa_source_output_cork(u->source_output, FALSE);
407 } else if (state == PA_SOURCE_SUSPENDED) {
408 pa_atomic_store (&u->source_active, 0);
409 pa_source_output_cork(u->source_output, TRUE);
410 }
411 return 0;
412 }
413
414 /* Called from main context */
415 static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
416 struct userdata *u;
417
418 pa_sink_assert_ref(s);
419 pa_assert_se(u = s->userdata);
420
421 if (!PA_SINK_IS_LINKED(state) ||
422 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
423 return 0;
424
425 pa_log_debug("Sink state %d", state);
426
427 if (state == PA_SINK_RUNNING) {
428 pa_atomic_store (&u->sink_active, 1);
429 pa_atomic_store (&u->request_resync, 1);
430 pa_sink_input_cork(u->sink_input, FALSE);
431 } else if (state == PA_SINK_SUSPENDED) {
432 pa_atomic_store (&u->sink_active, 0);
433 pa_sink_input_cork(u->sink_input, TRUE);
434 }
435 return 0;
436 }
437
438 /* Called from I/O thread context */
439 static void source_update_requested_latency_cb(pa_source *s) {
440 struct userdata *u;
441
442 pa_source_assert_ref(s);
443 pa_assert_se(u = s->userdata);
444
445 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
446 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state))
447 return;
448
449 pa_log_debug("Source update requested latency");
450
451 /* Just hand this one over to the master source */
452 pa_source_output_set_requested_latency_within_thread(
453 u->source_output,
454 pa_source_get_requested_latency_within_thread(s));
455 }
456
457 /* Called from I/O thread context */
458 static void sink_update_requested_latency_cb(pa_sink *s) {
459 struct userdata *u;
460
461 pa_sink_assert_ref(s);
462 pa_assert_se(u = s->userdata);
463
464 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
465 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
466 return;
467
468 pa_log_debug("Sink update requested latency");
469
470 /* Just hand this one over to the master sink */
471 pa_sink_input_set_requested_latency_within_thread(
472 u->sink_input,
473 pa_sink_get_requested_latency_within_thread(s));
474 }
475
476 /* Called from I/O thread context */
477 static void sink_request_rewind_cb(pa_sink *s) {
478 struct userdata *u;
479
480 pa_sink_assert_ref(s);
481 pa_assert_se(u = s->userdata);
482
483 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
484 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
485 return;
486
487 pa_log_debug("Sink request rewind %lld", (long long) s->thread_info.rewind_nbytes);
488
489 /* Just hand this one over to the master sink */
490 pa_sink_input_request_rewind(u->sink_input,
491 s->thread_info.rewind_nbytes, TRUE, FALSE, FALSE);
492 }
493
494 /* Called from main context */
495 static void source_set_volume_cb(pa_source *s) {
496 struct userdata *u;
497
498 pa_source_assert_ref(s);
499 pa_assert_se(u = s->userdata);
500
501 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
502 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
503 return;
504
505 /* FIXME, no volume control in source_output, set volume at the master */
506 pa_source_set_volume(u->source_output->source, &s->volume, TRUE);
507 }
508
509 /* Called from main context */
510 static void sink_set_volume_cb(pa_sink *s) {
511 struct userdata *u;
512
513 pa_sink_assert_ref(s);
514 pa_assert_se(u = s->userdata);
515
516 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
517 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
518 return;
519
520 pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
521 }
522
523 static void source_get_volume_cb(pa_source *s) {
524 struct userdata *u;
525
526 pa_source_assert_ref(s);
527 pa_assert_se(u = s->userdata);
528
529 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
530 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
531 return;
532
533 /* FIXME, no volume control in source_output, get the info from the master */
534 pa_source_get_volume(u->source_output->source, TRUE);
535
536 if (pa_cvolume_equal(&s->volume,&u->source_output->source->volume))
537 /* no change */
538 return;
539
540 s->volume = u->source_output->source->volume;
541 pa_source_set_soft_volume(s, NULL);
542 }
543
544
545 /* Called from main context */
546 static void source_set_mute_cb(pa_source *s) {
547 struct userdata *u;
548
549 pa_source_assert_ref(s);
550 pa_assert_se(u = s->userdata);
551
552 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
553 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
554 return;
555
556 /* FIXME, no volume control in source_output, set mute at the master */
557 pa_source_set_mute(u->source_output->source, TRUE, TRUE);
558 }
559
560 /* Called from main context */
561 static void sink_set_mute_cb(pa_sink *s) {
562 struct userdata *u;
563
564 pa_sink_assert_ref(s);
565 pa_assert_se(u = s->userdata);
566
567 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
568 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
569 return;
570
571 pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
572 }
573
574 /* Called from main context */
575 static void source_get_mute_cb(pa_source *s) {
576 struct userdata *u;
577
578 pa_source_assert_ref(s);
579 pa_assert_se(u = s->userdata);
580
581 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
582 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
583 return;
584
585 /* FIXME, no volume control in source_output, get the info from the master */
586 pa_source_get_mute(u->source_output->source, TRUE);
587 }
588
589 /* must be called from the input thread context */
590 static void apply_diff_time(struct userdata *u, int64_t diff_time) {
591 int64_t diff;
592
593 if (diff_time < 0) {
594 diff = pa_usec_to_bytes (-diff_time, &u->source_output->sample_spec);
595
596 if (diff > 0) {
597 pa_log_info("Playback after capture (%lld), drop sink %lld", (long long) diff_time, (long long) diff);
598
599 u->sink_skip = diff;
600 u->source_skip = 0;
601 }
602 } else if (diff_time > 0) {
603 diff = pa_usec_to_bytes (diff_time, &u->source_output->sample_spec);
604
605 if (diff > 0) {
606 pa_log_info("playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
607
608 u->source_skip = diff;
609 u->sink_skip = 0;
610 }
611 }
612 }
613
614 /* must be called from the input thread */
615 static void do_resync(struct userdata *u) {
616 int64_t diff_time;
617 struct snapshot latency_snapshot;
618
619 pa_log("Doing resync");
620
621 /* update our snapshot */
622 source_output_snapshot_within_thread(u, &latency_snapshot);
623 pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
624
625 /* calculate drift between capture and playback */
626 diff_time = calc_diff(u, &latency_snapshot);
627
628 /* and adjust for the drift */
629 apply_diff_time(u, diff_time);
630 }
631
632 /* Called from input thread context */
633 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
634 struct userdata *u;
635 size_t rlen, plen;
636
637 pa_source_output_assert_ref(o);
638 pa_source_output_assert_io_context(o);
639 pa_assert_se(u = o->userdata);
640
641 if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) {
642 pa_log("push when no link?");
643 return;
644 }
645
646 /* handle queued messages */
647 u->in_push = TRUE;
648 while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
649 ;
650 u->in_push = FALSE;
651
652 if (pa_atomic_cmpxchg (&u->request_resync, 1, 0)) {
653 do_resync (u);
654 }
655
656 pa_memblockq_push_align(u->source_memblockq, chunk);
657
658 rlen = pa_memblockq_get_length(u->source_memblockq);
659 plen = pa_memblockq_get_length(u->sink_memblockq);
660
661 while (rlen >= u->blocksize) {
662 pa_memchunk rchunk, pchunk;
663
664 /* take fixed block from recorded samples */
665 pa_memblockq_peek_fixed_size(u->source_memblockq, u->blocksize, &rchunk);
666
667 if (plen > u->blocksize && u->source_skip == 0) {
668 uint8_t *rdata, *pdata, *cdata;
669 pa_memchunk cchunk;
670
671 if (u->sink_skip) {
672 size_t to_skip;
673
674 if (u->sink_skip > plen)
675 to_skip = plen;
676 else
677 to_skip = u->sink_skip;
678
679 pa_memblockq_drop(u->sink_memblockq, to_skip);
680 plen -= to_skip;
681
682 u->sink_skip -= to_skip;
683 }
684
685 if (plen > u->blocksize && u->sink_skip == 0) {
686 /* take fixed block from played samples */
687 pa_memblockq_peek_fixed_size(u->sink_memblockq, u->blocksize, &pchunk);
688
689 rdata = pa_memblock_acquire(rchunk.memblock);
690 rdata += rchunk.index;
691 pdata = pa_memblock_acquire(pchunk.memblock);
692 pdata += pchunk.index;
693
694 cchunk.index = 0;
695 cchunk.length = u->blocksize;
696 cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
697 cdata = pa_memblock_acquire(cchunk.memblock);
698
699 /* perform echo cancelation */
700 u->ec->run(u->ec, rdata, pdata, cdata);
701
702 if (u->save_aec) {
703 if (u->captured_file)
704 fwrite(rdata, 1, u->blocksize, u->captured_file);
705 if (u->played_file)
706 fwrite(pdata, 1, u->blocksize, u->played_file);
707 if (u->canceled_file)
708 fwrite(cdata, 1, u->blocksize, u->canceled_file);
709 pa_log_debug("AEC frame saved.");
710 }
711
712 pa_memblock_release(cchunk.memblock);
713 pa_memblock_release(pchunk.memblock);
714 pa_memblock_release(rchunk.memblock);
715
716 /* drop consumed sink samples */
717 pa_memblockq_drop(u->sink_memblockq, u->blocksize);
718 pa_memblock_unref(pchunk.memblock);
719
720 pa_memblock_unref(rchunk.memblock);
721 /* the filtered samples now become the samples from our
722 * source */
723 rchunk = cchunk;
724
725 plen -= u->blocksize;
726 }
727 }
728
729 /* forward the (echo-canceled) data to the virtual source */
730 pa_source_post(u->source, &rchunk);
731 pa_memblock_unref(rchunk.memblock);
732
733 pa_memblockq_drop(u->source_memblockq, u->blocksize);
734 rlen -= u->blocksize;
735
736 if (u->source_skip) {
737 if (u->source_skip > u->blocksize) {
738 u->source_skip -= u->blocksize;
739 }
740 else {
741 u->sink_skip += (u->blocksize - u->source_skip);
742 u->source_skip = 0;
743 }
744 }
745 }
746 }
747
748 /* Called from I/O thread context */
749 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
750 struct userdata *u;
751
752 pa_sink_input_assert_ref(i);
753 pa_assert(chunk);
754 pa_assert_se(u = i->userdata);
755
756 if (u->sink->thread_info.rewind_requested)
757 pa_sink_process_rewind(u->sink, 0);
758
759 pa_sink_render_full(u->sink, nbytes, chunk);
760
761 if (i->thread_info.underrun_for > 0) {
762 pa_log_debug("Handling end of underrun.");
763 pa_atomic_store (&u->request_resync, 1);
764 }
765
766 /* let source thread handle the chunk. pass the sample count as well so that
767 * the source IO thread can update the right variables. */
768 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_POST,
769 NULL, 0, chunk, NULL);
770 u->send_counter += chunk->length;
771
772 return 0;
773 }
774
775 /* Called from input thread context */
776 static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
777 struct userdata *u;
778
779 pa_source_output_assert_ref(o);
780 pa_source_output_assert_io_context(o);
781 pa_assert_se(u = o->userdata);
782
783 pa_source_process_rewind(u->source, nbytes);
784
785 /* go back on read side, we need to use older sink data for this */
786 pa_memblockq_rewind(u->sink_memblockq, nbytes);
787
788 /* manipulate write index */
789 pa_memblockq_seek(u->source_memblockq, -nbytes, PA_SEEK_RELATIVE, TRUE);
790
791 pa_log_debug("Source rewind (%lld) %lld", (long long) nbytes,
792 (long long) pa_memblockq_get_length (u->source_memblockq));
793 }
794
795 /* Called from I/O thread context */
796 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
797 struct userdata *u;
798
799 pa_sink_input_assert_ref(i);
800 pa_assert_se(u = i->userdata);
801
802 pa_log_debug("Sink process rewind %lld", (long long) nbytes);
803
804 pa_sink_process_rewind(u->sink, nbytes);
805
806 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_REWIND, NULL, (int64_t) nbytes, NULL, NULL);
807 u->send_counter -= nbytes;
808 }
809
810 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot) {
811 size_t delay, rlen, plen;
812 pa_usec_t now, latency;
813
814 now = pa_rtclock_now();
815 latency = pa_source_get_latency_within_thread(u->source_output->source);
816 delay = pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq);
817
818 delay = (u->source_output->thread_info.resampler ? pa_resampler_request(u->source_output->thread_info.resampler, delay) : delay);
819 rlen = pa_memblockq_get_length(u->source_memblockq);
820 plen = pa_memblockq_get_length(u->sink_memblockq);
821
822 snapshot->source_now = now;
823 snapshot->source_latency = latency;
824 snapshot->source_delay = delay;
825 snapshot->recv_counter = u->recv_counter;
826 snapshot->rlen = rlen + u->sink_skip;
827 snapshot->plen = plen + u->source_skip;
828 }
829
830
831 /* Called from output thread context */
832 static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
833 struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;
834
835 switch (code) {
836
837 case SOURCE_OUTPUT_MESSAGE_POST:
838
839 pa_source_output_assert_io_context(u->source_output);
840
841 if (PA_SOURCE_IS_OPENED(u->source_output->source->thread_info.state))
842 pa_memblockq_push_align(u->sink_memblockq, chunk);
843 else
844 pa_memblockq_flush_write(u->sink_memblockq, TRUE);
845
846 u->recv_counter += (int64_t) chunk->length;
847
848 return 0;
849
850 case SOURCE_OUTPUT_MESSAGE_REWIND:
851 pa_source_output_assert_io_context(u->source_output);
852
853 /* manipulate write index, never go past what we have */
854 if (PA_SOURCE_IS_OPENED(u->source_output->source->thread_info.state))
855 pa_memblockq_seek(u->sink_memblockq, -offset, PA_SEEK_RELATIVE, TRUE);
856 else
857 pa_memblockq_flush_write(u->sink_memblockq, TRUE);
858
859 pa_log_debug("Sink rewind (%lld)", (long long) offset);
860
861 u->recv_counter -= offset;
862
863 return 0;
864
865 case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT: {
866 struct snapshot *snapshot = (struct snapshot *) data;
867
868 source_output_snapshot_within_thread(u, snapshot);
869 return 0;
870 }
871
872 case SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME:
873 apply_diff_time(u, offset);
874 return 0;
875
876 }
877
878 return pa_source_output_process_msg(obj, code, data, offset, chunk);
879 }
880
881 static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
882 struct userdata *u = PA_SINK_INPUT(obj)->userdata;
883
884 switch (code) {
885
886 case SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT: {
887 size_t delay;
888 pa_usec_t now, latency;
889 struct snapshot *snapshot = (struct snapshot *) data;
890
891 pa_sink_input_assert_io_context(u->sink_input);
892
893 now = pa_rtclock_now();
894 latency = pa_sink_get_latency_within_thread(u->sink_input->sink);
895 delay = pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq);
896
897 delay = (u->sink_input->thread_info.resampler ? pa_resampler_request(u->sink_input->thread_info.resampler, delay) : delay);
898
899 snapshot->sink_now = now;
900 snapshot->sink_latency = latency;
901 snapshot->sink_delay = delay;
902 snapshot->send_counter = u->send_counter;
903 return 0;
904 }
905 }
906
907 return pa_sink_input_process_msg(obj, code, data, offset, chunk);
908 }
909
910 /* Called from I/O thread context */
911 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
912 struct userdata *u;
913
914 pa_sink_input_assert_ref(i);
915 pa_assert_se(u = i->userdata);
916
917 pa_log_debug("Sink input update max rewind %lld", (long long) nbytes);
918
919 pa_memblockq_set_maxrewind (u->sink_memblockq, nbytes);
920 pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
921 }
922
923 /* Called from I/O thread context */
924 static void source_output_update_max_rewind_cb(pa_source_output *o, size_t nbytes) {
925 struct userdata *u;
926
927 pa_source_output_assert_ref(o);
928 pa_assert_se(u = o->userdata);
929
930 pa_log_debug("Source output update max rewind %lld", (long long) nbytes);
931
932 pa_source_set_max_rewind_within_thread(u->source, nbytes);
933 }
934
935 /* Called from I/O thread context */
936 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
937 struct userdata *u;
938
939 pa_sink_input_assert_ref(i);
940 pa_assert_se(u = i->userdata);
941
942 pa_log_debug("Sink input update max request %lld", (long long) nbytes);
943
944 pa_sink_set_max_request_within_thread(u->sink, nbytes);
945 }
946
947 /* Called from I/O thread context */
948 static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
949 struct userdata *u;
950 pa_usec_t latency;
951
952 pa_sink_input_assert_ref(i);
953 pa_assert_se(u = i->userdata);
954
955 latency = pa_sink_get_requested_latency_within_thread(i->sink);
956
957 pa_log_debug("Sink input update requested latency %lld", (long long) latency);
958 }
959
960 /* Called from I/O thread context */
961 static void source_output_update_source_requested_latency_cb(pa_source_output *o) {
962 struct userdata *u;
963 pa_usec_t latency;
964
965 pa_source_output_assert_ref(o);
966 pa_assert_se(u = o->userdata);
967
968 latency = pa_source_get_requested_latency_within_thread(o->source);
969
970 pa_log_debug("source output update requested latency %lld", (long long) latency);
971 }
972
973 /* Called from I/O thread context */
974 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
975 struct userdata *u;
976
977 pa_sink_input_assert_ref(i);
978 pa_assert_se(u = i->userdata);
979
980 pa_log_debug("Sink input update latency range %lld %lld",
981 (long long) i->sink->thread_info.min_latency,
982 (long long) i->sink->thread_info.max_latency);
983
984 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
985 }
986
987 /* Called from I/O thread context */
988 static void source_output_update_source_latency_range_cb(pa_source_output *o) {
989 struct userdata *u;
990
991 pa_source_output_assert_ref(o);
992 pa_assert_se(u = o->userdata);
993
994 pa_log_debug("Source output update latency range %lld %lld",
995 (long long) o->source->thread_info.min_latency,
996 (long long) o->source->thread_info.max_latency);
997
998 pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
999 }
1000
1001 /* Called from I/O thread context */
1002 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
1003 struct userdata *u;
1004
1005 pa_sink_input_assert_ref(i);
1006 pa_assert_se(u = i->userdata);
1007
1008 pa_log_debug("Sink input update fixed latency %lld",
1009 (long long) i->sink->thread_info.fixed_latency);
1010
1011 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
1012 }
1013
1014 /* Called from I/O thread context */
1015 static void source_output_update_source_fixed_latency_cb(pa_source_output *o) {
1016 struct userdata *u;
1017
1018 pa_source_output_assert_ref(o);
1019 pa_assert_se(u = o->userdata);
1020
1021 pa_log_debug("Source output update fixed latency %lld",
1022 (long long) o->source->thread_info.fixed_latency);
1023
1024 pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
1025 }
1026
1027 /* Called from output thread context */
1028 static void source_output_attach_cb(pa_source_output *o) {
1029 struct userdata *u;
1030
1031 pa_source_output_assert_ref(o);
1032 pa_source_output_assert_io_context(o);
1033 pa_assert_se(u = o->userdata);
1034
1035 pa_source_set_rtpoll(u->source, o->source->thread_info.rtpoll);
1036 pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
1037 pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
1038 pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
1039
1040 pa_log_debug("Source output %p attach", o);
1041
1042 pa_source_attach_within_thread(u->source);
1043
1044 u->rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
1045 o->source->thread_info.rtpoll,
1046 PA_RTPOLL_LATE,
1047 u->asyncmsgq);
1048 }
1049
1050 /* Called from I/O thread context */
1051 static void sink_input_attach_cb(pa_sink_input *i) {
1052 struct userdata *u;
1053
1054 pa_sink_input_assert_ref(i);
1055 pa_assert_se(u = i->userdata);
1056
1057 pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
1058 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1059
1060 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
1061 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
1062 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
1063
1064 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
1065 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
1066 * HERE. SEE (6) */
1067 pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
1068 pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
1069
1070 pa_log_debug("Sink input %p attach", i);
1071
1072 u->rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
1073 i->sink->thread_info.rtpoll,
1074 PA_RTPOLL_LATE,
1075 u->asyncmsgq);
1076
1077 pa_sink_attach_within_thread(u->sink);
1078 }
1079
1080
1081 /* Called from output thread context */
1082 static void source_output_detach_cb(pa_source_output *o) {
1083 struct userdata *u;
1084
1085 pa_source_output_assert_ref(o);
1086 pa_source_output_assert_io_context(o);
1087 pa_assert_se(u = o->userdata);
1088
1089 pa_source_detach_within_thread(u->source);
1090 pa_source_set_rtpoll(u->source, NULL);
1091
1092 pa_log_debug("Source output %p detach", o);
1093
1094 if (u->rtpoll_item_read) {
1095 pa_rtpoll_item_free(u->rtpoll_item_read);
1096 u->rtpoll_item_read = NULL;
1097 }
1098 }
1099
1100 /* Called from I/O thread context */
1101 static void sink_input_detach_cb(pa_sink_input *i) {
1102 struct userdata *u;
1103
1104 pa_sink_input_assert_ref(i);
1105 pa_assert_se(u = i->userdata);
1106
1107 pa_sink_detach_within_thread(u->sink);
1108
1109 pa_sink_set_rtpoll(u->sink, NULL);
1110
1111 pa_log_debug("Sink input %p detach", i);
1112
1113 if (u->rtpoll_item_write) {
1114 pa_rtpoll_item_free(u->rtpoll_item_write);
1115 u->rtpoll_item_write = NULL;
1116 }
1117 }
1118
1119 /* Called from output thread context */
1120 static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
1121 struct userdata *u;
1122
1123 pa_source_output_assert_ref(o);
1124 pa_source_output_assert_io_context(o);
1125 pa_assert_se(u = o->userdata);
1126
1127 pa_log_debug("Source output %p state %d", o, state);
1128 }
1129
1130 /* Called from IO thread context */
1131 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
1132 struct userdata *u;
1133
1134 pa_sink_input_assert_ref(i);
1135 pa_assert_se(u = i->userdata);
1136
1137 pa_log_debug("Sink input %p state %d", i, state);
1138
1139 /* If we are added for the first time, ask for a rewinding so that
1140 * we are heard right-away. */
1141 if (PA_SINK_INPUT_IS_LINKED(state) &&
1142 i->thread_info.state == PA_SINK_INPUT_INIT) {
1143 pa_log_debug("Requesting rewind due to state change.");
1144 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1145 }
1146 }
1147
1148 /* Called from main thread */
1149 static void source_output_kill_cb(pa_source_output *o) {
1150 struct userdata *u;
1151
1152 pa_source_output_assert_ref(o);
1153 pa_assert_ctl_context();
1154 pa_assert_se(u = o->userdata);
1155
1156 /* The order here matters! We first kill the source output, followed
1157 * by the source. That means the source callbacks must be protected
1158 * against an unconnected source output! */
1159 pa_source_output_unlink(u->source_output);
1160 pa_source_unlink(u->source);
1161
1162 pa_source_output_unref(u->source_output);
1163 u->source_output = NULL;
1164
1165 pa_source_unref(u->source);
1166 u->source = NULL;
1167
1168 pa_log_debug("Source output kill %p", o);
1169
1170 pa_module_unload_request(u->module, TRUE);
1171 }
1172
1173 /* Called from main context */
1174 static void sink_input_kill_cb(pa_sink_input *i) {
1175 struct userdata *u;
1176
1177 pa_sink_input_assert_ref(i);
1178 pa_assert_se(u = i->userdata);
1179
1180 /* The order here matters! We first kill the sink input, followed
1181 * by the sink. That means the sink callbacks must be protected
1182 * against an unconnected sink input! */
1183 pa_sink_input_unlink(u->sink_input);
1184 pa_sink_unlink(u->sink);
1185
1186 pa_sink_input_unref(u->sink_input);
1187 u->sink_input = NULL;
1188
1189 pa_sink_unref(u->sink);
1190 u->sink = NULL;
1191
1192 pa_log_debug("Sink input kill %p", i);
1193
1194 pa_module_unload_request(u->module, TRUE);
1195 }
1196
1197 /* Called from main thread */
1198 static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
1199 struct userdata *u;
1200
1201 pa_source_output_assert_ref(o);
1202 pa_assert_ctl_context();
1203 pa_assert_se(u = o->userdata);
1204
1205 return TRUE;
1206 }
1207
1208 /* Called from main context */
1209 static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
1210 struct userdata *u;
1211
1212 pa_sink_input_assert_ref(i);
1213 pa_assert_se(u = i->userdata);
1214
1215 return u->sink != dest;
1216 }
1217
1218 /* Called from main thread */
1219 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
1220 struct userdata *u;
1221
1222 pa_source_output_assert_ref(o);
1223 pa_assert_ctl_context();
1224 pa_assert_se(u = o->userdata);
1225
1226 if (dest) {
1227 pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
1228 pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
1229 } else
1230 pa_source_set_asyncmsgq(u->source, NULL);
1231
1232 if (u->source_auto_desc && dest) {
1233 const char *z;
1234 pa_proplist *pl;
1235
1236 pl = pa_proplist_new();
1237 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
1238 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s",
1239 pa_proplist_gets(u->source->proplist, "device.echo-cancel.name"), z ? z : dest->name);
1240
1241 pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
1242 pa_proplist_free(pl);
1243 }
1244 }
1245
1246 /* Called from main context */
1247 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
1248 struct userdata *u;
1249
1250 pa_sink_input_assert_ref(i);
1251 pa_assert_se(u = i->userdata);
1252
1253 if (dest) {
1254 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
1255 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
1256 } else
1257 pa_sink_set_asyncmsgq(u->sink, NULL);
1258
1259 if (u->sink_auto_desc && dest) {
1260 const char *z;
1261 pa_proplist *pl;
1262
1263 pl = pa_proplist_new();
1264 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
1265 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s",
1266 pa_proplist_gets(u->sink->proplist, "device.echo-cancel.name"), z ? z : dest->name);
1267
1268 pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
1269 pa_proplist_free(pl);
1270 }
1271 }
1272
1273 /* Called from main context */
1274 static void sink_input_volume_changed_cb(pa_sink_input *i) {
1275 struct userdata *u;
1276
1277 pa_sink_input_assert_ref(i);
1278 pa_assert_se(u = i->userdata);
1279
1280 pa_sink_volume_changed(u->sink, &i->volume);
1281 }
1282
1283 /* Called from main context */
1284 static void sink_input_mute_changed_cb(pa_sink_input *i) {
1285 struct userdata *u;
1286
1287 pa_sink_input_assert_ref(i);
1288 pa_assert_se(u = i->userdata);
1289
1290 pa_sink_mute_changed(u->sink, i->muted);
1291 }
1292
1293 static pa_echo_canceller_method_t get_ec_method_from_string(const char *method)
1294 {
1295 if (strcmp(method, "speex") == 0)
1296 return PA_ECHO_CANCELLER_SPEEX;
1297 else if (strcmp(method, "adrian") == 0)
1298 return PA_ECHO_CANCELLER_ADRIAN;
1299 else
1300 return PA_ECHO_CANCELLER_INVALID;
1301 }
1302
1303 int pa__init(pa_module*m) {
1304 struct userdata *u;
1305 pa_sample_spec source_ss, sink_ss;
1306 pa_channel_map source_map, sink_map;
1307 pa_modargs *ma;
1308 pa_source *source_master=NULL;
1309 pa_sink *sink_master=NULL;
1310 pa_source_output_new_data source_output_data;
1311 pa_sink_input_new_data sink_input_data;
1312 pa_source_new_data source_data;
1313 pa_sink_new_data sink_data;
1314 pa_memchunk silence;
1315 pa_echo_canceller_method_t ec_method;
1316 uint32_t adjust_time_sec;
1317
1318 pa_assert(m);
1319
1320 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1321 pa_log("Failed to parse module arguments.");
1322 goto fail;
1323 }
1324
1325 if (!(source_master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source_master", NULL), PA_NAMEREG_SOURCE))) {
1326 pa_log("Master source not found");
1327 goto fail;
1328 }
1329 pa_assert(source_master);
1330
1331 if (!(sink_master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink_master", NULL), PA_NAMEREG_SINK))) {
1332 pa_log("Master sink not found");
1333 goto fail;
1334 }
1335 pa_assert(sink_master);
1336
1337 source_ss = source_master->sample_spec;
1338 source_map = source_master->channel_map;
1339 if (pa_modargs_get_sample_spec_and_channel_map(ma, &source_ss, &source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
1340 pa_log("Invalid sample format specification or channel map");
1341 goto fail;
1342 }
1343
1344 sink_ss = sink_master->sample_spec;
1345 sink_map = sink_master->channel_map;
1346
1347 u = pa_xnew0(struct userdata, 1);
1348 if (!u) {
1349 pa_log("Failed to alloc userdata");
1350 goto fail;
1351 }
1352 u->core = m->core;
1353 u->module = m;
1354 m->userdata = u;
1355
1356 u->ec = pa_xnew0(pa_echo_canceller, 1);
1357 if (!u->ec) {
1358 pa_log("Failed to alloc echo canceller");
1359 goto fail;
1360 }
1361
1362 if ((ec_method = get_ec_method_from_string(pa_modargs_get_value(ma, "aec_method", DEFAULT_ECHO_CANCELLER))) < 0) {
1363 pa_log("Invalid echo canceller implementation");
1364 goto fail;
1365 }
1366
1367 u->ec->init = ec_table[ec_method].init;
1368 u->ec->run = ec_table[ec_method].run;
1369 u->ec->done = ec_table[ec_method].done;
1370
1371 adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
1372 if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
1373 pa_log("Failed to parse adjust_time value");
1374 goto fail;
1375 }
1376
1377 if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
1378 u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
1379 else
1380 u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
1381
1382 u->save_aec = DEFAULT_SAVE_AEC;
1383 if (pa_modargs_get_value_u32(ma, "save_aec", &u->save_aec) < 0) {
1384 pa_log("Failed to parse save_aec value");
1385 goto fail;
1386 }
1387
1388 u->asyncmsgq = pa_asyncmsgq_new(0);
1389 u->need_realign = TRUE;
1390 if (u->ec->init) {
1391 if (!u->ec->init(u->ec, &source_ss, &source_map, &sink_ss, &sink_map, &u->blocksize, pa_modargs_get_value(ma, "aec_args", NULL))) {
1392 pa_log("Failed to init AEC engine");
1393 goto fail;
1394 }
1395 }
1396
1397 /* Create source */
1398 pa_source_new_data_init(&source_data);
1399 source_data.driver = __FILE__;
1400 source_data.module = m;
1401 if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
1402 source_data.name = pa_sprintf_malloc("%s.echo-cancel", source_master->name);
1403 pa_source_new_data_set_sample_spec(&source_data, &source_ss);
1404 pa_source_new_data_set_channel_map(&source_data, &source_map);
1405 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, source_master->name);
1406 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1407 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
1408 pa_proplist_sets(source_data.proplist, "device.echo-cancel.name", source_data.name);
1409
1410 if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
1411 pa_log("Invalid properties");
1412 pa_source_new_data_done(&source_data);
1413 goto fail;
1414 }
1415
1416 if ((u->source_auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
1417 const char *z;
1418
1419 z = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1420 pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s", source_data.name, z ? z : source_master->name);
1421 }
1422
1423 u->source = pa_source_new(m->core, &source_data,
1424 PA_SOURCE_HW_MUTE_CTRL|PA_SOURCE_HW_VOLUME_CTRL|PA_SOURCE_DECIBEL_VOLUME|
1425 (source_master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)));
1426 pa_source_new_data_done(&source_data);
1427
1428 if (!u->source) {
1429 pa_log("Failed to create source.");
1430 goto fail;
1431 }
1432
1433 u->source->parent.process_msg = source_process_msg_cb;
1434 u->source->set_state = source_set_state_cb;
1435 u->source->update_requested_latency = source_update_requested_latency_cb;
1436 u->source->set_volume = source_set_volume_cb;
1437 u->source->set_mute = source_set_mute_cb;
1438 u->source->get_volume = source_get_volume_cb;
1439 u->source->get_mute = source_get_mute_cb;
1440 u->source->userdata = u;
1441
1442 pa_source_set_asyncmsgq(u->source, source_master->asyncmsgq);
1443
1444 /* Create sink */
1445 pa_sink_new_data_init(&sink_data);
1446 sink_data.driver = __FILE__;
1447 sink_data.module = m;
1448 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
1449 sink_data.name = pa_sprintf_malloc("%s.echo-cancel", sink_master->name);
1450 pa_sink_new_data_set_sample_spec(&sink_data, &sink_ss);
1451 pa_sink_new_data_set_channel_map(&sink_data, &sink_map);
1452 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, sink_master->name);
1453 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1454 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
1455 pa_proplist_sets(sink_data.proplist, "device.echo-cancel.name", sink_data.name);
1456
1457 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
1458 pa_log("Invalid properties");
1459 pa_sink_new_data_done(&sink_data);
1460 goto fail;
1461 }
1462
1463 if ((u->sink_auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
1464 const char *z;
1465
1466 z = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1467 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s", sink_data.name, z ? z : sink_master->name);
1468 }
1469
1470 u->sink = pa_sink_new(m->core, &sink_data,
1471 PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
1472 (sink_master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
1473 pa_sink_new_data_done(&sink_data);
1474
1475 if (!u->sink) {
1476 pa_log("Failed to create sink.");
1477 goto fail;
1478 }
1479
1480 u->sink->parent.process_msg = sink_process_msg_cb;
1481 u->sink->set_state = sink_set_state_cb;
1482 u->sink->update_requested_latency = sink_update_requested_latency_cb;
1483 u->sink->request_rewind = sink_request_rewind_cb;
1484 u->sink->set_volume = sink_set_volume_cb;
1485 u->sink->set_mute = sink_set_mute_cb;
1486 u->sink->userdata = u;
1487
1488 pa_sink_set_asyncmsgq(u->sink, sink_master->asyncmsgq);
1489
1490 /* Create source output */
1491 pa_source_output_new_data_init(&source_output_data);
1492 source_output_data.driver = __FILE__;
1493 source_output_data.module = m;
1494 source_output_data.source = source_master;
1495 /* FIXME
1496 source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */
1497
1498 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Source Stream");
1499 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
1500 pa_source_output_new_data_set_sample_spec(&source_output_data, &source_ss);
1501 pa_source_output_new_data_set_channel_map(&source_output_data, &source_map);
1502
1503 pa_source_output_new(&u->source_output, m->core, &source_output_data);
1504 pa_source_output_new_data_done(&source_output_data);
1505
1506 if (!u->source_output)
1507 goto fail;
1508
1509 u->source_output->parent.process_msg = source_output_process_msg_cb;
1510 u->source_output->push = source_output_push_cb;
1511 u->source_output->process_rewind = source_output_process_rewind_cb;
1512 u->source_output->update_max_rewind = source_output_update_max_rewind_cb;
1513 u->source_output->update_source_requested_latency = source_output_update_source_requested_latency_cb;
1514 u->source_output->update_source_latency_range = source_output_update_source_latency_range_cb;
1515 u->source_output->update_source_fixed_latency = source_output_update_source_fixed_latency_cb;
1516 u->source_output->kill = source_output_kill_cb;
1517 u->source_output->attach = source_output_attach_cb;
1518 u->source_output->detach = source_output_detach_cb;
1519 u->source_output->state_change = source_output_state_change_cb;
1520 u->source_output->may_move_to = source_output_may_move_to_cb;
1521 u->source_output->moving = source_output_moving_cb;
1522 u->source_output->userdata = u;
1523
1524 /* Create sink input */
1525 pa_sink_input_new_data_init(&sink_input_data);
1526 sink_input_data.driver = __FILE__;
1527 sink_input_data.module = m;
1528 sink_input_data.sink = sink_master;
1529 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");
1530 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
1531 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_ss);
1532 pa_sink_input_new_data_set_channel_map(&sink_input_data, &sink_map);
1533 sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;
1534
1535 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
1536 pa_sink_input_new_data_done(&sink_input_data);
1537
1538 if (!u->sink_input)
1539 goto fail;
1540
1541 u->sink_input->parent.process_msg = sink_input_process_msg_cb;
1542 u->sink_input->pop = sink_input_pop_cb;
1543 u->sink_input->process_rewind = sink_input_process_rewind_cb;
1544 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
1545 u->sink_input->update_max_request = sink_input_update_max_request_cb;
1546 u->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb;
1547 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
1548 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
1549 u->sink_input->kill = sink_input_kill_cb;
1550 u->sink_input->attach = sink_input_attach_cb;
1551 u->sink_input->detach = sink_input_detach_cb;
1552 u->sink_input->state_change = sink_input_state_change_cb;
1553 u->sink_input->may_move_to = sink_input_may_move_to_cb;
1554 u->sink_input->moving = sink_input_moving_cb;
1555 u->sink_input->volume_changed = sink_input_volume_changed_cb;
1556 u->sink_input->mute_changed = sink_input_mute_changed_cb;
1557 u->sink_input->userdata = u;
1558
1559 pa_sink_input_get_silence(u->sink_input, &silence);
1560
1561 u->source_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0,
1562 pa_frame_size(&source_ss), 1, 1, 0, &silence);
1563 u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0,
1564 pa_frame_size(&sink_ss), 1, 1, 0, &silence);
1565
1566 pa_memblock_unref(silence.memblock);
1567
1568 if (!u->source_memblockq || !u->sink_memblockq) {
1569 pa_log("Failed to create memblockq.");
1570 goto fail;
1571 }
1572
1573 if (u->adjust_time > 0)
1574 u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
1575
1576 if (u->save_aec) {
1577 pa_log("Creating AEC files in /tmp");
1578 u->captured_file = fopen("/tmp/aec_rec.sw", "wb");
1579 if (u->captured_file == NULL)
1580 perror ("fopen failed");
1581 u->played_file = fopen("/tmp/aec_play.sw", "wb");
1582 if (u->played_file == NULL)
1583 perror ("fopen failed");
1584 u->canceled_file = fopen("/tmp/aec_out.sw", "wb");
1585 if (u->canceled_file == NULL)
1586 perror ("fopen failed");
1587 }
1588
1589 pa_sink_put(u->sink);
1590 pa_source_put(u->source);
1591
1592 pa_sink_input_put(u->sink_input);
1593 pa_source_output_put(u->source_output);
1594
1595 pa_modargs_free(ma);
1596
1597 return 0;
1598
1599 fail:
1600 if (ma)
1601 pa_modargs_free(ma);
1602
1603 pa__done(m);
1604
1605 return -1;
1606 }
1607
1608 int pa__get_n_used(pa_module *m) {
1609 struct userdata *u;
1610
1611 pa_assert(m);
1612 pa_assert_se(u = m->userdata);
1613
1614 return pa_sink_linked_by(u->sink) + pa_source_linked_by(u->source);
1615 }
1616
1617 void pa__done(pa_module*m) {
1618 struct userdata *u;
1619
1620 pa_assert(m);
1621
1622 if (!(u = m->userdata))
1623 return;
1624
1625 /* See comments in source_output_kill_cb() above regarding
1626 * destruction order! */
1627
1628 if (u->source_output)
1629 pa_source_output_unlink(u->source_output);
1630 if (u->sink_input)
1631 pa_sink_input_unlink(u->sink_input);
1632
1633 if (u->source)
1634 pa_source_unlink(u->source);
1635 if (u->sink)
1636 pa_sink_unlink(u->sink);
1637
1638 if (u->source_output)
1639 pa_source_output_unref(u->source_output);
1640 if (u->sink_input)
1641 pa_sink_input_unref(u->sink_input);
1642
1643 if (u->source)
1644 pa_source_unref(u->source);
1645 if (u->sink)
1646 pa_sink_unref(u->sink);
1647
1648 if (u->time_event)
1649 u->core->mainloop->time_free(u->time_event);
1650
1651 if (u->source_memblockq)
1652 pa_memblockq_free(u->source_memblockq);
1653 if (u->sink_memblockq)
1654 pa_memblockq_free(u->sink_memblockq);
1655
1656 if (u->ec) {
1657 if (u->ec->done)
1658 u->ec->done(u->ec);
1659
1660 pa_xfree(u->ec);
1661 }
1662
1663 if (u->asyncmsgq)
1664 pa_asyncmsgq_unref(u->asyncmsgq);
1665
1666 pa_xfree(u);
1667 }