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