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, see <http://www.gnu.org/licenses/>.
25 ***/
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <math.h>
33
34 #include "echo-cancel.h"
35
36 #include <pulse/xmalloc.h>
37 #include <pulse/timeval.h>
38 #include <pulse/rtclock.h>
39
40 #include <pulsecore/i18n.h>
41 #include <pulsecore/atomic.h>
42 #include <pulsecore/macro.h>
43 #include <pulsecore/namereg.h>
44 #include <pulsecore/sink.h>
45 #include <pulsecore/module.h>
46 #include <pulsecore/core-rtclock.h>
47 #include <pulsecore/core-util.h>
48 #include <pulsecore/modargs.h>
49 #include <pulsecore/log.h>
50 #include <pulsecore/rtpoll.h>
51 #include <pulsecore/sample-util.h>
52 #include <pulsecore/ltdl-helper.h>
53
54 PA_MODULE_AUTHOR("Wim Taymans");
55 PA_MODULE_DESCRIPTION("Echo Cancellation");
56 PA_MODULE_VERSION(PACKAGE_VERSION);
57 PA_MODULE_LOAD_ONCE(false);
58 PA_MODULE_USAGE(
59 _("source_name=<name for the source> "
60 "source_properties=<properties for the source> "
61 "source_master=<name of source to filter> "
62 "sink_name=<name for the sink> "
63 "sink_properties=<properties for the sink> "
64 "sink_master=<name of sink to filter> "
65 "adjust_time=<how often to readjust rates in s> "
66 "adjust_threshold=<how much drift to readjust after in ms> "
67 "format=<sample format> "
68 "rate=<sample rate> "
69 "channels=<number of channels> "
70 "channel_map=<channel map> "
71 "aec_method=<implementation to use> "
72 "aec_args=<parameters for the AEC engine> "
73 "save_aec=<save AEC data in /tmp> "
74 "autoloaded=<set if this module is being loaded automatically> "
75 "use_volume_sharing=<yes or no> "
76 "use_master_format=<yes or no> "
77 ));
78
79 /* NOTE: Make sure the enum and ec_table are maintained in the correct order */
80 typedef enum {
81 PA_ECHO_CANCELLER_INVALID = -1,
82 PA_ECHO_CANCELLER_NULL,
83 #ifdef HAVE_SPEEX
84 PA_ECHO_CANCELLER_SPEEX,
85 #endif
86 #ifdef HAVE_ADRIAN_EC
87 PA_ECHO_CANCELLER_ADRIAN,
88 #endif
89 #ifdef HAVE_WEBRTC
90 PA_ECHO_CANCELLER_WEBRTC,
91 #endif
92 } pa_echo_canceller_method_t;
93
94 #ifdef HAVE_WEBRTC
95 #define DEFAULT_ECHO_CANCELLER "webrtc"
96 #else
97 #define DEFAULT_ECHO_CANCELLER "speex"
98 #endif
99
100 static const pa_echo_canceller ec_table[] = {
101 {
102 /* Null, Dummy echo canceller (just copies data) */
103 .init = pa_null_ec_init,
104 .run = pa_null_ec_run,
105 .done = pa_null_ec_done,
106 },
107 #ifdef HAVE_SPEEX
108 {
109 /* Speex */
110 .init = pa_speex_ec_init,
111 .run = pa_speex_ec_run,
112 .done = pa_speex_ec_done,
113 },
114 #endif
115 #ifdef HAVE_ADRIAN_EC
116 {
117 /* Adrian Andre's NLMS implementation */
118 .init = pa_adrian_ec_init,
119 .run = pa_adrian_ec_run,
120 .done = pa_adrian_ec_done,
121 },
122 #endif
123 #ifdef HAVE_WEBRTC
124 {
125 /* WebRTC's audio processing engine */
126 .init = pa_webrtc_ec_init,
127 .play = pa_webrtc_ec_play,
128 .record = pa_webrtc_ec_record,
129 .set_drift = pa_webrtc_ec_set_drift,
130 .run = pa_webrtc_ec_run,
131 .done = pa_webrtc_ec_done,
132 },
133 #endif
134 };
135
136 #define DEFAULT_RATE 32000
137 #define DEFAULT_CHANNELS 1
138 #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC)
139 #define DEFAULT_ADJUST_TOLERANCE (5*PA_USEC_PER_MSEC)
140 #define DEFAULT_SAVE_AEC false
141 #define DEFAULT_AUTOLOADED false
142 #define DEFAULT_USE_MASTER_FORMAT false
143
144 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
145
146 #define MAX_LATENCY_BLOCKS 10
147
148 /* Can only be used in main context */
149 #define IS_ACTIVE(u) (((u)->source->state == PA_SOURCE_RUNNING) && \
150 ((u)->sink->state == PA_SINK_RUNNING))
151
152 /* This module creates a new (virtual) source and sink.
153 *
154 * The data sent to the new sink is kept in a memblockq before being
155 * forwarded to the real sink_master.
156 *
157 * Data read from source_master is matched against the saved sink data and
158 * echo canceled data is then pushed onto the new source.
159 *
160 * Both source and sink masters have their own threads to push/pull data
161 * respectively. We however perform all our actions in the source IO thread.
162 * To do this we send all played samples to the source IO thread where they
163 * are then pushed into the memblockq.
164 *
165 * Alignment is performed in two steps:
166 *
167 * 1) when something happens that requires quick adjustment of the alignment of
168 * capture and playback samples, we perform a resync. This adjusts the
169 * position in the playback memblock to the requested sample. Quick
170 * adjustments include moving the playback samples before the capture
171 * samples (because else the echo canceller does not work) or when the
172 * playback pointer drifts too far away.
173 *
174 * 2) periodically check the difference between capture and playback. We use a
175 * low and high watermark for adjusting the alignment. Playback should always
176 * be before capture and the difference should not be bigger than one frame
177 * size. We would ideally like to resample the sink_input but most driver
178 * don't give enough accuracy to be able to do that right now.
179 */
180
181 struct userdata;
182
183 struct pa_echo_canceller_msg {
184 pa_msgobject parent;
185 bool dead;
186 struct userdata *userdata;
187 };
188
189 PA_DEFINE_PRIVATE_CLASS(pa_echo_canceller_msg, pa_msgobject);
190 #define PA_ECHO_CANCELLER_MSG(o) (pa_echo_canceller_msg_cast(o))
191
192 struct snapshot {
193 pa_usec_t sink_now;
194 pa_usec_t sink_latency;
195 size_t sink_delay;
196 int64_t send_counter;
197
198 pa_usec_t source_now;
199 pa_usec_t source_latency;
200 size_t source_delay;
201 int64_t recv_counter;
202 size_t rlen;
203 size_t plen;
204 };
205
206 struct userdata {
207 pa_core *core;
208 pa_module *module;
209
210 bool dead;
211 bool save_aec;
212
213 pa_echo_canceller *ec;
214 uint32_t source_output_blocksize;
215 uint32_t source_blocksize;
216 uint32_t sink_blocksize;
217
218 bool need_realign;
219
220 /* to wakeup the source I/O thread */
221 pa_asyncmsgq *asyncmsgq;
222 pa_rtpoll_item *rtpoll_item_read, *rtpoll_item_write;
223
224 pa_source *source;
225 bool source_auto_desc;
226 pa_source_output *source_output;
227 pa_memblockq *source_memblockq; /* echo canceller needs fixed sized chunks */
228 size_t source_skip;
229
230 pa_sink *sink;
231 bool sink_auto_desc;
232 pa_sink_input *sink_input;
233 pa_memblockq *sink_memblockq;
234 int64_t send_counter; /* updated in sink IO thread */
235 int64_t recv_counter;
236 size_t sink_skip;
237
238 /* Bytes left over from previous iteration */
239 size_t sink_rem;
240 size_t source_rem;
241
242 pa_atomic_t request_resync;
243
244 pa_time_event *time_event;
245 pa_usec_t adjust_time;
246 int adjust_threshold;
247
248 FILE *captured_file;
249 FILE *played_file;
250 FILE *canceled_file;
251 FILE *drift_file;
252
253 bool use_volume_sharing;
254
255 struct {
256 pa_cvolume current_volume;
257 } thread_info;
258 };
259
260 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot);
261
262 static const char* const valid_modargs[] = {
263 "source_name",
264 "source_properties",
265 "source_master",
266 "sink_name",
267 "sink_properties",
268 "sink_master",
269 "adjust_time",
270 "adjust_threshold",
271 "format",
272 "rate",
273 "channels",
274 "channel_map",
275 "aec_method",
276 "aec_args",
277 "save_aec",
278 "autoloaded",
279 "use_volume_sharing",
280 "use_master_format",
281 NULL
282 };
283
284 enum {
285 SOURCE_OUTPUT_MESSAGE_POST = PA_SOURCE_OUTPUT_MESSAGE_MAX,
286 SOURCE_OUTPUT_MESSAGE_REWIND,
287 SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT,
288 SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
289 };
290
291 enum {
292 SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
293 };
294
295 enum {
296 ECHO_CANCELLER_MESSAGE_SET_VOLUME,
297 };
298
calc_diff(struct userdata * u,struct snapshot * snapshot)299 static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
300 int64_t diff_time, buffer_latency;
301 pa_usec_t plen, rlen, source_delay, sink_delay, recv_counter, send_counter;
302
303 /* get latency difference between playback and record */
304 plen = pa_bytes_to_usec(snapshot->plen, &u->sink_input->sample_spec);
305 rlen = pa_bytes_to_usec(snapshot->rlen, &u->source_output->sample_spec);
306 if (plen > rlen)
307 buffer_latency = plen - rlen;
308 else
309 buffer_latency = 0;
310
311 source_delay = pa_bytes_to_usec(snapshot->source_delay, &u->source_output->sample_spec);
312 sink_delay = pa_bytes_to_usec(snapshot->sink_delay, &u->sink_input->sample_spec);
313 buffer_latency += source_delay + sink_delay;
314
315 /* add the latency difference due to samples not yet transferred */
316 send_counter = pa_bytes_to_usec(snapshot->send_counter, &u->sink->sample_spec);
317 recv_counter = pa_bytes_to_usec(snapshot->recv_counter, &u->sink->sample_spec);
318 if (recv_counter <= send_counter)
319 buffer_latency += (int64_t) (send_counter - recv_counter);
320 else
321 buffer_latency = PA_CLIP_SUB(buffer_latency, (int64_t) (recv_counter - send_counter));
322
323 /* capture and playback are perfectly aligned when diff_time is 0 */
324 diff_time = (snapshot->sink_now + snapshot->sink_latency - buffer_latency) -
325 (snapshot->source_now - snapshot->source_latency);
326
327 pa_log_debug("Diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time,
328 (long long) snapshot->sink_latency,
329 (long long) buffer_latency, (long long) snapshot->source_latency,
330 (long long) source_delay, (long long) sink_delay,
331 (long long) (send_counter - recv_counter),
332 (long long) (snapshot->sink_now - snapshot->source_now));
333
334 return diff_time;
335 }
336
337 /* Called from main context */
time_callback(pa_mainloop_api * a,pa_time_event * e,const struct timeval * t,void * userdata)338 static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
339 struct userdata *u = userdata;
340 uint32_t old_rate, base_rate, new_rate;
341 int64_t diff_time;
342 /*size_t fs*/
343 struct snapshot latency_snapshot;
344
345 pa_assert(u);
346 pa_assert(a);
347 pa_assert(u->time_event == e);
348 pa_assert_ctl_context();
349
350 if (!IS_ACTIVE(u))
351 return;
352
353 /* update our snapshots */
354 pa_asyncmsgq_send(u->source_output->source->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
355 pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
356
357 /* calculate drift between capture and playback */
358 diff_time = calc_diff(u, &latency_snapshot);
359
360 /*fs = pa_frame_size(&u->source_output->sample_spec);*/
361 old_rate = u->sink_input->sample_spec.rate;
362 base_rate = u->source_output->sample_spec.rate;
363
364 if (diff_time < 0) {
365 /* recording before playback, we need to adjust quickly. The echo
366 * canceller does not work in this case. */
367 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
368 NULL, diff_time, NULL, NULL);
369 /*new_rate = base_rate - ((pa_usec_to_bytes(-diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
370 new_rate = base_rate;
371 }
372 else {
373 if (diff_time > u->adjust_threshold) {
374 /* diff too big, quickly adjust */
375 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
376 NULL, diff_time, NULL, NULL);
377 }
378
379 /* recording behind playback, we need to slowly adjust the rate to match */
380 /*new_rate = base_rate + ((pa_usec_to_bytes(diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
381
382 /* assume equal samplerates for now */
383 new_rate = base_rate;
384 }
385
386 /* make sure we don't make too big adjustments because that sounds horrible */
387 if (new_rate > base_rate * 1.1 || new_rate < base_rate * 0.9)
388 new_rate = base_rate;
389
390 if (new_rate != old_rate) {
391 pa_log_info("Old rate %lu Hz, new rate %lu Hz", (unsigned long) old_rate, (unsigned long) new_rate);
392
393 pa_sink_input_set_rate(u->sink_input, new_rate);
394 }
395
396 pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
397 }
398
399 /* Called from source I/O thread context */
source_process_msg_cb(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)400 static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
401 struct userdata *u = PA_SOURCE(o)->userdata;
402
403 switch (code) {
404
405 case PA_SOURCE_MESSAGE_GET_LATENCY:
406
407 /* The source is _put() before the source output is, so let's
408 * make sure we don't access it in that time. Also, the
409 * source output is first shut down, the source second. */
410 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
411 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) {
412 *((int64_t*) data) = 0;
413 return 0;
414 }
415
416 *((int64_t*) data) =
417
418 /* Get the latency of the master source */
419 pa_source_get_latency_within_thread(u->source_output->source, true) +
420 /* Add the latency internal to our source output on top */
421 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec) +
422 /* and the buffering we do on the source */
423 pa_bytes_to_usec(u->source_output_blocksize, &u->source_output->source->sample_spec);
424
425 return 0;
426
427 case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED:
428 u->thread_info.current_volume = u->source->reference_volume;
429 break;
430 }
431
432 return pa_source_process_msg(o, code, data, offset, chunk);
433 }
434
435 /* Called from sink I/O thread context */
sink_process_msg_cb(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)436 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
437 struct userdata *u = PA_SINK(o)->userdata;
438
439 switch (code) {
440
441 case PA_SINK_MESSAGE_GET_LATENCY:
442
443 /* The sink is _put() before the sink input is, so let's
444 * make sure we don't access it in that time. Also, the
445 * sink input is first shut down, the sink second. */
446 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
447 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
448 *((int64_t*) data) = 0;
449 return 0;
450 }
451
452 *((int64_t*) data) =
453
454 /* Get the latency of the master sink */
455 pa_sink_get_latency_within_thread(u->sink_input->sink, true) +
456
457 /* Add the latency internal to our sink input on top */
458 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
459
460 return 0;
461 }
462
463 return pa_sink_process_msg(o, code, data, offset, chunk);
464 }
465
466 /* Called from main context */
source_set_state_in_main_thread_cb(pa_source * s,pa_source_state_t state,pa_suspend_cause_t suspend_cause)467 static int source_set_state_in_main_thread_cb(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
468 struct userdata *u;
469
470 pa_source_assert_ref(s);
471 pa_assert_se(u = s->userdata);
472
473 if (!PA_SOURCE_IS_LINKED(state) ||
474 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->state))
475 return 0;
476
477 if (state == PA_SOURCE_RUNNING) {
478 /* restart timer when both sink and source are active */
479 if ((u->sink->state == PA_SINK_RUNNING) && u->adjust_time)
480 pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
481
482 pa_atomic_store(&u->request_resync, 1);
483 pa_source_output_cork(u->source_output, false);
484 } else if (state == PA_SOURCE_SUSPENDED) {
485 pa_source_output_cork(u->source_output, true);
486 }
487
488 return 0;
489 }
490
491 /* Called from main context */
sink_set_state_in_main_thread_cb(pa_sink * s,pa_sink_state_t state,pa_suspend_cause_t suspend_cause)492 static int sink_set_state_in_main_thread_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
493 struct userdata *u;
494
495 pa_sink_assert_ref(s);
496 pa_assert_se(u = s->userdata);
497
498 if (!PA_SINK_IS_LINKED(state) ||
499 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
500 return 0;
501
502 if (state == PA_SINK_RUNNING) {
503 /* restart timer when both sink and source are active */
504 if ((u->source->state == PA_SOURCE_RUNNING) && u->adjust_time)
505 pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
506
507 pa_atomic_store(&u->request_resync, 1);
508 pa_sink_input_cork(u->sink_input, false);
509 } else if (state == PA_SINK_SUSPENDED) {
510 pa_sink_input_cork(u->sink_input, true);
511 }
512
513 return 0;
514 }
515
516 /* Called from the IO thread. */
sink_set_state_in_io_thread_cb(pa_sink * s,pa_sink_state_t new_state,pa_suspend_cause_t new_suspend_cause)517 static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
518 struct userdata *u;
519
520 pa_assert(s);
521 pa_assert_se(u = s->userdata);
522
523 /* When set to running or idle for the first time, request a rewind
524 * of the master sink to make sure we are heard immediately */
525 if (PA_SINK_IS_OPENED(new_state) && s->thread_info.state == PA_SINK_INIT) {
526 pa_log_debug("Requesting rewind due to state change.");
527 pa_sink_input_request_rewind(u->sink_input, 0, false, true, true);
528 }
529
530 return 0;
531 }
532
533 /* Called from source I/O thread context */
source_update_requested_latency_cb(pa_source * s)534 static void source_update_requested_latency_cb(pa_source *s) {
535 struct userdata *u;
536 pa_usec_t latency;
537
538 pa_source_assert_ref(s);
539 pa_assert_se(u = s->userdata);
540
541 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
542 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state))
543 return;
544
545 pa_log_debug("Source update requested latency");
546
547 /* Cap the maximum latency so we don't have to process too large chunks */
548 latency = PA_MIN(pa_source_get_requested_latency_within_thread(s),
549 pa_bytes_to_usec(u->source_blocksize, &s->sample_spec) * MAX_LATENCY_BLOCKS);
550
551 pa_source_output_set_requested_latency_within_thread(u->source_output, latency);
552 }
553
554 /* Called from sink I/O thread context */
sink_update_requested_latency_cb(pa_sink * s)555 static void sink_update_requested_latency_cb(pa_sink *s) {
556 struct userdata *u;
557 pa_usec_t latency;
558
559 pa_sink_assert_ref(s);
560 pa_assert_se(u = s->userdata);
561
562 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
563 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
564 return;
565
566 pa_log_debug("Sink update requested latency");
567
568 /* Cap the maximum latency so we don't have to process too large chunks */
569 latency = PA_MIN(pa_sink_get_requested_latency_within_thread(s),
570 pa_bytes_to_usec(u->sink_blocksize, &s->sample_spec) * MAX_LATENCY_BLOCKS);
571
572 pa_sink_input_set_requested_latency_within_thread(u->sink_input, latency);
573 }
574
575 /* Called from sink I/O thread context */
sink_request_rewind_cb(pa_sink * s)576 static void sink_request_rewind_cb(pa_sink *s) {
577 struct userdata *u;
578
579 pa_sink_assert_ref(s);
580 pa_assert_se(u = s->userdata);
581
582 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
583 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
584 return;
585
586 pa_log_debug("Sink request rewind %lld", (long long) s->thread_info.rewind_nbytes);
587
588 /* Just hand this one over to the master sink */
589 pa_sink_input_request_rewind(u->sink_input,
590 s->thread_info.rewind_nbytes, true, false, false);
591 }
592
593 /* Called from main context */
source_set_volume_cb(pa_source * s)594 static void source_set_volume_cb(pa_source *s) {
595 struct userdata *u;
596
597 pa_source_assert_ref(s);
598 pa_assert_se(u = s->userdata);
599
600 if (!PA_SOURCE_IS_LINKED(s->state) ||
601 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->state))
602 return;
603
604 pa_source_output_set_volume(u->source_output, &s->real_volume, s->save_volume, true);
605 }
606
607 /* Called from main context */
sink_set_volume_cb(pa_sink * s)608 static void sink_set_volume_cb(pa_sink *s) {
609 struct userdata *u;
610
611 pa_sink_assert_ref(s);
612 pa_assert_se(u = s->userdata);
613
614 if (!PA_SINK_IS_LINKED(s->state) ||
615 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
616 return;
617
618 pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true);
619 }
620
621 /* Called from main context. */
source_get_volume_cb(pa_source * s)622 static void source_get_volume_cb(pa_source *s) {
623 struct userdata *u;
624 pa_cvolume v;
625
626 pa_source_assert_ref(s);
627 pa_assert_se(u = s->userdata);
628
629 if (!PA_SOURCE_IS_LINKED(s->state) ||
630 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->state))
631 return;
632
633 pa_source_output_get_volume(u->source_output, &v, true);
634
635 if (pa_cvolume_equal(&s->real_volume, &v))
636 /* no change */
637 return;
638
639 s->real_volume = v;
640 pa_source_set_soft_volume(s, NULL);
641 }
642
643 /* Called from main context */
source_set_mute_cb(pa_source * s)644 static void source_set_mute_cb(pa_source *s) {
645 struct userdata *u;
646
647 pa_source_assert_ref(s);
648 pa_assert_se(u = s->userdata);
649
650 if (!PA_SOURCE_IS_LINKED(s->state) ||
651 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->state))
652 return;
653
654 pa_source_output_set_mute(u->source_output, s->muted, s->save_muted);
655 }
656
657 /* Called from main context */
sink_set_mute_cb(pa_sink * s)658 static void sink_set_mute_cb(pa_sink *s) {
659 struct userdata *u;
660
661 pa_sink_assert_ref(s);
662 pa_assert_se(u = s->userdata);
663
664 if (!PA_SINK_IS_LINKED(s->state) ||
665 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
666 return;
667
668 pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
669 }
670
671 /* Called from source I/O thread context. */
apply_diff_time(struct userdata * u,int64_t diff_time)672 static void apply_diff_time(struct userdata *u, int64_t diff_time) {
673 int64_t diff;
674
675 if (diff_time < 0) {
676 diff = pa_usec_to_bytes(-diff_time, &u->sink_input->sample_spec);
677
678 if (diff > 0) {
679 /* add some extra safety samples to compensate for jitter in the
680 * timings */
681 diff += 10 * pa_frame_size (&u->sink_input->sample_spec);
682
683 pa_log("Playback after capture (%lld), drop sink %lld", (long long) diff_time, (long long) diff);
684
685 u->sink_skip = diff;
686 u->source_skip = 0;
687 }
688 } else if (diff_time > 0) {
689 diff = pa_usec_to_bytes(diff_time, &u->source_output->sample_spec);
690
691 if (diff > 0) {
692 pa_log("Playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
693
694 u->source_skip = diff;
695 u->sink_skip = 0;
696 }
697 }
698 }
699
700 /* Called from source I/O thread context. */
do_resync(struct userdata * u)701 static void do_resync(struct userdata *u) {
702 int64_t diff_time;
703 struct snapshot latency_snapshot;
704
705 pa_log("Doing resync");
706
707 /* update our snapshot */
708 /* 1. Get sink input latency snapshot, might cause buffers to be sent to source thread */
709 pa_asyncmsgq_send(u->sink_input->sink->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT, &latency_snapshot, 0, NULL);
710 /* 2. Pick up any in-flight buffers (and discard if needed) */
711 while (pa_asyncmsgq_process_one(u->asyncmsgq))
712 ;
713 /* 3. Now get the source output latency snapshot */
714 source_output_snapshot_within_thread(u, &latency_snapshot);
715
716 /* calculate drift between capture and playback */
717 diff_time = calc_diff(u, &latency_snapshot);
718
719 /* and adjust for the drift */
720 apply_diff_time(u, diff_time);
721 }
722
723 /* 1. Calculate drift at this point, pass to canceller
724 * 2. Push out playback samples in blocksize chunks
725 * 3. Push out capture samples in blocksize chunks
726 * 4. ???
727 * 5. Profit
728 *
729 * Called from source I/O thread context.
730 */
do_push_drift_comp(struct userdata * u)731 static void do_push_drift_comp(struct userdata *u) {
732 size_t rlen, plen;
733 pa_memchunk rchunk, pchunk, cchunk;
734 uint8_t *rdata, *pdata, *cdata;
735 float drift;
736 int unused PA_GCC_UNUSED;
737
738 rlen = pa_memblockq_get_length(u->source_memblockq);
739 plen = pa_memblockq_get_length(u->sink_memblockq);
740
741 /* Estimate snapshot drift as follows:
742 * pd: amount of data consumed since last time
743 * rd: amount of data consumed since last time
744 *
745 * drift = (pd - rd) / rd;
746 *
747 * We calculate pd and rd as the memblockq length less the number of
748 * samples left from the last iteration (to avoid double counting
749 * those remainder samples.
750 */
751 drift = ((float)(plen - u->sink_rem) - (rlen - u->source_rem)) / ((float)(rlen - u->source_rem));
752 u->sink_rem = plen % u->sink_blocksize;
753 u->source_rem = rlen % u->source_output_blocksize;
754
755 if (u->save_aec) {
756 if (u->drift_file)
757 fprintf(u->drift_file, "d %a\n", drift);
758 }
759
760 /* Send in the playback samples first */
761 while (plen >= u->sink_blocksize) {
762 pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
763 pdata = pa_memblock_acquire(pchunk.memblock);
764 pdata += pchunk.index;
765
766 u->ec->play(u->ec, pdata);
767
768 if (u->save_aec) {
769 if (u->drift_file)
770 fprintf(u->drift_file, "p %d\n", u->sink_blocksize);
771 if (u->played_file)
772 unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
773 }
774
775 pa_memblock_release(pchunk.memblock);
776 pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
777 pa_memblock_unref(pchunk.memblock);
778
779 plen -= u->sink_blocksize;
780 }
781
782 /* And now the capture samples */
783 while (rlen >= u->source_output_blocksize) {
784 pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_output_blocksize, &rchunk);
785
786 rdata = pa_memblock_acquire(rchunk.memblock);
787 rdata += rchunk.index;
788
789 cchunk.index = 0;
790 cchunk.length = u->source_output_blocksize;
791 cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
792 cdata = pa_memblock_acquire(cchunk.memblock);
793
794 u->ec->set_drift(u->ec, drift);
795 u->ec->record(u->ec, rdata, cdata);
796
797 if (u->save_aec) {
798 if (u->drift_file)
799 fprintf(u->drift_file, "c %d\n", u->source_output_blocksize);
800 if (u->captured_file)
801 unused = fwrite(rdata, 1, u->source_output_blocksize, u->captured_file);
802 if (u->canceled_file)
803 unused = fwrite(cdata, 1, u->source_output_blocksize, u->canceled_file);
804 }
805
806 pa_memblock_release(cchunk.memblock);
807 pa_memblock_release(rchunk.memblock);
808
809 pa_memblock_unref(rchunk.memblock);
810
811 pa_source_post(u->source, &cchunk);
812 pa_memblock_unref(cchunk.memblock);
813
814 pa_memblockq_drop(u->source_memblockq, u->source_output_blocksize);
815 rlen -= u->source_output_blocksize;
816 }
817 }
818
819 /* This one's simpler than the drift compensation case -- we just iterate over
820 * the capture buffer, and pass the canceller blocksize bytes of playback and
821 * capture data. If playback is currently inactive, we just push silence.
822 *
823 * Called from source I/O thread context. */
do_push(struct userdata * u)824 static void do_push(struct userdata *u) {
825 size_t rlen, plen;
826 pa_memchunk rchunk, pchunk, cchunk;
827 uint8_t *rdata, *pdata, *cdata;
828 int unused PA_GCC_UNUSED;
829
830 rlen = pa_memblockq_get_length(u->source_memblockq);
831 plen = pa_memblockq_get_length(u->sink_memblockq);
832
833 while (rlen >= u->source_output_blocksize) {
834
835 /* take fixed blocks from recorded and played samples */
836 pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_output_blocksize, &rchunk);
837 pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
838
839 /* we ran out of played data and pchunk has been filled with silence bytes */
840 if (plen < u->sink_blocksize)
841 pa_memblockq_seek(u->sink_memblockq, u->sink_blocksize - plen, PA_SEEK_RELATIVE, true);
842
843 rdata = pa_memblock_acquire(rchunk.memblock);
844 rdata += rchunk.index;
845 pdata = pa_memblock_acquire(pchunk.memblock);
846 pdata += pchunk.index;
847
848 cchunk.index = 0;
849 cchunk.length = u->source_blocksize;
850 cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
851 cdata = pa_memblock_acquire(cchunk.memblock);
852
853 if (u->save_aec) {
854 if (u->captured_file)
855 unused = fwrite(rdata, 1, u->source_output_blocksize, u->captured_file);
856 if (u->played_file)
857 unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
858 }
859
860 /* perform echo cancellation */
861 u->ec->run(u->ec, rdata, pdata, cdata);
862
863 if (u->save_aec) {
864 if (u->canceled_file)
865 unused = fwrite(cdata, 1, u->source_blocksize, u->canceled_file);
866 }
867
868 pa_memblock_release(cchunk.memblock);
869 pa_memblock_release(pchunk.memblock);
870 pa_memblock_release(rchunk.memblock);
871
872 /* drop consumed source samples */
873 pa_memblockq_drop(u->source_memblockq, u->source_output_blocksize);
874 pa_memblock_unref(rchunk.memblock);
875 rlen -= u->source_output_blocksize;
876
877 /* drop consumed sink samples */
878 pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
879 pa_memblock_unref(pchunk.memblock);
880
881 if (plen >= u->sink_blocksize)
882 plen -= u->sink_blocksize;
883 else
884 plen = 0;
885
886 /* forward the (echo-canceled) data to the virtual source */
887 pa_source_post(u->source, &cchunk);
888 pa_memblock_unref(cchunk.memblock);
889 }
890 }
891
892 /* Called from source I/O thread context. */
source_output_push_cb(pa_source_output * o,const pa_memchunk * chunk)893 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
894 struct userdata *u;
895 size_t rlen, plen, to_skip;
896 pa_memchunk rchunk;
897
898 pa_source_output_assert_ref(o);
899 pa_source_output_assert_io_context(o);
900 pa_assert_se(u = o->userdata);
901
902 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state))
903 return;
904
905 if (!PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) {
906 pa_log("Push when no link?");
907 return;
908 }
909
910 /* handle queued messages, do any message sending of our own */
911 while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
912 ;
913
914 pa_memblockq_push_align(u->source_memblockq, chunk);
915
916 rlen = pa_memblockq_get_length(u->source_memblockq);
917 plen = pa_memblockq_get_length(u->sink_memblockq);
918
919 /* Let's not do anything else till we have enough data to process */
920 if (rlen < u->source_output_blocksize)
921 return;
922
923 /* See if we need to drop samples in order to sync */
924 if (pa_atomic_cmpxchg (&u->request_resync, 1, 0)) {
925 do_resync(u);
926 }
927
928 /* Okay, skip cancellation for skipped source samples if needed. */
929 if (PA_UNLIKELY(u->source_skip)) {
930 /* The slightly tricky bit here is that we drop all but modulo
931 * blocksize bytes and then adjust for that last bit on the sink side.
932 * We do this because the source data is coming at a fixed rate, which
933 * means the only way to try to catch up is drop sink samples and let
934 * the canceller cope up with this. */
935 to_skip = rlen >= u->source_skip ? u->source_skip : rlen;
936 to_skip -= to_skip % u->source_output_blocksize;
937
938 if (to_skip) {
939 pa_memblockq_peek_fixed_size(u->source_memblockq, to_skip, &rchunk);
940 pa_source_post(u->source, &rchunk);
941
942 pa_memblock_unref(rchunk.memblock);
943 pa_memblockq_drop(u->source_memblockq, to_skip);
944
945 rlen -= to_skip;
946 u->source_skip -= to_skip;
947 }
948
949 if (rlen && u->source_skip % u->source_output_blocksize) {
950 u->sink_skip += (uint64_t) (u->source_output_blocksize - (u->source_skip % u->source_output_blocksize)) * u->sink_blocksize / u->source_output_blocksize;
951 u->source_skip -= (u->source_skip % u->source_output_blocksize);
952 }
953 }
954
955 /* And for the sink, these samples have been played back already, so we can
956 * just drop them and get on with it. */
957 if (PA_UNLIKELY(u->sink_skip)) {
958 to_skip = plen >= u->sink_skip ? u->sink_skip : plen;
959
960 pa_memblockq_drop(u->sink_memblockq, to_skip);
961
962 plen -= to_skip;
963 u->sink_skip -= to_skip;
964 }
965
966 /* process and push out samples */
967 if (u->ec->params.drift_compensation)
968 do_push_drift_comp(u);
969 else
970 do_push(u);
971 }
972
973 /* Called from sink I/O thread context. */
sink_input_pop_cb(pa_sink_input * i,size_t nbytes,pa_memchunk * chunk)974 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
975 struct userdata *u;
976
977 pa_sink_input_assert_ref(i);
978 pa_assert(chunk);
979 pa_assert_se(u = i->userdata);
980
981 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
982 return -1;
983
984 if (u->sink->thread_info.rewind_requested)
985 pa_sink_process_rewind(u->sink, 0);
986
987 pa_sink_render_full(u->sink, nbytes, chunk);
988
989 if (i->thread_info.underrun_for > 0) {
990 pa_log_debug("Handling end of underrun.");
991 pa_atomic_store(&u->request_resync, 1);
992 }
993
994 /* let source thread handle the chunk. pass the sample count as well so that
995 * the source IO thread can update the right variables. */
996 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_POST,
997 NULL, 0, chunk, NULL);
998 u->send_counter += chunk->length;
999
1000 return 0;
1001 }
1002
1003 /* Called from source I/O thread context. */
source_output_process_rewind_cb(pa_source_output * o,size_t nbytes)1004 static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
1005 struct userdata *u;
1006
1007 pa_source_output_assert_ref(o);
1008 pa_source_output_assert_io_context(o);
1009 pa_assert_se(u = o->userdata);
1010
1011 /* If the source is not yet linked, there is nothing to rewind */
1012 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state))
1013 return;
1014
1015 pa_source_process_rewind(u->source, nbytes);
1016
1017 /* go back on read side, we need to use older sink data for this */
1018 pa_memblockq_rewind(u->sink_memblockq, nbytes);
1019
1020 /* manipulate write index */
1021 pa_memblockq_seek(u->source_memblockq, -nbytes, PA_SEEK_RELATIVE, true);
1022
1023 pa_log_debug("Source rewind (%lld) %lld", (long long) nbytes,
1024 (long long) pa_memblockq_get_length (u->source_memblockq));
1025 }
1026
1027 /* Called from sink I/O thread context. */
sink_input_process_rewind_cb(pa_sink_input * i,size_t nbytes)1028 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
1029 struct userdata *u;
1030
1031 pa_sink_input_assert_ref(i);
1032 pa_assert_se(u = i->userdata);
1033
1034 /* If the sink is not yet linked, there is nothing to rewind */
1035 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
1036 return;
1037
1038 pa_log_debug("Sink process rewind %lld", (long long) nbytes);
1039
1040 pa_sink_process_rewind(u->sink, nbytes);
1041
1042 pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_REWIND, NULL, (int64_t) nbytes, NULL, NULL);
1043 u->send_counter -= nbytes;
1044 }
1045
1046 /* Called from source I/O thread context. */
source_output_snapshot_within_thread(struct userdata * u,struct snapshot * snapshot)1047 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot) {
1048 size_t delay, rlen, plen;
1049 pa_usec_t now, latency;
1050
1051 now = pa_rtclock_now();
1052 latency = pa_source_get_latency_within_thread(u->source_output->source, false);
1053 delay = pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq);
1054
1055 delay = (u->source_output->thread_info.resampler ? pa_resampler_request(u->source_output->thread_info.resampler, delay) : delay);
1056 rlen = pa_memblockq_get_length(u->source_memblockq);
1057 plen = pa_memblockq_get_length(u->sink_memblockq);
1058
1059 snapshot->source_now = now;
1060 snapshot->source_latency = latency;
1061 snapshot->source_delay = delay;
1062 snapshot->recv_counter = u->recv_counter;
1063 snapshot->rlen = rlen + u->sink_skip;
1064 snapshot->plen = plen + u->source_skip;
1065 }
1066
1067 /* Called from source I/O thread context. */
source_output_process_msg_cb(pa_msgobject * obj,int code,void * data,int64_t offset,pa_memchunk * chunk)1068 static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
1069 struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;
1070
1071 switch (code) {
1072
1073 case SOURCE_OUTPUT_MESSAGE_POST:
1074
1075 pa_source_output_assert_io_context(u->source_output);
1076
1077 if (u->source_output->source->thread_info.state == PA_SOURCE_RUNNING)
1078 pa_memblockq_push_align(u->sink_memblockq, chunk);
1079 else
1080 pa_memblockq_flush_write(u->sink_memblockq, true);
1081
1082 u->recv_counter += (int64_t) chunk->length;
1083
1084 return 0;
1085
1086 case SOURCE_OUTPUT_MESSAGE_REWIND:
1087 pa_source_output_assert_io_context(u->source_output);
1088
1089 /* manipulate write index, never go past what we have */
1090 if (PA_SOURCE_IS_OPENED(u->source_output->source->thread_info.state))
1091 pa_memblockq_seek(u->sink_memblockq, -offset, PA_SEEK_RELATIVE, true);
1092 else
1093 pa_memblockq_flush_write(u->sink_memblockq, true);
1094
1095 pa_log_debug("Sink rewind (%lld)", (long long) offset);
1096
1097 u->recv_counter -= offset;
1098
1099 return 0;
1100
1101 case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT: {
1102 struct snapshot *snapshot = (struct snapshot *) data;
1103
1104 source_output_snapshot_within_thread(u, snapshot);
1105 return 0;
1106 }
1107
1108 case SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME:
1109 apply_diff_time(u, offset);
1110 return 0;
1111
1112 }
1113
1114 return pa_source_output_process_msg(obj, code, data, offset, chunk);
1115 }
1116
1117 /* Called from sink I/O thread context. */
sink_input_process_msg_cb(pa_msgobject * obj,int code,void * data,int64_t offset,pa_memchunk * chunk)1118 static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
1119 struct userdata *u = PA_SINK_INPUT(obj)->userdata;
1120
1121 switch (code) {
1122
1123 case SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT: {
1124 size_t delay;
1125 pa_usec_t now, latency;
1126 struct snapshot *snapshot = (struct snapshot *) data;
1127
1128 pa_sink_input_assert_io_context(u->sink_input);
1129
1130 now = pa_rtclock_now();
1131 latency = pa_sink_get_latency_within_thread(u->sink_input->sink, false);
1132 delay = pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq);
1133
1134 delay = (u->sink_input->thread_info.resampler ? pa_resampler_request(u->sink_input->thread_info.resampler, delay) : delay);
1135
1136 snapshot->sink_now = now;
1137 snapshot->sink_latency = latency;
1138 snapshot->sink_delay = delay;
1139 snapshot->send_counter = u->send_counter;
1140 return 0;
1141 }
1142 }
1143
1144 return pa_sink_input_process_msg(obj, code, data, offset, chunk);
1145 }
1146
1147 /* Called from sink I/O thread context. */
sink_input_update_max_rewind_cb(pa_sink_input * i,size_t nbytes)1148 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
1149 struct userdata *u;
1150
1151 pa_sink_input_assert_ref(i);
1152 pa_assert_se(u = i->userdata);
1153
1154 pa_log_debug("Sink input update max rewind %lld", (long long) nbytes);
1155
1156 /* FIXME: Too small max_rewind:
1157 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
1158 pa_memblockq_set_maxrewind(u->sink_memblockq, nbytes);
1159 pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
1160 }
1161
1162 /* Called from source I/O thread context. */
source_output_update_max_rewind_cb(pa_source_output * o,size_t nbytes)1163 static void source_output_update_max_rewind_cb(pa_source_output *o, size_t nbytes) {
1164 struct userdata *u;
1165
1166 pa_source_output_assert_ref(o);
1167 pa_assert_se(u = o->userdata);
1168
1169 pa_log_debug("Source output update max rewind %lld", (long long) nbytes);
1170
1171 pa_source_set_max_rewind_within_thread(u->source, nbytes);
1172 }
1173
1174 /* Called from sink I/O thread context. */
sink_input_update_max_request_cb(pa_sink_input * i,size_t nbytes)1175 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
1176 struct userdata *u;
1177
1178 pa_sink_input_assert_ref(i);
1179 pa_assert_se(u = i->userdata);
1180
1181 pa_log_debug("Sink input update max request %lld", (long long) nbytes);
1182
1183 pa_sink_set_max_request_within_thread(u->sink, nbytes);
1184 }
1185
1186 /* Called from sink I/O thread context. */
sink_input_update_sink_requested_latency_cb(pa_sink_input * i)1187 static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
1188 struct userdata *u;
1189 pa_usec_t latency;
1190
1191 pa_sink_input_assert_ref(i);
1192 pa_assert_se(u = i->userdata);
1193
1194 latency = pa_sink_get_requested_latency_within_thread(i->sink);
1195
1196 pa_log_debug("Sink input update requested latency %lld", (long long) latency);
1197 }
1198
1199 /* Called from source I/O thread context. */
source_output_update_source_requested_latency_cb(pa_source_output * o)1200 static void source_output_update_source_requested_latency_cb(pa_source_output *o) {
1201 struct userdata *u;
1202 pa_usec_t latency;
1203
1204 pa_source_output_assert_ref(o);
1205 pa_assert_se(u = o->userdata);
1206
1207 latency = pa_source_get_requested_latency_within_thread(o->source);
1208
1209 pa_log_debug("Source output update requested latency %lld", (long long) latency);
1210 }
1211
1212 /* Called from sink I/O thread context. */
sink_input_update_sink_latency_range_cb(pa_sink_input * i)1213 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
1214 struct userdata *u;
1215
1216 pa_sink_input_assert_ref(i);
1217 pa_assert_se(u = i->userdata);
1218
1219 pa_log_debug("Sink input update latency range %lld %lld",
1220 (long long) i->sink->thread_info.min_latency,
1221 (long long) i->sink->thread_info.max_latency);
1222
1223 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1224 }
1225
1226 /* Called from source I/O thread context. */
source_output_update_source_latency_range_cb(pa_source_output * o)1227 static void source_output_update_source_latency_range_cb(pa_source_output *o) {
1228 struct userdata *u;
1229
1230 pa_source_output_assert_ref(o);
1231 pa_assert_se(u = o->userdata);
1232
1233 pa_log_debug("Source output update latency range %lld %lld",
1234 (long long) o->source->thread_info.min_latency,
1235 (long long) o->source->thread_info.max_latency);
1236
1237 pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
1238 }
1239
1240 /* Called from sink I/O thread context. */
sink_input_update_sink_fixed_latency_cb(pa_sink_input * i)1241 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
1242 struct userdata *u;
1243
1244 pa_sink_input_assert_ref(i);
1245 pa_assert_se(u = i->userdata);
1246
1247 pa_log_debug("Sink input update fixed latency %lld",
1248 (long long) i->sink->thread_info.fixed_latency);
1249
1250 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
1251 }
1252
1253 /* Called from source I/O thread context. */
source_output_update_source_fixed_latency_cb(pa_source_output * o)1254 static void source_output_update_source_fixed_latency_cb(pa_source_output *o) {
1255 struct userdata *u;
1256
1257 pa_source_output_assert_ref(o);
1258 pa_assert_se(u = o->userdata);
1259
1260 pa_log_debug("Source output update fixed latency %lld",
1261 (long long) o->source->thread_info.fixed_latency);
1262
1263 pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
1264 }
1265
1266 /* Called from source I/O thread context. */
source_output_attach_cb(pa_source_output * o)1267 static void source_output_attach_cb(pa_source_output *o) {
1268 struct userdata *u;
1269
1270 pa_source_output_assert_ref(o);
1271 pa_source_output_assert_io_context(o);
1272 pa_assert_se(u = o->userdata);
1273
1274 pa_source_set_rtpoll(u->source, o->source->thread_info.rtpoll);
1275 pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
1276 pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
1277 pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
1278
1279 pa_log_debug("Source output %d attach", o->index);
1280
1281 if (PA_SOURCE_IS_LINKED(u->source->thread_info.state))
1282 pa_source_attach_within_thread(u->source);
1283
1284 u->rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
1285 o->source->thread_info.rtpoll,
1286 PA_RTPOLL_LATE,
1287 u->asyncmsgq);
1288 }
1289
1290 /* Called from sink I/O thread context. */
sink_input_attach_cb(pa_sink_input * i)1291 static void sink_input_attach_cb(pa_sink_input *i) {
1292 struct userdata *u;
1293
1294 pa_sink_input_assert_ref(i);
1295 pa_assert_se(u = i->userdata);
1296
1297 pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
1298 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1299
1300 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
1301 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
1302 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
1303
1304 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
1305 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
1306 * HERE. SEE (6) */
1307 pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
1308
1309 /* FIXME: Too small max_rewind:
1310 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
1311 pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
1312
1313 pa_log_debug("Sink input %d attach", i->index);
1314
1315 u->rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
1316 i->sink->thread_info.rtpoll,
1317 PA_RTPOLL_LATE,
1318 u->asyncmsgq);
1319
1320 if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
1321 pa_sink_attach_within_thread(u->sink);
1322 }
1323
1324 /* Called from source I/O thread context. */
source_output_detach_cb(pa_source_output * o)1325 static void source_output_detach_cb(pa_source_output *o) {
1326 struct userdata *u;
1327
1328 pa_source_output_assert_ref(o);
1329 pa_source_output_assert_io_context(o);
1330 pa_assert_se(u = o->userdata);
1331
1332 if (PA_SOURCE_IS_LINKED(u->source->thread_info.state))
1333 pa_source_detach_within_thread(u->source);
1334 pa_source_set_rtpoll(u->source, NULL);
1335
1336 pa_log_debug("Source output %d detach", o->index);
1337
1338 if (u->rtpoll_item_read) {
1339 pa_rtpoll_item_free(u->rtpoll_item_read);
1340 u->rtpoll_item_read = NULL;
1341 }
1342 }
1343
1344 /* Called from sink I/O thread context. */
sink_input_detach_cb(pa_sink_input * i)1345 static void sink_input_detach_cb(pa_sink_input *i) {
1346 struct userdata *u;
1347
1348 pa_sink_input_assert_ref(i);
1349 pa_assert_se(u = i->userdata);
1350
1351 if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
1352 pa_sink_detach_within_thread(u->sink);
1353
1354 pa_sink_set_rtpoll(u->sink, NULL);
1355
1356 pa_log_debug("Sink input %d detach", i->index);
1357
1358 if (u->rtpoll_item_write) {
1359 pa_rtpoll_item_free(u->rtpoll_item_write);
1360 u->rtpoll_item_write = NULL;
1361 }
1362 }
1363
1364 /* Called from source I/O thread context except when cork() is called without valid source. */
source_output_state_change_cb(pa_source_output * o,pa_source_output_state_t state)1365 static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
1366 struct userdata *u;
1367
1368 pa_source_output_assert_ref(o);
1369 pa_assert_se(u = o->userdata);
1370
1371 pa_log_debug("Source output %d state %d", o->index, state);
1372 }
1373
1374 /* Called from sink I/O thread context. */
sink_input_state_change_cb(pa_sink_input * i,pa_sink_input_state_t state)1375 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
1376 struct userdata *u;
1377
1378 pa_sink_input_assert_ref(i);
1379 pa_assert_se(u = i->userdata);
1380
1381 pa_log_debug("Sink input %d state %d", i->index, state);
1382 }
1383
1384 /* Called from main context. */
source_output_kill_cb(pa_source_output * o)1385 static void source_output_kill_cb(pa_source_output *o) {
1386 struct userdata *u;
1387
1388 pa_source_output_assert_ref(o);
1389 pa_assert_ctl_context();
1390 pa_assert_se(u = o->userdata);
1391
1392 u->dead = true;
1393
1394 /* The order here matters! We first kill the source so that streams can
1395 * properly be moved away while the source output is still connected to
1396 * the master. */
1397 pa_source_output_cork(u->source_output, true);
1398 pa_source_unlink(u->source);
1399 pa_source_output_unlink(u->source_output);
1400
1401 pa_source_output_unref(u->source_output);
1402 u->source_output = NULL;
1403
1404 pa_source_unref(u->source);
1405 u->source = NULL;
1406
1407 pa_log_debug("Source output kill %d", o->index);
1408
1409 pa_module_unload_request(u->module, true);
1410 }
1411
1412 /* Called from main context */
sink_input_kill_cb(pa_sink_input * i)1413 static void sink_input_kill_cb(pa_sink_input *i) {
1414 struct userdata *u;
1415
1416 pa_sink_input_assert_ref(i);
1417 pa_assert_se(u = i->userdata);
1418
1419 u->dead = true;
1420
1421 /* The order here matters! We first kill the sink so that streams
1422 * can properly be moved away while the sink input is still connected
1423 * to the master. */
1424 pa_sink_input_cork(u->sink_input, true);
1425 pa_sink_unlink(u->sink);
1426 pa_sink_input_unlink(u->sink_input);
1427
1428 pa_sink_input_unref(u->sink_input);
1429 u->sink_input = NULL;
1430
1431 pa_sink_unref(u->sink);
1432 u->sink = NULL;
1433
1434 pa_log_debug("Sink input kill %d", i->index);
1435
1436 pa_module_unload_request(u->module, true);
1437 }
1438
1439 /* Called from main context. */
source_output_may_move_to_cb(pa_source_output * o,pa_source * dest)1440 static bool source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
1441 struct userdata *u;
1442
1443 pa_source_output_assert_ref(o);
1444 pa_assert_ctl_context();
1445 pa_assert_se(u = o->userdata);
1446
1447 if (u->dead)
1448 return false;
1449
1450 return (u->source != dest) && (u->sink != dest->monitor_of);
1451 }
1452
1453 /* Called from main context */
sink_input_may_move_to_cb(pa_sink_input * i,pa_sink * dest)1454 static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
1455 struct userdata *u;
1456
1457 pa_sink_input_assert_ref(i);
1458 pa_assert_se(u = i->userdata);
1459
1460 if (u->dead)
1461 return false;
1462
1463 return u->sink != dest;
1464 }
1465
1466 /* Called from main context. */
source_output_moving_cb(pa_source_output * o,pa_source * dest)1467 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
1468 struct userdata *u;
1469 uint32_t idx;
1470 pa_source_output *output;
1471
1472 pa_source_output_assert_ref(o);
1473 pa_assert_ctl_context();
1474 pa_assert_se(u = o->userdata);
1475
1476 if (dest) {
1477 pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
1478 pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
1479 } else
1480 pa_source_set_asyncmsgq(u->source, NULL);
1481
1482 /* Propagate asyncmsq change to attached virtual sources */
1483 PA_IDXSET_FOREACH(output, u->source->outputs, idx) {
1484 if (output->destination_source && output->moving)
1485 output->moving(output, u->source);
1486 }
1487
1488 if (u->source_auto_desc && dest) {
1489 const char *y, *z;
1490 pa_proplist *pl;
1491
1492 pl = pa_proplist_new();
1493 if (u->sink_input->sink) {
1494 pa_proplist_sets(pl, PA_PROP_DEVICE_MASTER_DEVICE, u->sink_input->sink->name);
1495 y = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
1496 } else
1497 y = "<unknown>"; /* Probably in the middle of a move */
1498 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
1499 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
1500 y ? y : u->sink_input->sink->name);
1501
1502 pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
1503 pa_proplist_free(pl);
1504 }
1505 }
1506
1507 /* Called from main context */
sink_input_moving_cb(pa_sink_input * i,pa_sink * dest)1508 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
1509 struct userdata *u;
1510
1511 pa_sink_input_assert_ref(i);
1512 pa_assert_se(u = i->userdata);
1513
1514 if (dest) {
1515 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
1516 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
1517 } else
1518 pa_sink_set_asyncmsgq(u->sink, NULL);
1519
1520 if (u->sink_auto_desc && dest) {
1521 const char *y, *z;
1522 pa_proplist *pl;
1523
1524 pl = pa_proplist_new();
1525 if (u->source_output->source) {
1526 pa_proplist_sets(pl, PA_PROP_DEVICE_MASTER_DEVICE, u->source_output->source->name);
1527 y = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION);
1528 } else
1529 y = "<unknown>"; /* Probably in the middle of a move */
1530 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
1531 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
1532 y ? y : u->source_output->source->name);
1533
1534 pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
1535 pa_proplist_free(pl);
1536 }
1537 }
1538
1539 /* Called from main context */
sink_input_volume_changed_cb(pa_sink_input * i)1540 static void sink_input_volume_changed_cb(pa_sink_input *i) {
1541 struct userdata *u;
1542
1543 pa_sink_input_assert_ref(i);
1544 pa_assert_se(u = i->userdata);
1545
1546 pa_sink_volume_changed(u->sink, &i->volume);
1547 }
1548
1549 /* Called from main context */
sink_input_mute_changed_cb(pa_sink_input * i)1550 static void sink_input_mute_changed_cb(pa_sink_input *i) {
1551 struct userdata *u;
1552
1553 pa_sink_input_assert_ref(i);
1554 pa_assert_se(u = i->userdata);
1555
1556 pa_sink_mute_changed(u->sink, i->muted);
1557 }
1558
1559 /* Called from main context */
canceller_process_msg_cb(pa_msgobject * o,int code,void * userdata,int64_t offset,pa_memchunk * chunk)1560 static int canceller_process_msg_cb(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1561 struct pa_echo_canceller_msg *msg;
1562 struct userdata *u;
1563
1564 pa_assert(o);
1565
1566 msg = PA_ECHO_CANCELLER_MSG(o);
1567
1568 /* When the module is unloaded, there may still remain queued messages for
1569 * the canceller. Messages are sent to the main thread using the master
1570 * source's asyncmsgq, and that message queue isn't (and can't be, at least
1571 * with the current asyncmsgq API) cleared from the canceller messages when
1572 * module-echo-cancel is unloaded.
1573 *
1574 * The userdata may already have been freed at this point, but the
1575 * asyncmsgq holds a reference to the pa_echo_canceller_msg object, which
1576 * contains a flag to indicate that all remaining messages have to be
1577 * ignored. */
1578 if (msg->dead)
1579 return 0;
1580
1581 u = msg->userdata;
1582
1583 switch (code) {
1584 case ECHO_CANCELLER_MESSAGE_SET_VOLUME: {
1585 pa_volume_t v = PA_PTR_TO_UINT(userdata);
1586 pa_cvolume vol;
1587
1588 if (u->use_volume_sharing) {
1589 pa_cvolume_set(&vol, u->source->sample_spec.channels, v);
1590 pa_source_set_volume(u->source, &vol, true, false);
1591 } else {
1592 pa_cvolume_set(&vol, u->source_output->sample_spec.channels, v);
1593 pa_source_output_set_volume(u->source_output, &vol, false, true);
1594 }
1595
1596 break;
1597 }
1598
1599 default:
1600 pa_assert_not_reached();
1601 break;
1602 }
1603
1604 return 0;
1605 }
1606
1607 /* Called by the canceller, so source I/O thread context. */
pa_echo_canceller_get_capture_volume(pa_echo_canceller * ec)1608 pa_volume_t pa_echo_canceller_get_capture_volume(pa_echo_canceller *ec) {
1609 #ifndef ECHO_CANCEL_TEST
1610 return pa_cvolume_avg(&ec->msg->userdata->thread_info.current_volume);
1611 #else
1612 return PA_VOLUME_NORM;
1613 #endif
1614 }
1615
1616 /* Called by the canceller, so source I/O thread context. */
pa_echo_canceller_set_capture_volume(pa_echo_canceller * ec,pa_volume_t v)1617 void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_volume_t v) {
1618 #ifndef ECHO_CANCEL_TEST
1619 if (pa_cvolume_avg(&ec->msg->userdata->thread_info.current_volume) != v) {
1620 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(ec->msg), ECHO_CANCELLER_MESSAGE_SET_VOLUME, PA_UINT_TO_PTR(v),
1621 0, NULL, NULL);
1622 }
1623 #endif
1624 }
1625
pa_echo_canceller_blocksize_power2(unsigned rate,unsigned ms)1626 uint32_t pa_echo_canceller_blocksize_power2(unsigned rate, unsigned ms) {
1627 unsigned nframes = (rate * ms) / 1000;
1628 uint32_t y = 1 << ((8 * sizeof(uint32_t)) - 2);
1629
1630 pa_assert(rate >= 4000);
1631 pa_assert(ms >= 1);
1632
1633 /* nframes should be a power of 2, round down to nearest power of two */
1634 while (y > nframes)
1635 y >>= 1;
1636
1637 pa_assert(y >= 1);
1638 return y;
1639 }
1640
get_ec_method_from_string(const char * method)1641 static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) {
1642 if (pa_streq(method, "null"))
1643 return PA_ECHO_CANCELLER_NULL;
1644 #ifdef HAVE_SPEEX
1645 if (pa_streq(method, "speex"))
1646 return PA_ECHO_CANCELLER_SPEEX;
1647 #endif
1648 #ifdef HAVE_ADRIAN_EC
1649 if (pa_streq(method, "adrian"))
1650 return PA_ECHO_CANCELLER_ADRIAN;
1651 #endif
1652 #ifdef HAVE_WEBRTC
1653 if (pa_streq(method, "webrtc"))
1654 return PA_ECHO_CANCELLER_WEBRTC;
1655 #endif
1656 return PA_ECHO_CANCELLER_INVALID;
1657 }
1658
1659 /* Common initialisation bits between module-echo-cancel and the standalone
1660 * test program.
1661 *
1662 * Called from main context. */
init_common(pa_modargs * ma,struct userdata * u,pa_sample_spec * source_ss,pa_channel_map * source_map)1663 static int init_common(pa_modargs *ma, struct userdata *u, pa_sample_spec *source_ss, pa_channel_map *source_map) {
1664 const char *ec_string;
1665 pa_echo_canceller_method_t ec_method;
1666
1667 if (pa_modargs_get_sample_spec_and_channel_map(ma, source_ss, source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
1668 pa_log("Invalid sample format specification or channel map");
1669 goto fail;
1670 }
1671
1672 u->ec = pa_xnew0(pa_echo_canceller, 1);
1673 if (!u->ec) {
1674 pa_log("Failed to alloc echo canceller");
1675 goto fail;
1676 }
1677
1678 ec_string = pa_modargs_get_value(ma, "aec_method", DEFAULT_ECHO_CANCELLER);
1679 if ((ec_method = get_ec_method_from_string(ec_string)) < 0) {
1680 pa_log("Invalid echo canceller implementation '%s'", ec_string);
1681 goto fail;
1682 }
1683
1684 pa_log_info("Using AEC engine: %s", ec_string);
1685
1686 u->ec->init = ec_table[ec_method].init;
1687 u->ec->play = ec_table[ec_method].play;
1688 u->ec->record = ec_table[ec_method].record;
1689 u->ec->set_drift = ec_table[ec_method].set_drift;
1690 u->ec->run = ec_table[ec_method].run;
1691 u->ec->done = ec_table[ec_method].done;
1692
1693 return 0;
1694
1695 fail:
1696 return -1;
1697 }
1698
1699 /* Called from main context. */
pa__init(pa_module * m)1700 int pa__init(pa_module*m) {
1701 struct userdata *u;
1702 pa_sample_spec source_output_ss, source_ss, sink_ss;
1703 pa_channel_map source_output_map, source_map, sink_map;
1704 pa_modargs *ma;
1705 pa_source *source_master=NULL;
1706 pa_sink *sink_master=NULL;
1707 bool autoloaded;
1708 pa_source_output_new_data source_output_data;
1709 pa_sink_input_new_data sink_input_data;
1710 pa_source_new_data source_data;
1711 pa_sink_new_data sink_data;
1712 pa_memchunk silence;
1713 uint32_t temp;
1714 uint32_t nframes = 0;
1715 bool use_master_format;
1716 pa_usec_t blocksize_usec;
1717
1718 pa_assert(m);
1719
1720 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1721 pa_log("Failed to parse module arguments.");
1722 goto fail;
1723 }
1724
1725 if (!(source_master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source_master", NULL), PA_NAMEREG_SOURCE))) {
1726 pa_log("Master source not found");
1727 goto fail;
1728 }
1729 pa_assert(source_master);
1730
1731 if (!(sink_master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink_master", NULL), PA_NAMEREG_SINK))) {
1732 pa_log("Master sink not found");
1733 goto fail;
1734 }
1735 pa_assert(sink_master);
1736
1737 if (source_master->monitor_of == sink_master) {
1738 pa_log("Can't cancel echo between a sink and its monitor");
1739 goto fail;
1740 }
1741
1742 /* Set to true if we just want to inherit sample spec and channel map from the sink and source master */
1743 use_master_format = DEFAULT_USE_MASTER_FORMAT;
1744 if (pa_modargs_get_value_boolean(ma, "use_master_format", &use_master_format) < 0) {
1745 pa_log("use_master_format= expects a boolean argument");
1746 goto fail;
1747 }
1748
1749 source_ss = source_master->sample_spec;
1750 sink_ss = sink_master->sample_spec;
1751
1752 if (use_master_format) {
1753 source_map = source_master->channel_map;
1754 sink_map = sink_master->channel_map;
1755 } else {
1756 source_ss = source_master->sample_spec;
1757 source_ss.rate = DEFAULT_RATE;
1758 source_ss.channels = DEFAULT_CHANNELS;
1759 pa_channel_map_init_auto(&source_map, source_ss.channels, PA_CHANNEL_MAP_DEFAULT);
1760
1761 sink_ss = sink_master->sample_spec;
1762 sink_ss.rate = DEFAULT_RATE;
1763 sink_ss.channels = DEFAULT_CHANNELS;
1764 pa_channel_map_init_auto(&sink_map, sink_ss.channels, PA_CHANNEL_MAP_DEFAULT);
1765 }
1766
1767 u = pa_xnew0(struct userdata, 1);
1768 if (!u) {
1769 pa_log("Failed to alloc userdata");
1770 goto fail;
1771 }
1772 u->core = m->core;
1773 u->module = m;
1774 m->userdata = u;
1775 u->dead = false;
1776
1777 u->use_volume_sharing = true;
1778 if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &u->use_volume_sharing) < 0) {
1779 pa_log("use_volume_sharing= expects a boolean argument");
1780 goto fail;
1781 }
1782
1783 temp = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
1784 if (pa_modargs_get_value_u32(ma, "adjust_time", &temp) < 0) {
1785 pa_log("Failed to parse adjust_time value");
1786 goto fail;
1787 }
1788
1789 if (temp != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
1790 u->adjust_time = temp * PA_USEC_PER_SEC;
1791 else
1792 u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
1793
1794 temp = DEFAULT_ADJUST_TOLERANCE / PA_USEC_PER_MSEC;
1795 if (pa_modargs_get_value_u32(ma, "adjust_threshold", &temp) < 0) {
1796 pa_log("Failed to parse adjust_threshold value");
1797 goto fail;
1798 }
1799
1800 if (temp != DEFAULT_ADJUST_TOLERANCE / PA_USEC_PER_MSEC)
1801 u->adjust_threshold = temp * PA_USEC_PER_MSEC;
1802 else
1803 u->adjust_threshold = DEFAULT_ADJUST_TOLERANCE;
1804
1805 u->save_aec = DEFAULT_SAVE_AEC;
1806 if (pa_modargs_get_value_boolean(ma, "save_aec", &u->save_aec) < 0) {
1807 pa_log("Failed to parse save_aec value");
1808 goto fail;
1809 }
1810
1811 autoloaded = DEFAULT_AUTOLOADED;
1812 if (pa_modargs_get_value_boolean(ma, "autoloaded", &autoloaded) < 0) {
1813 pa_log("Failed to parse autoloaded value");
1814 goto fail;
1815 }
1816
1817 if (init_common(ma, u, &source_ss, &source_map) < 0)
1818 goto fail;
1819
1820 u->asyncmsgq = pa_asyncmsgq_new(0);
1821 if (!u->asyncmsgq) {
1822 pa_log("pa_asyncmsgq_new() failed.");
1823 goto fail;
1824 }
1825
1826 u->need_realign = true;
1827
1828 source_output_ss = source_ss;
1829 source_output_map = source_map;
1830
1831 if (sink_ss.rate != source_ss.rate) {
1832 pa_log_info("Sample rates of play and out stream differ. Adjusting rate of play stream.");
1833 sink_ss.rate = source_ss.rate;
1834 }
1835
1836 pa_assert(u->ec->init);
1837 if (!u->ec->init(u->core, u->ec, &source_output_ss, &source_output_map, &sink_ss, &sink_map, &source_ss, &source_map, &nframes, pa_modargs_get_value(ma, "aec_args", NULL))) {
1838 pa_log("Failed to init AEC engine");
1839 goto fail;
1840 }
1841
1842 pa_assert(source_output_ss.rate == source_ss.rate);
1843 pa_assert(sink_ss.rate == source_ss.rate);
1844
1845 u->source_output_blocksize = nframes * pa_frame_size(&source_output_ss);
1846 u->source_blocksize = nframes * pa_frame_size(&source_ss);
1847 u->sink_blocksize = nframes * pa_frame_size(&sink_ss);
1848
1849 if (u->ec->params.drift_compensation)
1850 pa_assert(u->ec->set_drift);
1851
1852 /* Create source */
1853 pa_source_new_data_init(&source_data);
1854 source_data.driver = __FILE__;
1855 source_data.module = m;
1856 if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
1857 source_data.name = pa_sprintf_malloc("%s.echo-cancel", source_master->name);
1858 pa_source_new_data_set_sample_spec(&source_data, &source_ss);
1859 pa_source_new_data_set_channel_map(&source_data, &source_map);
1860 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, source_master->name);
1861 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1862 if (!autoloaded)
1863 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
1864
1865 if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
1866 pa_log("Invalid properties");
1867 pa_source_new_data_done(&source_data);
1868 goto fail;
1869 }
1870
1871 if ((u->source_auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
1872 const char *y, *z;
1873
1874 y = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1875 z = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1876 pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
1877 z ? z : source_master->name, y ? y : sink_master->name);
1878 }
1879
1880 u->source = pa_source_new(m->core, &source_data, (source_master->flags & (PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY))
1881 | (u->use_volume_sharing ? PA_SOURCE_SHARE_VOLUME_WITH_MASTER : 0));
1882 pa_source_new_data_done(&source_data);
1883
1884 if (!u->source) {
1885 pa_log("Failed to create source.");
1886 goto fail;
1887 }
1888
1889 u->source->parent.process_msg = source_process_msg_cb;
1890 u->source->set_state_in_main_thread = source_set_state_in_main_thread_cb;
1891 u->source->update_requested_latency = source_update_requested_latency_cb;
1892 pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
1893 if (!u->use_volume_sharing) {
1894 pa_source_set_get_volume_callback(u->source, source_get_volume_cb);
1895 pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
1896 pa_source_enable_decibel_volume(u->source, true);
1897 }
1898 u->source->userdata = u;
1899
1900 pa_source_set_asyncmsgq(u->source, source_master->asyncmsgq);
1901
1902 /* Create sink */
1903 pa_sink_new_data_init(&sink_data);
1904 sink_data.driver = __FILE__;
1905 sink_data.module = m;
1906 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
1907 sink_data.name = pa_sprintf_malloc("%s.echo-cancel", sink_master->name);
1908 pa_sink_new_data_set_sample_spec(&sink_data, &sink_ss);
1909 pa_sink_new_data_set_channel_map(&sink_data, &sink_map);
1910 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, sink_master->name);
1911 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1912 if (!autoloaded)
1913 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
1914
1915 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
1916 pa_log("Invalid properties");
1917 pa_sink_new_data_done(&sink_data);
1918 goto fail;
1919 }
1920
1921 if ((u->sink_auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
1922 const char *y, *z;
1923
1924 y = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1925 z = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1926 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
1927 z ? z : sink_master->name, y ? y : source_master->name);
1928 }
1929
1930 u->sink = pa_sink_new(m->core, &sink_data, (sink_master->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY))
1931 | (u->use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
1932 pa_sink_new_data_done(&sink_data);
1933
1934 if (!u->sink) {
1935 pa_log("Failed to create sink.");
1936 goto fail;
1937 }
1938
1939 u->sink->parent.process_msg = sink_process_msg_cb;
1940 u->sink->set_state_in_main_thread = sink_set_state_in_main_thread_cb;
1941 u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
1942 u->sink->update_requested_latency = sink_update_requested_latency_cb;
1943 u->sink->request_rewind = sink_request_rewind_cb;
1944 pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
1945 if (!u->use_volume_sharing) {
1946 pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
1947 pa_sink_enable_decibel_volume(u->sink, true);
1948 }
1949 u->sink->userdata = u;
1950
1951 pa_sink_set_asyncmsgq(u->sink, sink_master->asyncmsgq);
1952
1953 /* Create source output */
1954 pa_source_output_new_data_init(&source_output_data);
1955 source_output_data.driver = __FILE__;
1956 source_output_data.module = m;
1957 pa_source_output_new_data_set_source(&source_output_data, source_master, false, true);
1958 source_output_data.destination_source = u->source;
1959
1960 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Source Stream");
1961 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
1962 pa_source_output_new_data_set_sample_spec(&source_output_data, &source_output_ss);
1963 pa_source_output_new_data_set_channel_map(&source_output_data, &source_output_map);
1964 source_output_data.flags |= PA_SOURCE_OUTPUT_START_CORKED;
1965
1966 if (autoloaded)
1967 source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE;
1968
1969 pa_source_output_new(&u->source_output, m->core, &source_output_data);
1970 pa_source_output_new_data_done(&source_output_data);
1971
1972 if (!u->source_output)
1973 goto fail;
1974
1975 u->source_output->parent.process_msg = source_output_process_msg_cb;
1976 u->source_output->push = source_output_push_cb;
1977 u->source_output->process_rewind = source_output_process_rewind_cb;
1978 u->source_output->update_max_rewind = source_output_update_max_rewind_cb;
1979 u->source_output->update_source_requested_latency = source_output_update_source_requested_latency_cb;
1980 u->source_output->update_source_latency_range = source_output_update_source_latency_range_cb;
1981 u->source_output->update_source_fixed_latency = source_output_update_source_fixed_latency_cb;
1982 u->source_output->kill = source_output_kill_cb;
1983 u->source_output->attach = source_output_attach_cb;
1984 u->source_output->detach = source_output_detach_cb;
1985 u->source_output->state_change = source_output_state_change_cb;
1986 u->source_output->may_move_to = source_output_may_move_to_cb;
1987 u->source_output->moving = source_output_moving_cb;
1988 u->source_output->userdata = u;
1989
1990 u->source->output_from_master = u->source_output;
1991
1992 /* Create sink input */
1993 pa_sink_input_new_data_init(&sink_input_data);
1994 sink_input_data.driver = __FILE__;
1995 sink_input_data.module = m;
1996 pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, false, true);
1997 sink_input_data.origin_sink = u->sink;
1998 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");
1999 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
2000 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_ss);
2001 pa_sink_input_new_data_set_channel_map(&sink_input_data, &sink_map);
2002 sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE | PA_SINK_INPUT_START_CORKED;
2003
2004 if (autoloaded)
2005 sink_input_data.flags |= PA_SINK_INPUT_DONT_MOVE;
2006
2007 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
2008 pa_sink_input_new_data_done(&sink_input_data);
2009
2010 if (!u->sink_input)
2011 goto fail;
2012
2013 u->sink_input->parent.process_msg = sink_input_process_msg_cb;
2014 u->sink_input->pop = sink_input_pop_cb;
2015 u->sink_input->process_rewind = sink_input_process_rewind_cb;
2016 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
2017 u->sink_input->update_max_request = sink_input_update_max_request_cb;
2018 u->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb;
2019 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
2020 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
2021 u->sink_input->kill = sink_input_kill_cb;
2022 u->sink_input->attach = sink_input_attach_cb;
2023 u->sink_input->detach = sink_input_detach_cb;
2024 u->sink_input->state_change = sink_input_state_change_cb;
2025 u->sink_input->may_move_to = sink_input_may_move_to_cb;
2026 u->sink_input->moving = sink_input_moving_cb;
2027 if (!u->use_volume_sharing)
2028 u->sink_input->volume_changed = sink_input_volume_changed_cb;
2029 u->sink_input->mute_changed = sink_input_mute_changed_cb;
2030 u->sink_input->userdata = u;
2031
2032 u->sink->input_to_master = u->sink_input;
2033
2034 pa_sink_input_get_silence(u->sink_input, &silence);
2035
2036 u->source_memblockq = pa_memblockq_new("module-echo-cancel source_memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0,
2037 &source_output_ss, 1, 1, 0, &silence);
2038 u->sink_memblockq = pa_memblockq_new("module-echo-cancel sink_memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0,
2039 &sink_ss, 0, 1, 0, &silence);
2040
2041 pa_memblock_unref(silence.memblock);
2042
2043 if (!u->source_memblockq || !u->sink_memblockq) {
2044 pa_log("Failed to create memblockq.");
2045 goto fail;
2046 }
2047
2048 if (u->adjust_time > 0 && !u->ec->params.drift_compensation)
2049 u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
2050 else if (u->ec->params.drift_compensation) {
2051 pa_log_info("Canceller does drift compensation -- built-in compensation will be disabled");
2052 u->adjust_time = 0;
2053 /* Perform resync just once to give the canceller a leg up */
2054 pa_atomic_store(&u->request_resync, 1);
2055 }
2056
2057 if (u->save_aec) {
2058 pa_log("Creating AEC files in /tmp");
2059 u->captured_file = fopen("/tmp/aec_rec.sw", "wb");
2060 if (u->captured_file == NULL)
2061 perror ("fopen failed");
2062 u->played_file = fopen("/tmp/aec_play.sw", "wb");
2063 if (u->played_file == NULL)
2064 perror ("fopen failed");
2065 u->canceled_file = fopen("/tmp/aec_out.sw", "wb");
2066 if (u->canceled_file == NULL)
2067 perror ("fopen failed");
2068 if (u->ec->params.drift_compensation) {
2069 u->drift_file = fopen("/tmp/aec_drift.txt", "w");
2070 if (u->drift_file == NULL)
2071 perror ("fopen failed");
2072 }
2073 }
2074
2075 u->ec->msg = pa_msgobject_new(pa_echo_canceller_msg);
2076 u->ec->msg->parent.process_msg = canceller_process_msg_cb;
2077 u->ec->msg->userdata = u;
2078
2079 u->thread_info.current_volume = u->source->reference_volume;
2080
2081 /* We don't want to deal with too many chunks at a time */
2082 blocksize_usec = pa_bytes_to_usec(u->source_blocksize, &u->source->sample_spec);
2083 if (u->source->flags & PA_SOURCE_DYNAMIC_LATENCY)
2084 pa_source_set_latency_range(u->source, blocksize_usec, blocksize_usec * MAX_LATENCY_BLOCKS);
2085 pa_source_output_set_requested_latency(u->source_output, blocksize_usec * MAX_LATENCY_BLOCKS);
2086
2087 blocksize_usec = pa_bytes_to_usec(u->sink_blocksize, &u->sink->sample_spec);
2088 if (u->sink->flags & PA_SINK_DYNAMIC_LATENCY)
2089 pa_sink_set_latency_range(u->sink, blocksize_usec, blocksize_usec * MAX_LATENCY_BLOCKS);
2090 pa_sink_input_set_requested_latency(u->sink_input, blocksize_usec * MAX_LATENCY_BLOCKS);
2091
2092 /* The order here is important. The input/output must be put first,
2093 * otherwise streams might attach to the sink/source before the
2094 * sink input or source output is attached to the master. */
2095 pa_sink_input_put(u->sink_input);
2096 pa_source_output_put(u->source_output);
2097
2098 pa_sink_put(u->sink);
2099 pa_source_put(u->source);
2100
2101 pa_source_output_cork(u->source_output, false);
2102 pa_sink_input_cork(u->sink_input, false);
2103
2104 pa_modargs_free(ma);
2105
2106 return 0;
2107
2108 fail:
2109 if (ma)
2110 pa_modargs_free(ma);
2111
2112 pa__done(m);
2113
2114 return -1;
2115 }
2116
2117 /* Called from main context. */
pa__get_n_used(pa_module * m)2118 int pa__get_n_used(pa_module *m) {
2119 struct userdata *u;
2120
2121 pa_assert(m);
2122 pa_assert_se(u = m->userdata);
2123
2124 return pa_sink_linked_by(u->sink) + pa_source_linked_by(u->source);
2125 }
2126
2127 /* Called from main context. */
pa__done(pa_module * m)2128 void pa__done(pa_module*m) {
2129 struct userdata *u;
2130
2131 pa_assert(m);
2132
2133 if (!(u = m->userdata))
2134 return;
2135
2136 u->dead = true;
2137
2138 /* See comments in source_output_kill_cb() above regarding
2139 * destruction order! */
2140
2141 if (u->time_event)
2142 u->core->mainloop->time_free(u->time_event);
2143
2144 if (u->source_output)
2145 pa_source_output_cork(u->source_output, true);
2146 if (u->sink_input)
2147 pa_sink_input_cork(u->sink_input, true);
2148
2149 if (u->source)
2150 pa_source_unlink(u->source);
2151 if (u->sink)
2152 pa_sink_unlink(u->sink);
2153
2154 if (u->source_output) {
2155 pa_source_output_unlink(u->source_output);
2156 pa_source_output_unref(u->source_output);
2157 }
2158
2159 if (u->sink_input) {
2160 pa_sink_input_unlink(u->sink_input);
2161 pa_sink_input_unref(u->sink_input);
2162 }
2163
2164 if (u->source)
2165 pa_source_unref(u->source);
2166 if (u->sink)
2167 pa_sink_unref(u->sink);
2168
2169 if (u->source_memblockq)
2170 pa_memblockq_free(u->source_memblockq);
2171 if (u->sink_memblockq)
2172 pa_memblockq_free(u->sink_memblockq);
2173
2174 if (u->ec) {
2175 if (u->ec->done)
2176 u->ec->done(u->ec);
2177
2178 if (u->ec->msg) {
2179 u->ec->msg->dead = true;
2180 pa_echo_canceller_msg_unref(u->ec->msg);
2181 }
2182
2183 pa_xfree(u->ec);
2184 }
2185
2186 if (u->asyncmsgq)
2187 pa_asyncmsgq_unref(u->asyncmsgq);
2188
2189 if (u->save_aec) {
2190 if (u->played_file)
2191 fclose(u->played_file);
2192 if (u->captured_file)
2193 fclose(u->captured_file);
2194 if (u->canceled_file)
2195 fclose(u->canceled_file);
2196 if (u->drift_file)
2197 fclose(u->drift_file);
2198 }
2199
2200 pa_xfree(u);
2201 }
2202
2203 #ifdef ECHO_CANCEL_TEST
2204 /*
2205 * Stand-alone test program for running in the canceller on pre-recorded files.
2206 */
main(int argc,char * argv[])2207 int main(int argc, char* argv[]) {
2208 struct userdata u;
2209 pa_sample_spec source_output_ss, source_ss, sink_ss;
2210 pa_channel_map source_output_map, source_map, sink_map;
2211 pa_modargs *ma = NULL;
2212 uint8_t *rdata = NULL, *pdata = NULL, *cdata = NULL;
2213 int unused PA_GCC_UNUSED;
2214 int ret = 0, i;
2215 char c;
2216 float drift;
2217 uint32_t nframes;
2218
2219 if (!getenv("MAKE_CHECK"))
2220 pa_log_set_level(PA_LOG_DEBUG);
2221
2222 pa_memzero(&u, sizeof(u));
2223
2224 if (argc < 4 || argc > 7) {
2225 goto usage;
2226 }
2227
2228 u.captured_file = fopen(argv[2], "rb");
2229 if (u.captured_file == NULL) {
2230 perror ("Could not open capture file");
2231 goto fail;
2232 }
2233 u.played_file = fopen(argv[1], "rb");
2234 if (u.played_file == NULL) {
2235 perror ("Could not open play file");
2236 goto fail;
2237 }
2238 u.canceled_file = fopen(argv[3], "wb");
2239 if (u.canceled_file == NULL) {
2240 perror ("Could not open canceled file");
2241 goto fail;
2242 }
2243
2244 u.core = pa_xnew0(pa_core, 1);
2245 u.core->cpu_info.cpu_type = PA_CPU_X86;
2246 u.core->cpu_info.flags.x86 |= PA_CPU_X86_SSE;
2247
2248 if (!(ma = pa_modargs_new(argc > 4 ? argv[4] : NULL, valid_modargs))) {
2249 pa_log("Failed to parse module arguments.");
2250 goto fail;
2251 }
2252
2253 source_ss.format = PA_SAMPLE_FLOAT32LE;
2254 source_ss.rate = DEFAULT_RATE;
2255 source_ss.channels = DEFAULT_CHANNELS;
2256 pa_channel_map_init_auto(&source_map, source_ss.channels, PA_CHANNEL_MAP_DEFAULT);
2257
2258 sink_ss.format = PA_SAMPLE_FLOAT32LE;
2259 sink_ss.rate = DEFAULT_RATE;
2260 sink_ss.channels = DEFAULT_CHANNELS;
2261 pa_channel_map_init_auto(&sink_map, sink_ss.channels, PA_CHANNEL_MAP_DEFAULT);
2262
2263 if (init_common(ma, &u, &source_ss, &source_map) < 0)
2264 goto fail;
2265
2266 source_output_ss = source_ss;
2267 source_output_map = source_map;
2268
2269 if (!u.ec->init(u.core, u.ec, &source_output_ss, &source_output_map, &sink_ss, &sink_map, &source_ss, &source_map, &nframes,
2270 pa_modargs_get_value(ma, "aec_args", NULL))) {
2271 pa_log("Failed to init AEC engine");
2272 goto fail;
2273 }
2274 u.source_output_blocksize = nframes * pa_frame_size(&source_output_ss);
2275 u.source_blocksize = nframes * pa_frame_size(&source_ss);
2276 u.sink_blocksize = nframes * pa_frame_size(&sink_ss);
2277
2278 if (u.ec->params.drift_compensation) {
2279 if (argc < 6) {
2280 pa_log("Drift compensation enabled but drift file not specified");
2281 goto fail;
2282 }
2283
2284 u.drift_file = fopen(argv[5], "rt");
2285
2286 if (u.drift_file == NULL) {
2287 perror ("Could not open drift file");
2288 goto fail;
2289 }
2290 }
2291
2292 rdata = pa_xmalloc(u.source_output_blocksize);
2293 pdata = pa_xmalloc(u.sink_blocksize);
2294 cdata = pa_xmalloc(u.source_blocksize);
2295
2296 if (!u.ec->params.drift_compensation) {
2297 while (fread(rdata, u.source_output_blocksize, 1, u.captured_file) > 0) {
2298 if (fread(pdata, u.sink_blocksize, 1, u.played_file) == 0) {
2299 perror("Played file ended before captured file");
2300 goto fail;
2301 }
2302
2303 u.ec->run(u.ec, rdata, pdata, cdata);
2304
2305 unused = fwrite(cdata, u.source_blocksize, 1, u.canceled_file);
2306 }
2307 } else {
2308 while (fscanf(u.drift_file, "%c", &c) > 0) {
2309 switch (c) {
2310 case 'd':
2311 if (!fscanf(u.drift_file, "%a", &drift)) {
2312 perror("Drift file incomplete");
2313 goto fail;
2314 }
2315
2316 u.ec->set_drift(u.ec, drift);
2317
2318 break;
2319
2320 case 'c':
2321 if (!fscanf(u.drift_file, "%d", &i)) {
2322 perror("Drift file incomplete");
2323 goto fail;
2324 }
2325
2326 if (fread(rdata, i, 1, u.captured_file) <= 0) {
2327 perror("Captured file ended prematurely");
2328 goto fail;
2329 }
2330
2331 u.ec->record(u.ec, rdata, cdata);
2332
2333 unused = fwrite(cdata, i, 1, u.canceled_file);
2334
2335 break;
2336
2337 case 'p':
2338 if (!fscanf(u.drift_file, "%d", &i)) {
2339 perror("Drift file incomplete");
2340 goto fail;
2341 }
2342
2343 if (fread(pdata, i, 1, u.played_file) <= 0) {
2344 perror("Played file ended prematurely");
2345 goto fail;
2346 }
2347
2348 u.ec->play(u.ec, pdata);
2349
2350 break;
2351 }
2352 }
2353
2354 if (fread(rdata, i, 1, u.captured_file) > 0)
2355 pa_log("All capture data was not consumed");
2356 if (fread(pdata, i, 1, u.played_file) > 0)
2357 pa_log("All playback data was not consumed");
2358 }
2359
2360 u.ec->done(u.ec);
2361 u.ec->msg->dead = true;
2362 pa_echo_canceller_msg_unref(u.ec->msg);
2363
2364 out:
2365 if (u.captured_file)
2366 fclose(u.captured_file);
2367 if (u.played_file)
2368 fclose(u.played_file);
2369 if (u.canceled_file)
2370 fclose(u.canceled_file);
2371 if (u.drift_file)
2372 fclose(u.drift_file);
2373
2374 pa_xfree(rdata);
2375 pa_xfree(pdata);
2376 pa_xfree(cdata);
2377
2378 pa_xfree(u.ec);
2379 pa_xfree(u.core);
2380
2381 if (ma)
2382 pa_modargs_free(ma);
2383
2384 return ret;
2385
2386 usage:
2387 pa_log("Usage: %s play_file rec_file out_file [module args] [drift_file]", argv[0]);
2388
2389 fail:
2390 ret = -1;
2391 goto out;
2392 }
2393 #endif /* ECHO_CANCEL_TEST */
2394