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