2 This file is part of PulseAudio.
4 Copyright 2010 Wim Taymans <wim.taymans@gmail.com>
6 Based on module-virtual-sink.c
7 module-virtual-source.c
10 Copyright 2010 Intel Corporation
11 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
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.
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.
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
36 #include "echo-cancel.h"
38 #include <pulse/xmalloc.h>
39 #include <pulse/timeval.h>
40 #include <pulse/rtclock.h>
42 #include <pulsecore/i18n.h>
43 #include <pulsecore/atomic.h>
44 #include <pulsecore/macro.h>
45 #include <pulsecore/namereg.h>
46 #include <pulsecore/sink.h>
47 #include <pulsecore/module.h>
48 #include <pulsecore/core-rtclock.h>
49 #include <pulsecore/core-util.h>
50 #include <pulsecore/modargs.h>
51 #include <pulsecore/log.h>
52 #include <pulsecore/rtpoll.h>
53 #include <pulsecore/sample-util.h>
54 #include <pulsecore/ltdl-helper.h>
56 #include "module-echo-cancel-symdef.h"
58 PA_MODULE_AUTHOR("Wim Taymans");
59 PA_MODULE_DESCRIPTION("Echo Cancellation");
60 PA_MODULE_VERSION(PACKAGE_VERSION
);
61 PA_MODULE_LOAD_ONCE(FALSE
);
63 _("source_name=<name for the source> "
64 "source_properties=<properties for the source> "
65 "source_master=<name of source to filter> "
66 "sink_name=<name for the sink> "
67 "sink_properties=<properties for the sink> "
68 "sink_master=<name of sink to filter> "
69 "adjust_time=<how often to readjust rates in s> "
70 "adjust_threshold=<how much drift to readjust after in ms> "
71 "format=<sample format> "
73 "channels=<number of channels> "
74 "channel_map=<channel map> "
75 "aec_method=<implementation to use> "
76 "aec_args=<parameters for the AEC engine> "
77 "save_aec=<save AEC data in /tmp> "
78 "autoloaded=<set if this module is being loaded automatically> "
79 "use_volume_sharing=<yes or no> "
82 /* NOTE: Make sure the enum and ec_table are maintained in the correct order */
84 PA_ECHO_CANCELLER_INVALID
= -1,
85 PA_ECHO_CANCELLER_NULL
,
87 PA_ECHO_CANCELLER_SPEEX
,
90 PA_ECHO_CANCELLER_ADRIAN
,
93 PA_ECHO_CANCELLER_WEBRTC
,
95 } pa_echo_canceller_method_t
;
98 #define DEFAULT_ECHO_CANCELLER "webrtc"
100 #define DEFAULT_ECHO_CANCELLER "speex"
103 static const pa_echo_canceller ec_table
[] = {
105 /* Null, Dummy echo canceller (just copies data) */
106 .init
= pa_null_ec_init
,
107 .run
= pa_null_ec_run
,
108 .done
= pa_null_ec_done
,
113 .init
= pa_speex_ec_init
,
114 .run
= pa_speex_ec_run
,
115 .done
= pa_speex_ec_done
,
118 #ifdef HAVE_ADRIAN_EC
120 /* Adrian Andre's NLMS implementation */
121 .init
= pa_adrian_ec_init
,
122 .run
= pa_adrian_ec_run
,
123 .done
= pa_adrian_ec_done
,
128 /* WebRTC's audio processing engine */
129 .init
= pa_webrtc_ec_init
,
130 .play
= pa_webrtc_ec_play
,
131 .record
= pa_webrtc_ec_record
,
132 .set_drift
= pa_webrtc_ec_set_drift
,
133 .run
= pa_webrtc_ec_run
,
134 .done
= pa_webrtc_ec_done
,
139 #define DEFAULT_RATE 32000
140 #define DEFAULT_CHANNELS 1
141 #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC)
142 #define DEFAULT_ADJUST_TOLERANCE (5*PA_USEC_PER_MSEC)
143 #define DEFAULT_SAVE_AEC FALSE
144 #define DEFAULT_AUTOLOADED FALSE
146 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
148 /* Can only be used in main context */
149 #define IS_ACTIVE(u) ((pa_source_get_state((u)->source) == PA_SOURCE_RUNNING) && \
150 (pa_sink_get_state((u)->sink) == PA_SINK_RUNNING))
152 /* This module creates a new (virtual) source and sink.
154 * The data sent to the new sink is kept in a memblockq before being
155 * forwarded to the real sink_master.
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.
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.
165 * Alignment is performed in two steps:
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 canceler does not work) or when the
172 * playback pointer drifts too far away.
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.
183 struct pa_echo_canceller_msg
{
185 struct userdata
*userdata
;
188 PA_DEFINE_PRIVATE_CLASS(pa_echo_canceller_msg
, pa_msgobject
);
189 #define PA_ECHO_CANCELLER_MSG(o) (pa_echo_canceller_msg_cast(o))
193 pa_usec_t sink_latency
;
195 int64_t send_counter
;
197 pa_usec_t source_now
;
198 pa_usec_t source_latency
;
200 int64_t recv_counter
;
209 pa_bool_t autoloaded
;
213 pa_echo_canceller
*ec
;
214 uint32_t source_output_blocksize
;
215 uint32_t source_blocksize
;
216 uint32_t sink_blocksize
;
218 pa_bool_t need_realign
;
220 /* to wakeup the source I/O thread */
221 pa_asyncmsgq
*asyncmsgq
;
222 pa_rtpoll_item
*rtpoll_item_read
, *rtpoll_item_write
;
225 pa_bool_t source_auto_desc
;
226 pa_source_output
*source_output
;
227 pa_memblockq
*source_memblockq
; /* echo canceler needs fixed sized chunks */
231 pa_bool_t 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
;
238 /* Bytes left over from previous iteration */
242 pa_atomic_t request_resync
;
244 pa_time_event
*time_event
;
245 pa_usec_t adjust_time
;
246 int adjust_threshold
;
253 pa_bool_t use_volume_sharing
;
256 pa_cvolume current_volume
;
260 static void source_output_snapshot_within_thread(struct userdata
*u
, struct snapshot
*snapshot
);
262 static const char* const valid_modargs
[] = {
279 "use_volume_sharing",
284 SOURCE_OUTPUT_MESSAGE_POST
= PA_SOURCE_OUTPUT_MESSAGE_MAX
,
285 SOURCE_OUTPUT_MESSAGE_REWIND
,
286 SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT
,
287 SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
291 SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
295 ECHO_CANCELLER_MESSAGE_SET_VOLUME
,
298 static int64_t calc_diff(struct userdata
*u
, struct snapshot
*snapshot
) {
299 int64_t diff_time
, buffer_latency
;
300 pa_usec_t plen
, rlen
, source_delay
, sink_delay
, recv_counter
, send_counter
;
302 /* get latency difference between playback and record */
303 plen
= pa_bytes_to_usec(snapshot
->plen
, &u
->sink_input
->sample_spec
);
304 rlen
= pa_bytes_to_usec(snapshot
->rlen
, &u
->source_output
->sample_spec
);
306 buffer_latency
= plen
- rlen
;
310 source_delay
= pa_bytes_to_usec(snapshot
->source_delay
, &u
->source_output
->sample_spec
);
311 sink_delay
= pa_bytes_to_usec(snapshot
->sink_delay
, &u
->sink_input
->sample_spec
);
312 buffer_latency
+= source_delay
+ sink_delay
;
314 /* add the latency difference due to samples not yet transferred */
315 send_counter
= pa_bytes_to_usec(snapshot
->send_counter
, &u
->sink
->sample_spec
);
316 recv_counter
= pa_bytes_to_usec(snapshot
->recv_counter
, &u
->sink
->sample_spec
);
317 if (recv_counter
<= send_counter
)
318 buffer_latency
+= (int64_t) (send_counter
- recv_counter
);
320 buffer_latency
+= PA_CLIP_SUB(buffer_latency
, (int64_t) (recv_counter
- send_counter
));
322 /* capture and playback are perfectly aligned when diff_time is 0 */
323 diff_time
= (snapshot
->sink_now
+ snapshot
->sink_latency
- buffer_latency
) -
324 (snapshot
->source_now
- snapshot
->source_latency
);
326 pa_log_debug("Diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time
,
327 (long long) snapshot
->sink_latency
,
328 (long long) buffer_latency
, (long long) snapshot
->source_latency
,
329 (long long) source_delay
, (long long) sink_delay
,
330 (long long) (send_counter
- recv_counter
),
331 (long long) (snapshot
->sink_now
- snapshot
->source_now
));
336 /* Called from main context */
337 static void time_callback(pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*t
, void *userdata
) {
338 struct userdata
*u
= userdata
;
339 uint32_t old_rate
, base_rate
, new_rate
;
342 struct snapshot latency_snapshot
;
346 pa_assert(u
->time_event
== e
);
347 pa_assert_ctl_context();
352 /* update our snapshots */
353 pa_asyncmsgq_send(u
->source_output
->source
->asyncmsgq
, PA_MSGOBJECT(u
->source_output
), SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT
, &latency_snapshot
, 0, NULL
);
354 pa_asyncmsgq_send(u
->sink_input
->sink
->asyncmsgq
, PA_MSGOBJECT(u
->sink_input
), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
, &latency_snapshot
, 0, NULL
);
356 /* calculate drift between capture and playback */
357 diff_time
= calc_diff(u
, &latency_snapshot
);
359 /*fs = pa_frame_size(&u->source_output->sample_spec);*/
360 old_rate
= u
->sink_input
->sample_spec
.rate
;
361 base_rate
= u
->source_output
->sample_spec
.rate
;
364 /* recording before playback, we need to adjust quickly. The echo
365 * canceler does not work in this case. */
366 pa_asyncmsgq_post(u
->asyncmsgq
, PA_MSGOBJECT(u
->source_output
), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
,
367 NULL
, diff_time
, NULL
, NULL
);
368 /*new_rate = base_rate - ((pa_usec_to_bytes(-diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
369 new_rate
= base_rate
;
372 if (diff_time
> u
->adjust_threshold
) {
373 /* diff too big, quickly adjust */
374 pa_asyncmsgq_post(u
->asyncmsgq
, PA_MSGOBJECT(u
->source_output
), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
,
375 NULL
, diff_time
, NULL
, NULL
);
378 /* recording behind playback, we need to slowly adjust the rate to match */
379 /*new_rate = base_rate + ((pa_usec_to_bytes(diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
381 /* assume equal samplerates for now */
382 new_rate
= base_rate
;
385 /* make sure we don't make too big adjustments because that sounds horrible */
386 if (new_rate
> base_rate
* 1.1 || new_rate
< base_rate
* 0.9)
387 new_rate
= base_rate
;
389 if (new_rate
!= old_rate
) {
390 pa_log_info("Old rate %lu Hz, new rate %lu Hz", (unsigned long) old_rate
, (unsigned long) new_rate
);
392 pa_sink_input_set_rate(u
->sink_input
, new_rate
);
395 pa_core_rttime_restart(u
->core
, u
->time_event
, pa_rtclock_now() + u
->adjust_time
);
398 /* Called from source I/O thread context */
399 static int source_process_msg_cb(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
400 struct userdata
*u
= PA_SOURCE(o
)->userdata
;
404 case PA_SOURCE_MESSAGE_GET_LATENCY
:
406 /* The source is _put() before the source output is, so let's
407 * make sure we don't access it in that time. Also, the
408 * source output is first shut down, the source second. */
409 if (!PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
) ||
410 !PA_SOURCE_OUTPUT_IS_LINKED(u
->source_output
->thread_info
.state
)) {
411 *((pa_usec_t
*) data
) = 0;
415 *((pa_usec_t
*) data
) =
417 /* Get the latency of the master source */
418 pa_source_get_latency_within_thread(u
->source_output
->source
) +
419 /* Add the latency internal to our source output on top */
420 pa_bytes_to_usec(pa_memblockq_get_length(u
->source_output
->thread_info
.delay_memblockq
), &u
->source_output
->source
->sample_spec
) +
421 /* and the buffering we do on the source */
422 pa_bytes_to_usec(u
->source_output_blocksize
, &u
->source_output
->source
->sample_spec
);
426 case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED
:
427 u
->thread_info
.current_volume
= u
->source
->reference_volume
;
431 return pa_source_process_msg(o
, code
, data
, offset
, chunk
);
434 /* Called from sink I/O thread context */
435 static int sink_process_msg_cb(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
436 struct userdata
*u
= PA_SINK(o
)->userdata
;
440 case PA_SINK_MESSAGE_GET_LATENCY
:
442 /* The sink is _put() before the sink input is, so let's
443 * make sure we don't access it in that time. Also, the
444 * sink input is first shut down, the sink second. */
445 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
446 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
)) {
447 *((pa_usec_t
*) data
) = 0;
451 *((pa_usec_t
*) data
) =
453 /* Get the latency of the master sink */
454 pa_sink_get_latency_within_thread(u
->sink_input
->sink
) +
456 /* Add the latency internal to our sink input on top */
457 pa_bytes_to_usec(pa_memblockq_get_length(u
->sink_input
->thread_info
.render_memblockq
), &u
->sink_input
->sink
->sample_spec
);
462 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
466 /* Called from main context */
467 static int source_set_state_cb(pa_source
*s
, pa_source_state_t state
) {
470 pa_source_assert_ref(s
);
471 pa_assert_se(u
= s
->userdata
);
473 if (!PA_SOURCE_IS_LINKED(state
) ||
474 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
)))
477 if (state
== PA_SOURCE_RUNNING
) {
478 /* restart timer when both sink and source are active */
479 if (IS_ACTIVE(u
) && u
->adjust_time
)
480 pa_core_rttime_restart(u
->core
, u
->time_event
, pa_rtclock_now() + u
->adjust_time
);
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
);
491 /* Called from main context */
492 static int sink_set_state_cb(pa_sink
*s
, pa_sink_state_t state
) {
495 pa_sink_assert_ref(s
);
496 pa_assert_se(u
= s
->userdata
);
498 if (!PA_SINK_IS_LINKED(state
) ||
499 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
502 if (state
== PA_SINK_RUNNING
) {
503 /* restart timer when both sink and source are active */
504 if (IS_ACTIVE(u
) && u
->adjust_time
)
505 pa_core_rttime_restart(u
->core
, u
->time_event
, pa_rtclock_now() + u
->adjust_time
);
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
);
516 /* Called from source I/O thread context */
517 static void source_update_requested_latency_cb(pa_source
*s
) {
520 pa_source_assert_ref(s
);
521 pa_assert_se(u
= s
->userdata
);
523 if (!PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
) ||
524 !PA_SOURCE_OUTPUT_IS_LINKED(u
->source_output
->thread_info
.state
))
527 pa_log_debug("Source update requested latency");
529 /* Just hand this one over to the master source */
530 pa_source_output_set_requested_latency_within_thread(
532 pa_source_get_requested_latency_within_thread(s
));
535 /* Called from sink I/O thread context */
536 static void sink_update_requested_latency_cb(pa_sink
*s
) {
539 pa_sink_assert_ref(s
);
540 pa_assert_se(u
= s
->userdata
);
542 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
543 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
546 pa_log_debug("Sink update requested latency");
548 /* Just hand this one over to the master sink */
549 pa_sink_input_set_requested_latency_within_thread(
551 pa_sink_get_requested_latency_within_thread(s
));
554 /* Called from sink I/O thread context */
555 static void sink_request_rewind_cb(pa_sink
*s
) {
558 pa_sink_assert_ref(s
);
559 pa_assert_se(u
= s
->userdata
);
561 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
562 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
565 pa_log_debug("Sink request rewind %lld", (long long) s
->thread_info
.rewind_nbytes
);
567 /* Just hand this one over to the master sink */
568 pa_sink_input_request_rewind(u
->sink_input
,
569 s
->thread_info
.rewind_nbytes
, TRUE
, FALSE
, FALSE
);
572 /* Called from main context */
573 static void source_set_volume_cb(pa_source
*s
) {
576 pa_source_assert_ref(s
);
577 pa_assert_se(u
= s
->userdata
);
579 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s
)) ||
580 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
)))
583 pa_source_output_set_volume(u
->source_output
, &s
->real_volume
, s
->save_volume
, TRUE
);
586 /* Called from main context */
587 static void sink_set_volume_cb(pa_sink
*s
) {
590 pa_sink_assert_ref(s
);
591 pa_assert_se(u
= s
->userdata
);
593 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
594 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
597 pa_sink_input_set_volume(u
->sink_input
, &s
->real_volume
, s
->save_volume
, TRUE
);
600 /* Called from main context. */
601 static void source_get_volume_cb(pa_source
*s
) {
605 pa_source_assert_ref(s
);
606 pa_assert_se(u
= s
->userdata
);
608 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s
)) ||
609 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
)))
612 pa_source_output_get_volume(u
->source_output
, &v
, TRUE
);
614 if (pa_cvolume_equal(&s
->real_volume
, &v
))
619 pa_source_set_soft_volume(s
, NULL
);
622 /* Called from main context */
623 static void source_set_mute_cb(pa_source
*s
) {
626 pa_source_assert_ref(s
);
627 pa_assert_se(u
= s
->userdata
);
629 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s
)) ||
630 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
)))
633 pa_source_output_set_mute(u
->source_output
, s
->muted
, s
->save_muted
);
636 /* Called from main context */
637 static void sink_set_mute_cb(pa_sink
*s
) {
640 pa_sink_assert_ref(s
);
641 pa_assert_se(u
= s
->userdata
);
643 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
644 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
647 pa_sink_input_set_mute(u
->sink_input
, s
->muted
, s
->save_muted
);
650 /* Called from main context */
651 static void source_get_mute_cb(pa_source
*s
) {
654 pa_source_assert_ref(s
);
655 pa_assert_se(u
= s
->userdata
);
657 if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s
)) ||
658 !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
)))
661 pa_source_output_get_mute(u
->source_output
);
664 /* Called from source I/O thread context. */
665 static void apply_diff_time(struct userdata
*u
, int64_t diff_time
) {
669 diff
= pa_usec_to_bytes(-diff_time
, &u
->sink_input
->sample_spec
);
672 /* add some extra safety samples to compensate for jitter in the
674 diff
+= 10 * pa_frame_size (&u
->sink_input
->sample_spec
);
676 pa_log("Playback after capture (%lld), drop sink %lld", (long long) diff_time
, (long long) diff
);
681 } else if (diff_time
> 0) {
682 diff
= pa_usec_to_bytes(diff_time
, &u
->source_output
->sample_spec
);
685 pa_log("Playback too far ahead (%lld), drop source %lld", (long long) diff_time
, (long long) diff
);
687 u
->source_skip
= diff
;
693 /* Called from source I/O thread context. */
694 static void do_resync(struct userdata
*u
) {
696 struct snapshot latency_snapshot
;
698 pa_log("Doing resync");
700 /* update our snapshot */
701 source_output_snapshot_within_thread(u
, &latency_snapshot
);
702 pa_asyncmsgq_send(u
->sink_input
->sink
->asyncmsgq
, PA_MSGOBJECT(u
->sink_input
), SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
, &latency_snapshot
, 0, NULL
);
704 /* calculate drift between capture and playback */
705 diff_time
= calc_diff(u
, &latency_snapshot
);
707 /* and adjust for the drift */
708 apply_diff_time(u
, diff_time
);
711 /* 1. Calculate drift at this point, pass to canceller
712 * 2. Push out playback samples in blocksize chunks
713 * 3. Push out capture samples in blocksize chunks
717 * Called from source I/O thread context.
719 static void do_push_drift_comp(struct userdata
*u
) {
721 pa_memchunk rchunk
, pchunk
, cchunk
;
722 uint8_t *rdata
, *pdata
, *cdata
;
724 int unused PA_GCC_UNUSED
;
726 rlen
= pa_memblockq_get_length(u
->source_memblockq
);
727 plen
= pa_memblockq_get_length(u
->sink_memblockq
);
729 /* Estimate snapshot drift as follows:
730 * pd: amount of data consumed since last time
731 * rd: amount of data consumed since last time
733 * drift = (pd - rd) / rd;
735 * We calculate pd and rd as the memblockq length less the number of
736 * samples left from the last iteration (to avoid double counting
737 * those remainder samples.
739 drift
= ((float)(plen
- u
->sink_rem
) - (rlen
- u
->source_rem
)) / ((float)(rlen
- u
->source_rem
));
740 u
->sink_rem
= plen
% u
->sink_blocksize
;
741 u
->source_rem
= rlen
% u
->source_output_blocksize
;
743 /* Now let the canceller work its drift compensation magic */
744 u
->ec
->set_drift(u
->ec
, drift
);
748 fprintf(u
->drift_file
, "d %a\n", drift
);
751 /* Send in the playback samples first */
752 while (plen
>= u
->sink_blocksize
) {
753 pa_memblockq_peek_fixed_size(u
->sink_memblockq
, u
->sink_blocksize
, &pchunk
);
754 pdata
= pa_memblock_acquire(pchunk
.memblock
);
755 pdata
+= pchunk
.index
;
757 u
->ec
->play(u
->ec
, pdata
);
761 fprintf(u
->drift_file
, "p %d\n", u
->sink_blocksize
);
763 unused
= fwrite(pdata
, 1, u
->sink_blocksize
, u
->played_file
);
766 pa_memblock_release(pchunk
.memblock
);
767 pa_memblockq_drop(u
->sink_memblockq
, u
->sink_blocksize
);
768 pa_memblock_unref(pchunk
.memblock
);
770 plen
-= u
->sink_blocksize
;
773 /* And now the capture samples */
774 while (rlen
>= u
->source_output_blocksize
) {
775 pa_memblockq_peek_fixed_size(u
->source_memblockq
, u
->source_output_blocksize
, &rchunk
);
777 rdata
= pa_memblock_acquire(rchunk
.memblock
);
778 rdata
+= rchunk
.index
;
781 cchunk
.length
= u
->source_output_blocksize
;
782 cchunk
.memblock
= pa_memblock_new(u
->source
->core
->mempool
, cchunk
.length
);
783 cdata
= pa_memblock_acquire(cchunk
.memblock
);
785 u
->ec
->record(u
->ec
, rdata
, cdata
);
789 fprintf(u
->drift_file
, "c %d\n", u
->source_output_blocksize
);
790 if (u
->captured_file
)
791 unused
= fwrite(rdata
, 1, u
->source_output_blocksize
, u
->captured_file
);
792 if (u
->canceled_file
)
793 unused
= fwrite(cdata
, 1, u
->source_output_blocksize
, u
->canceled_file
);
796 pa_memblock_release(cchunk
.memblock
);
797 pa_memblock_release(rchunk
.memblock
);
799 pa_memblock_unref(rchunk
.memblock
);
801 pa_source_post(u
->source
, &cchunk
);
802 pa_memblock_unref(cchunk
.memblock
);
804 pa_memblockq_drop(u
->source_memblockq
, u
->source_output_blocksize
);
805 rlen
-= u
->source_output_blocksize
;
809 /* This one's simpler than the drift compensation case -- we just iterate over
810 * the capture buffer, and pass the canceller blocksize bytes of playback and
813 * Called from source I/O thread context. */
814 static void do_push(struct userdata
*u
) {
816 pa_memchunk rchunk
, pchunk
, cchunk
;
817 uint8_t *rdata
, *pdata
, *cdata
;
818 int unused PA_GCC_UNUSED
;
820 rlen
= pa_memblockq_get_length(u
->source_memblockq
);
821 plen
= pa_memblockq_get_length(u
->sink_memblockq
);
823 while (rlen
>= u
->source_output_blocksize
) {
825 /* take fixed blocks from recorded and played samples */
826 pa_memblockq_peek_fixed_size(u
->source_memblockq
, u
->source_output_blocksize
, &rchunk
);
827 pa_memblockq_peek_fixed_size(u
->sink_memblockq
, u
->sink_blocksize
, &pchunk
);
829 /* we ran out of played data and pchunk has been filled with silence bytes */
830 if (plen
< u
->sink_blocksize
)
831 pa_memblockq_seek(u
->sink_memblockq
, u
->sink_blocksize
- plen
, PA_SEEK_RELATIVE
, true);
833 rdata
= pa_memblock_acquire(rchunk
.memblock
);
834 rdata
+= rchunk
.index
;
835 pdata
= pa_memblock_acquire(pchunk
.memblock
);
836 pdata
+= pchunk
.index
;
839 cchunk
.length
= u
->source_blocksize
;
840 cchunk
.memblock
= pa_memblock_new(u
->source
->core
->mempool
, cchunk
.length
);
841 cdata
= pa_memblock_acquire(cchunk
.memblock
);
844 if (u
->captured_file
)
845 unused
= fwrite(rdata
, 1, u
->source_output_blocksize
, u
->captured_file
);
847 unused
= fwrite(pdata
, 1, u
->sink_blocksize
, u
->played_file
);
850 /* perform echo cancellation */
851 u
->ec
->run(u
->ec
, rdata
, pdata
, cdata
);
854 if (u
->canceled_file
)
855 unused
= fwrite(cdata
, 1, u
->source_blocksize
, u
->canceled_file
);
858 pa_memblock_release(cchunk
.memblock
);
859 pa_memblock_release(pchunk
.memblock
);
860 pa_memblock_release(rchunk
.memblock
);
862 /* drop consumed source samples */
863 pa_memblockq_drop(u
->source_memblockq
, u
->source_output_blocksize
);
864 pa_memblock_unref(rchunk
.memblock
);
865 rlen
-= u
->source_output_blocksize
;
867 /* drop consumed sink samples */
868 pa_memblockq_drop(u
->sink_memblockq
, u
->sink_blocksize
);
869 pa_memblock_unref(pchunk
.memblock
);
871 if (plen
>= u
->sink_blocksize
)
872 plen
-= u
->sink_blocksize
;
876 /* forward the (echo-canceled) data to the virtual source */
877 pa_source_post(u
->source
, &cchunk
);
878 pa_memblock_unref(cchunk
.memblock
);
882 /* Called from source I/O thread context. */
883 static void source_output_push_cb(pa_source_output
*o
, const pa_memchunk
*chunk
) {
885 size_t rlen
, plen
, to_skip
;
888 pa_source_output_assert_ref(o
);
889 pa_source_output_assert_io_context(o
);
890 pa_assert_se(u
= o
->userdata
);
892 if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u
->source_output
))) {
893 pa_log("Push when no link?");
897 if (PA_UNLIKELY(u
->source
->thread_info
.state
!= PA_SOURCE_RUNNING
||
898 u
->sink
->thread_info
.state
!= PA_SINK_RUNNING
)) {
899 pa_source_post(u
->source
, chunk
);
903 /* handle queued messages, do any message sending of our own */
904 while (pa_asyncmsgq_process_one(u
->asyncmsgq
) > 0)
907 pa_memblockq_push_align(u
->source_memblockq
, chunk
);
909 rlen
= pa_memblockq_get_length(u
->source_memblockq
);
910 plen
= pa_memblockq_get_length(u
->sink_memblockq
);
912 /* Let's not do anything else till we have enough data to process */
913 if (rlen
< u
->source_output_blocksize
)
916 /* See if we need to drop samples in order to sync */
917 if (pa_atomic_cmpxchg (&u
->request_resync
, 1, 0)) {
921 /* Okay, skip cancellation for skipped source samples if needed. */
922 if (PA_UNLIKELY(u
->source_skip
)) {
923 /* The slightly tricky bit here is that we drop all but modulo
924 * blocksize bytes and then adjust for that last bit on the sink side.
925 * We do this because the source data is coming at a fixed rate, which
926 * means the only way to try to catch up is drop sink samples and let
927 * the canceller cope up with this. */
928 to_skip
= rlen
>= u
->source_skip
? u
->source_skip
: rlen
;
929 to_skip
-= to_skip
% u
->source_output_blocksize
;
932 pa_memblockq_peek_fixed_size(u
->source_memblockq
, to_skip
, &rchunk
);
933 pa_source_post(u
->source
, &rchunk
);
935 pa_memblock_unref(rchunk
.memblock
);
936 pa_memblockq_drop(u
->source_memblockq
, to_skip
);
939 u
->source_skip
-= to_skip
;
942 if (rlen
&& u
->source_skip
% u
->source_output_blocksize
) {
943 u
->sink_skip
+= (uint64_t) (u
->source_output_blocksize
- (u
->source_skip
% u
->source_output_blocksize
)) * u
->sink_blocksize
/ u
->source_output_blocksize
;
944 u
->source_skip
-= (u
->source_skip
% u
->source_output_blocksize
);
948 /* And for the sink, these samples have been played back already, so we can
949 * just drop them and get on with it. */
950 if (PA_UNLIKELY(u
->sink_skip
)) {
951 to_skip
= plen
>= u
->sink_skip
? u
->sink_skip
: plen
;
953 pa_memblockq_drop(u
->sink_memblockq
, to_skip
);
956 u
->sink_skip
-= to_skip
;
959 /* process and push out samples */
960 if (u
->ec
->params
.drift_compensation
)
961 do_push_drift_comp(u
);
966 /* Called from sink I/O thread context. */
967 static int sink_input_pop_cb(pa_sink_input
*i
, size_t nbytes
, pa_memchunk
*chunk
) {
970 pa_sink_input_assert_ref(i
);
972 pa_assert_se(u
= i
->userdata
);
974 if (u
->sink
->thread_info
.rewind_requested
)
975 pa_sink_process_rewind(u
->sink
, 0);
977 pa_sink_render_full(u
->sink
, nbytes
, chunk
);
979 if (i
->thread_info
.underrun_for
> 0) {
980 pa_log_debug("Handling end of underrun.");
981 pa_atomic_store(&u
->request_resync
, 1);
984 /* let source thread handle the chunk. pass the sample count as well so that
985 * the source IO thread can update the right variables. */
986 pa_asyncmsgq_post(u
->asyncmsgq
, PA_MSGOBJECT(u
->source_output
), SOURCE_OUTPUT_MESSAGE_POST
,
987 NULL
, 0, chunk
, NULL
);
988 u
->send_counter
+= chunk
->length
;
993 /* Called from source I/O thread context. */
994 static void source_output_process_rewind_cb(pa_source_output
*o
, size_t nbytes
) {
997 pa_source_output_assert_ref(o
);
998 pa_source_output_assert_io_context(o
);
999 pa_assert_se(u
= o
->userdata
);
1001 pa_source_process_rewind(u
->source
, nbytes
);
1003 /* go back on read side, we need to use older sink data for this */
1004 pa_memblockq_rewind(u
->sink_memblockq
, nbytes
);
1006 /* manipulate write index */
1007 pa_memblockq_seek(u
->source_memblockq
, -nbytes
, PA_SEEK_RELATIVE
, TRUE
);
1009 pa_log_debug("Source rewind (%lld) %lld", (long long) nbytes
,
1010 (long long) pa_memblockq_get_length (u
->source_memblockq
));
1013 /* Called from sink I/O thread context. */
1014 static void sink_input_process_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
1017 pa_sink_input_assert_ref(i
);
1018 pa_assert_se(u
= i
->userdata
);
1020 pa_log_debug("Sink process rewind %lld", (long long) nbytes
);
1022 pa_sink_process_rewind(u
->sink
, nbytes
);
1024 pa_asyncmsgq_post(u
->asyncmsgq
, PA_MSGOBJECT(u
->source_output
), SOURCE_OUTPUT_MESSAGE_REWIND
, NULL
, (int64_t) nbytes
, NULL
, NULL
);
1025 u
->send_counter
-= nbytes
;
1028 /* Called from source I/O thread context. */
1029 static void source_output_snapshot_within_thread(struct userdata
*u
, struct snapshot
*snapshot
) {
1030 size_t delay
, rlen
, plen
;
1031 pa_usec_t now
, latency
;
1033 now
= pa_rtclock_now();
1034 latency
= pa_source_get_latency_within_thread(u
->source_output
->source
);
1035 delay
= pa_memblockq_get_length(u
->source_output
->thread_info
.delay_memblockq
);
1037 delay
= (u
->source_output
->thread_info
.resampler
? pa_resampler_request(u
->source_output
->thread_info
.resampler
, delay
) : delay
);
1038 rlen
= pa_memblockq_get_length(u
->source_memblockq
);
1039 plen
= pa_memblockq_get_length(u
->sink_memblockq
);
1041 snapshot
->source_now
= now
;
1042 snapshot
->source_latency
= latency
;
1043 snapshot
->source_delay
= delay
;
1044 snapshot
->recv_counter
= u
->recv_counter
;
1045 snapshot
->rlen
= rlen
+ u
->sink_skip
;
1046 snapshot
->plen
= plen
+ u
->source_skip
;
1049 /* Called from source I/O thread context. */
1050 static int source_output_process_msg_cb(pa_msgobject
*obj
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
1051 struct userdata
*u
= PA_SOURCE_OUTPUT(obj
)->userdata
;
1055 case SOURCE_OUTPUT_MESSAGE_POST
:
1057 pa_source_output_assert_io_context(u
->source_output
);
1059 if (u
->source_output
->source
->thread_info
.state
== PA_SOURCE_RUNNING
)
1060 pa_memblockq_push_align(u
->sink_memblockq
, chunk
);
1062 pa_memblockq_flush_write(u
->sink_memblockq
, TRUE
);
1064 u
->recv_counter
+= (int64_t) chunk
->length
;
1068 case SOURCE_OUTPUT_MESSAGE_REWIND
:
1069 pa_source_output_assert_io_context(u
->source_output
);
1071 /* manipulate write index, never go past what we have */
1072 if (PA_SOURCE_IS_OPENED(u
->source_output
->source
->thread_info
.state
))
1073 pa_memblockq_seek(u
->sink_memblockq
, -offset
, PA_SEEK_RELATIVE
, TRUE
);
1075 pa_memblockq_flush_write(u
->sink_memblockq
, TRUE
);
1077 pa_log_debug("Sink rewind (%lld)", (long long) offset
);
1079 u
->recv_counter
-= offset
;
1083 case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT
: {
1084 struct snapshot
*snapshot
= (struct snapshot
*) data
;
1086 source_output_snapshot_within_thread(u
, snapshot
);
1090 case SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME
:
1091 apply_diff_time(u
, offset
);
1096 return pa_source_output_process_msg(obj
, code
, data
, offset
, chunk
);
1099 /* Called from sink I/O thread context. */
1100 static int sink_input_process_msg_cb(pa_msgobject
*obj
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
1101 struct userdata
*u
= PA_SINK_INPUT(obj
)->userdata
;
1105 case SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
: {
1107 pa_usec_t now
, latency
;
1108 struct snapshot
*snapshot
= (struct snapshot
*) data
;
1110 pa_sink_input_assert_io_context(u
->sink_input
);
1112 now
= pa_rtclock_now();
1113 latency
= pa_sink_get_latency_within_thread(u
->sink_input
->sink
);
1114 delay
= pa_memblockq_get_length(u
->sink_input
->thread_info
.render_memblockq
);
1116 delay
= (u
->sink_input
->thread_info
.resampler
? pa_resampler_request(u
->sink_input
->thread_info
.resampler
, delay
) : delay
);
1118 snapshot
->sink_now
= now
;
1119 snapshot
->sink_latency
= latency
;
1120 snapshot
->sink_delay
= delay
;
1121 snapshot
->send_counter
= u
->send_counter
;
1126 return pa_sink_input_process_msg(obj
, code
, data
, offset
, chunk
);
1129 /* Called from sink I/O thread context. */
1130 static void sink_input_update_max_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
1133 pa_sink_input_assert_ref(i
);
1134 pa_assert_se(u
= i
->userdata
);
1136 pa_log_debug("Sink input update max rewind %lld", (long long) nbytes
);
1138 /* FIXME: Too small max_rewind:
1139 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
1140 pa_memblockq_set_maxrewind(u
->sink_memblockq
, nbytes
);
1141 pa_sink_set_max_rewind_within_thread(u
->sink
, nbytes
);
1144 /* Called from source I/O thread context. */
1145 static void source_output_update_max_rewind_cb(pa_source_output
*o
, size_t nbytes
) {
1148 pa_source_output_assert_ref(o
);
1149 pa_assert_se(u
= o
->userdata
);
1151 pa_log_debug("Source output update max rewind %lld", (long long) nbytes
);
1153 pa_source_set_max_rewind_within_thread(u
->source
, nbytes
);
1156 /* Called from sink I/O thread context. */
1157 static void sink_input_update_max_request_cb(pa_sink_input
*i
, size_t nbytes
) {
1160 pa_sink_input_assert_ref(i
);
1161 pa_assert_se(u
= i
->userdata
);
1163 pa_log_debug("Sink input update max request %lld", (long long) nbytes
);
1165 pa_sink_set_max_request_within_thread(u
->sink
, nbytes
);
1168 /* Called from sink I/O thread context. */
1169 static void sink_input_update_sink_requested_latency_cb(pa_sink_input
*i
) {
1173 pa_sink_input_assert_ref(i
);
1174 pa_assert_se(u
= i
->userdata
);
1176 latency
= pa_sink_get_requested_latency_within_thread(i
->sink
);
1178 pa_log_debug("Sink input update requested latency %lld", (long long) latency
);
1181 /* Called from source I/O thread context. */
1182 static void source_output_update_source_requested_latency_cb(pa_source_output
*o
) {
1186 pa_source_output_assert_ref(o
);
1187 pa_assert_se(u
= o
->userdata
);
1189 latency
= pa_source_get_requested_latency_within_thread(o
->source
);
1191 pa_log_debug("Source output update requested latency %lld", (long long) latency
);
1194 /* Called from sink I/O thread context. */
1195 static void sink_input_update_sink_latency_range_cb(pa_sink_input
*i
) {
1198 pa_sink_input_assert_ref(i
);
1199 pa_assert_se(u
= i
->userdata
);
1201 pa_log_debug("Sink input update latency range %lld %lld",
1202 (long long) i
->sink
->thread_info
.min_latency
,
1203 (long long) i
->sink
->thread_info
.max_latency
);
1205 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1208 /* Called from source I/O thread context. */
1209 static void source_output_update_source_latency_range_cb(pa_source_output
*o
) {
1212 pa_source_output_assert_ref(o
);
1213 pa_assert_se(u
= o
->userdata
);
1215 pa_log_debug("Source output update latency range %lld %lld",
1216 (long long) o
->source
->thread_info
.min_latency
,
1217 (long long) o
->source
->thread_info
.max_latency
);
1219 pa_source_set_latency_range_within_thread(u
->source
, o
->source
->thread_info
.min_latency
, o
->source
->thread_info
.max_latency
);
1222 /* Called from sink I/O thread context. */
1223 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input
*i
) {
1226 pa_sink_input_assert_ref(i
);
1227 pa_assert_se(u
= i
->userdata
);
1229 pa_log_debug("Sink input update fixed latency %lld",
1230 (long long) i
->sink
->thread_info
.fixed_latency
);
1232 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
1235 /* Called from source I/O thread context. */
1236 static void source_output_update_source_fixed_latency_cb(pa_source_output
*o
) {
1239 pa_source_output_assert_ref(o
);
1240 pa_assert_se(u
= o
->userdata
);
1242 pa_log_debug("Source output update fixed latency %lld",
1243 (long long) o
->source
->thread_info
.fixed_latency
);
1245 pa_source_set_fixed_latency_within_thread(u
->source
, o
->source
->thread_info
.fixed_latency
);
1248 /* Called from source I/O thread context. */
1249 static void source_output_attach_cb(pa_source_output
*o
) {
1252 pa_source_output_assert_ref(o
);
1253 pa_source_output_assert_io_context(o
);
1254 pa_assert_se(u
= o
->userdata
);
1256 pa_source_set_rtpoll(u
->source
, o
->source
->thread_info
.rtpoll
);
1257 pa_source_set_latency_range_within_thread(u
->source
, o
->source
->thread_info
.min_latency
, o
->source
->thread_info
.max_latency
);
1258 pa_source_set_fixed_latency_within_thread(u
->source
, o
->source
->thread_info
.fixed_latency
);
1259 pa_source_set_max_rewind_within_thread(u
->source
, pa_source_output_get_max_rewind(o
));
1261 pa_log_debug("Source output %d attach", o
->index
);
1263 pa_source_attach_within_thread(u
->source
);
1265 u
->rtpoll_item_read
= pa_rtpoll_item_new_asyncmsgq_read(
1266 o
->source
->thread_info
.rtpoll
,
1271 /* Called from sink I/O thread context. */
1272 static void sink_input_attach_cb(pa_sink_input
*i
) {
1275 pa_sink_input_assert_ref(i
);
1276 pa_assert_se(u
= i
->userdata
);
1278 pa_sink_set_rtpoll(u
->sink
, i
->sink
->thread_info
.rtpoll
);
1279 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1281 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
1282 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
1283 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
1285 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
1286 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
1288 pa_sink_set_max_request_within_thread(u
->sink
, pa_sink_input_get_max_request(i
));
1290 /* FIXME: Too small max_rewind:
1291 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
1292 pa_sink_set_max_rewind_within_thread(u
->sink
, pa_sink_input_get_max_rewind(i
));
1294 pa_log_debug("Sink input %d attach", i
->index
);
1296 u
->rtpoll_item_write
= pa_rtpoll_item_new_asyncmsgq_write(
1297 i
->sink
->thread_info
.rtpoll
,
1301 pa_sink_attach_within_thread(u
->sink
);
1305 /* Called from source I/O thread context. */
1306 static void source_output_detach_cb(pa_source_output
*o
) {
1309 pa_source_output_assert_ref(o
);
1310 pa_source_output_assert_io_context(o
);
1311 pa_assert_se(u
= o
->userdata
);
1313 pa_source_detach_within_thread(u
->source
);
1314 pa_source_set_rtpoll(u
->source
, NULL
);
1316 pa_log_debug("Source output %d detach", o
->index
);
1318 if (u
->rtpoll_item_read
) {
1319 pa_rtpoll_item_free(u
->rtpoll_item_read
);
1320 u
->rtpoll_item_read
= NULL
;
1324 /* Called from sink I/O thread context. */
1325 static void sink_input_detach_cb(pa_sink_input
*i
) {
1328 pa_sink_input_assert_ref(i
);
1329 pa_assert_se(u
= i
->userdata
);
1331 pa_sink_detach_within_thread(u
->sink
);
1333 pa_sink_set_rtpoll(u
->sink
, NULL
);
1335 pa_log_debug("Sink input %d detach", i
->index
);
1337 if (u
->rtpoll_item_write
) {
1338 pa_rtpoll_item_free(u
->rtpoll_item_write
);
1339 u
->rtpoll_item_write
= NULL
;
1343 /* Called from source I/O thread context. */
1344 static void source_output_state_change_cb(pa_source_output
*o
, pa_source_output_state_t state
) {
1347 pa_source_output_assert_ref(o
);
1348 pa_source_output_assert_io_context(o
);
1349 pa_assert_se(u
= o
->userdata
);
1351 pa_log_debug("Source output %d state %d", o
->index
, state
);
1354 /* Called from sink I/O thread context. */
1355 static void sink_input_state_change_cb(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1358 pa_sink_input_assert_ref(i
);
1359 pa_assert_se(u
= i
->userdata
);
1361 pa_log_debug("Sink input %d state %d", i
->index
, state
);
1363 /* If we are added for the first time, ask for a rewinding so that
1364 * we are heard right-away. */
1365 if (PA_SINK_INPUT_IS_LINKED(state
) &&
1366 i
->thread_info
.state
== PA_SINK_INPUT_INIT
) {
1367 pa_log_debug("Requesting rewind due to state change.");
1368 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1372 /* Called from main context. */
1373 static void source_output_kill_cb(pa_source_output
*o
) {
1376 pa_source_output_assert_ref(o
);
1377 pa_assert_ctl_context();
1378 pa_assert_se(u
= o
->userdata
);
1382 /* The order here matters! We first kill the source output, followed
1383 * by the source. That means the source callbacks must be protected
1384 * against an unconnected source output! */
1385 pa_source_output_unlink(u
->source_output
);
1386 pa_source_unlink(u
->source
);
1388 pa_source_output_unref(u
->source_output
);
1389 u
->source_output
= NULL
;
1391 pa_source_unref(u
->source
);
1394 pa_log_debug("Source output kill %d", o
->index
);
1396 pa_module_unload_request(u
->module
, TRUE
);
1399 /* Called from main context */
1400 static void sink_input_kill_cb(pa_sink_input
*i
) {
1403 pa_sink_input_assert_ref(i
);
1404 pa_assert_se(u
= i
->userdata
);
1408 /* The order here matters! We first kill the sink input, followed
1409 * by the sink. That means the sink callbacks must be protected
1410 * against an unconnected sink input! */
1411 pa_sink_input_unlink(u
->sink_input
);
1412 pa_sink_unlink(u
->sink
);
1414 pa_sink_input_unref(u
->sink_input
);
1415 u
->sink_input
= NULL
;
1417 pa_sink_unref(u
->sink
);
1420 pa_log_debug("Sink input kill %d", i
->index
);
1422 pa_module_unload_request(u
->module
, TRUE
);
1425 /* Called from main context. */
1426 static pa_bool_t
source_output_may_move_to_cb(pa_source_output
*o
, pa_source
*dest
) {
1429 pa_source_output_assert_ref(o
);
1430 pa_assert_ctl_context();
1431 pa_assert_se(u
= o
->userdata
);
1433 if (u
->dead
|| u
->autoloaded
)
1436 return (u
->source
!= dest
) && (u
->sink
!= dest
->monitor_of
);
1439 /* Called from main context */
1440 static pa_bool_t
sink_input_may_move_to_cb(pa_sink_input
*i
, pa_sink
*dest
) {
1443 pa_sink_input_assert_ref(i
);
1444 pa_assert_se(u
= i
->userdata
);
1446 if (u
->dead
|| u
->autoloaded
)
1449 return u
->sink
!= dest
;
1452 /* Called from main context. */
1453 static void source_output_moving_cb(pa_source_output
*o
, pa_source
*dest
) {
1456 pa_source_output_assert_ref(o
);
1457 pa_assert_ctl_context();
1458 pa_assert_se(u
= o
->userdata
);
1461 pa_source_set_asyncmsgq(u
->source
, dest
->asyncmsgq
);
1462 pa_source_update_flags(u
->source
, PA_SOURCE_LATENCY
|PA_SOURCE_DYNAMIC_LATENCY
, dest
->flags
);
1464 pa_source_set_asyncmsgq(u
->source
, NULL
);
1466 if (u
->source_auto_desc
&& dest
) {
1470 pl
= pa_proplist_new();
1471 y
= pa_proplist_gets(u
->sink_input
->sink
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1472 z
= pa_proplist_gets(dest
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1473 pa_proplist_setf(pl
, PA_PROP_DEVICE_DESCRIPTION
, "%s (echo cancelled with %s)", z
? z
: dest
->name
,
1474 y
? y
: u
->sink_input
->sink
->name
);
1476 pa_source_update_proplist(u
->source
, PA_UPDATE_REPLACE
, pl
);
1477 pa_proplist_free(pl
);
1481 /* Called from main context */
1482 static void sink_input_moving_cb(pa_sink_input
*i
, pa_sink
*dest
) {
1485 pa_sink_input_assert_ref(i
);
1486 pa_assert_se(u
= i
->userdata
);
1489 pa_sink_set_asyncmsgq(u
->sink
, dest
->asyncmsgq
);
1490 pa_sink_update_flags(u
->sink
, PA_SINK_LATENCY
|PA_SINK_DYNAMIC_LATENCY
, dest
->flags
);
1492 pa_sink_set_asyncmsgq(u
->sink
, NULL
);
1494 if (u
->sink_auto_desc
&& dest
) {
1498 pl
= pa_proplist_new();
1499 y
= pa_proplist_gets(u
->source_output
->source
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1500 z
= pa_proplist_gets(dest
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1501 pa_proplist_setf(pl
, PA_PROP_DEVICE_DESCRIPTION
, "%s (echo cancelled with %s)", z
? z
: dest
->name
,
1502 y
? y
: u
->source_output
->source
->name
);
1504 pa_sink_update_proplist(u
->sink
, PA_UPDATE_REPLACE
, pl
);
1505 pa_proplist_free(pl
);
1509 /* Called from main context */
1510 static void sink_input_volume_changed_cb(pa_sink_input
*i
) {
1513 pa_sink_input_assert_ref(i
);
1514 pa_assert_se(u
= i
->userdata
);
1516 pa_sink_volume_changed(u
->sink
, &i
->volume
);
1519 /* Called from main context */
1520 static void sink_input_mute_changed_cb(pa_sink_input
*i
) {
1523 pa_sink_input_assert_ref(i
);
1524 pa_assert_se(u
= i
->userdata
);
1526 pa_sink_mute_changed(u
->sink
, i
->muted
);
1529 /* Called from main context */
1530 static int canceller_process_msg_cb(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1531 struct pa_echo_canceller_msg
*msg
;
1536 msg
= PA_ECHO_CANCELLER_MSG(o
);
1540 case ECHO_CANCELLER_MESSAGE_SET_VOLUME
: {
1541 pa_cvolume
*v
= (pa_cvolume
*) userdata
;
1543 if (u
->use_volume_sharing
)
1544 pa_source_set_volume(u
->source
, v
, TRUE
, FALSE
);
1546 pa_source_output_set_volume(u
->source_output
, v
, FALSE
, TRUE
);
1552 pa_assert_not_reached();
1559 /* Called by the canceller, so source I/O thread context. */
1560 void pa_echo_canceller_get_capture_volume(pa_echo_canceller
*ec
, pa_cvolume
*v
) {
1561 *v
= ec
->msg
->userdata
->thread_info
.current_volume
;
1564 /* Called by the canceller, so source I/O thread context. */
1565 void pa_echo_canceller_set_capture_volume(pa_echo_canceller
*ec
, pa_cvolume
*v
) {
1566 if (!pa_cvolume_equal(&ec
->msg
->userdata
->thread_info
.current_volume
, v
)) {
1567 pa_cvolume
*vol
= pa_xnewdup(pa_cvolume
, v
, 1);
1569 pa_asyncmsgq_post(pa_thread_mq_get()->outq
, PA_MSGOBJECT(ec
->msg
), ECHO_CANCELLER_MESSAGE_SET_VOLUME
, vol
, 0, NULL
,
1574 uint32_t pa_echo_canceller_blocksize_power2(unsigned rate
, unsigned ms
) {
1575 unsigned nframes
= (rate
* ms
) / 1000;
1576 uint32_t y
= 1 << ((8 * sizeof(uint32_t)) - 2);
1578 assert(rate
>= 4000);
1581 /* nframes should be a power of 2, round down to nearest power of two */
1589 static pa_echo_canceller_method_t
get_ec_method_from_string(const char *method
) {
1590 if (pa_streq(method
, "null"))
1591 return PA_ECHO_CANCELLER_NULL
;
1593 if (pa_streq(method
, "speex"))
1594 return PA_ECHO_CANCELLER_SPEEX
;
1596 #ifdef HAVE_ADRIAN_EC
1597 if (pa_streq(method
, "adrian"))
1598 return PA_ECHO_CANCELLER_ADRIAN
;
1601 if (pa_streq(method
, "webrtc"))
1602 return PA_ECHO_CANCELLER_WEBRTC
;
1604 return PA_ECHO_CANCELLER_INVALID
;
1607 /* Common initialisation bits between module-echo-cancel and the standalone
1610 * Called from main context. */
1611 static int init_common(pa_modargs
*ma
, struct userdata
*u
, pa_sample_spec
*source_ss
, pa_channel_map
*source_map
) {
1612 const char *ec_string
;
1613 pa_echo_canceller_method_t ec_method
;
1615 if (pa_modargs_get_sample_spec_and_channel_map(ma
, source_ss
, source_map
, PA_CHANNEL_MAP_DEFAULT
) < 0) {
1616 pa_log("Invalid sample format specification or channel map");
1620 u
->ec
= pa_xnew0(pa_echo_canceller
, 1);
1622 pa_log("Failed to alloc echo canceller");
1626 ec_string
= pa_modargs_get_value(ma
, "aec_method", DEFAULT_ECHO_CANCELLER
);
1627 if ((ec_method
= get_ec_method_from_string(ec_string
)) < 0) {
1628 pa_log("Invalid echo canceller implementation '%s'", ec_string
);
1632 pa_log_info("Using AEC engine: %s", ec_string
);
1634 u
->ec
->init
= ec_table
[ec_method
].init
;
1635 u
->ec
->play
= ec_table
[ec_method
].play
;
1636 u
->ec
->record
= ec_table
[ec_method
].record
;
1637 u
->ec
->set_drift
= ec_table
[ec_method
].set_drift
;
1638 u
->ec
->run
= ec_table
[ec_method
].run
;
1639 u
->ec
->done
= ec_table
[ec_method
].done
;
1647 /* Called from main context. */
1648 int pa__init(pa_module
*m
) {
1650 pa_sample_spec source_output_ss
, source_ss
, sink_ss
;
1651 pa_channel_map source_output_map
, source_map
, sink_map
;
1653 pa_source
*source_master
=NULL
;
1654 pa_sink
*sink_master
=NULL
;
1655 pa_source_output_new_data source_output_data
;
1656 pa_sink_input_new_data sink_input_data
;
1657 pa_source_new_data source_data
;
1658 pa_sink_new_data sink_data
;
1659 pa_memchunk silence
;
1661 uint32_t nframes
= 0;
1665 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
1666 pa_log("Failed to parse module arguments.");
1670 if (!(source_master
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "source_master", NULL
), PA_NAMEREG_SOURCE
))) {
1671 pa_log("Master source not found");
1674 pa_assert(source_master
);
1676 if (!(sink_master
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "sink_master", NULL
), PA_NAMEREG_SINK
))) {
1677 pa_log("Master sink not found");
1680 pa_assert(sink_master
);
1682 if (source_master
->monitor_of
== sink_master
) {
1683 pa_log("Can't cancel echo between a sink and its monitor");
1687 source_ss
= source_master
->sample_spec
;
1688 source_ss
.rate
= DEFAULT_RATE
;
1689 source_ss
.channels
= DEFAULT_CHANNELS
;
1690 pa_channel_map_init_auto(&source_map
, source_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
);
1692 sink_ss
= sink_master
->sample_spec
;
1693 sink_map
= sink_master
->channel_map
;
1695 u
= pa_xnew0(struct userdata
, 1);
1697 pa_log("Failed to alloc userdata");
1705 u
->use_volume_sharing
= TRUE
;
1706 if (pa_modargs_get_value_boolean(ma
, "use_volume_sharing", &u
->use_volume_sharing
) < 0) {
1707 pa_log("use_volume_sharing= expects a boolean argument");
1711 temp
= DEFAULT_ADJUST_TIME_USEC
/ PA_USEC_PER_SEC
;
1712 if (pa_modargs_get_value_u32(ma
, "adjust_time", &temp
) < 0) {
1713 pa_log("Failed to parse adjust_time value");
1717 if (temp
!= DEFAULT_ADJUST_TIME_USEC
/ PA_USEC_PER_SEC
)
1718 u
->adjust_time
= temp
* PA_USEC_PER_SEC
;
1720 u
->adjust_time
= DEFAULT_ADJUST_TIME_USEC
;
1722 temp
= DEFAULT_ADJUST_TOLERANCE
/ PA_USEC_PER_MSEC
;
1723 if (pa_modargs_get_value_u32(ma
, "adjust_threshold", &temp
) < 0) {
1724 pa_log("Failed to parse adjust_threshold value");
1728 if (temp
!= DEFAULT_ADJUST_TOLERANCE
/ PA_USEC_PER_MSEC
)
1729 u
->adjust_threshold
= temp
* PA_USEC_PER_MSEC
;
1731 u
->adjust_threshold
= DEFAULT_ADJUST_TOLERANCE
;
1733 u
->save_aec
= DEFAULT_SAVE_AEC
;
1734 if (pa_modargs_get_value_boolean(ma
, "save_aec", &u
->save_aec
) < 0) {
1735 pa_log("Failed to parse save_aec value");
1739 u
->autoloaded
= DEFAULT_AUTOLOADED
;
1740 if (pa_modargs_get_value_boolean(ma
, "autoloaded", &u
->autoloaded
) < 0) {
1741 pa_log("Failed to parse autoloaded value");
1745 if (init_common(ma
, u
, &source_ss
, &source_map
) < 0)
1748 u
->asyncmsgq
= pa_asyncmsgq_new(0);
1749 u
->need_realign
= TRUE
;
1751 source_output_ss
= source_ss
;
1752 source_output_map
= source_map
;
1754 if (sink_ss
.rate
!= source_ss
.rate
) {
1755 pa_log_info("Sample rates of play and out stream differ. Adjusting rate of play stream.");
1756 sink_ss
.rate
= source_ss
.rate
;
1759 pa_assert(u
->ec
->init
);
1760 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
))) {
1761 pa_log("Failed to init AEC engine");
1765 pa_assert(source_output_ss
.rate
== source_ss
.rate
);
1766 pa_assert(sink_ss
.rate
== source_ss
.rate
);
1768 u
->source_output_blocksize
= nframes
* pa_frame_size(&source_output_ss
);
1769 u
->source_blocksize
= nframes
* pa_frame_size(&source_ss
);
1770 u
->sink_blocksize
= nframes
* pa_frame_size(&sink_ss
);
1772 if (u
->ec
->params
.drift_compensation
)
1773 pa_assert(u
->ec
->set_drift
);
1776 pa_source_new_data_init(&source_data
);
1777 source_data
.driver
= __FILE__
;
1778 source_data
.module
= m
;
1779 if (!(source_data
.name
= pa_xstrdup(pa_modargs_get_value(ma
, "source_name", NULL
))))
1780 source_data
.name
= pa_sprintf_malloc("%s.echo-cancel", source_master
->name
);
1781 pa_source_new_data_set_sample_spec(&source_data
, &source_ss
);
1782 pa_source_new_data_set_channel_map(&source_data
, &source_map
);
1783 pa_proplist_sets(source_data
.proplist
, PA_PROP_DEVICE_MASTER_DEVICE
, source_master
->name
);
1784 pa_proplist_sets(source_data
.proplist
, PA_PROP_DEVICE_CLASS
, "filter");
1786 pa_proplist_sets(source_data
.proplist
, PA_PROP_DEVICE_INTENDED_ROLES
, "phone");
1788 if (pa_modargs_get_proplist(ma
, "source_properties", source_data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1789 pa_log("Invalid properties");
1790 pa_source_new_data_done(&source_data
);
1794 if ((u
->source_auto_desc
= !pa_proplist_contains(source_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
))) {
1797 y
= pa_proplist_gets(sink_master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1798 z
= pa_proplist_gets(source_master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1799 pa_proplist_setf(source_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, "%s (echo cancelled with %s)",
1800 z
? z
: source_master
->name
, y
? y
: sink_master
->name
);
1803 u
->source
= pa_source_new(m
->core
, &source_data
, (source_master
->flags
& (PA_SOURCE_LATENCY
| PA_SOURCE_DYNAMIC_LATENCY
))
1804 | (u
->use_volume_sharing
? PA_SOURCE_SHARE_VOLUME_WITH_MASTER
: 0));
1805 pa_source_new_data_done(&source_data
);
1808 pa_log("Failed to create source.");
1812 u
->source
->parent
.process_msg
= source_process_msg_cb
;
1813 u
->source
->set_state
= source_set_state_cb
;
1814 u
->source
->update_requested_latency
= source_update_requested_latency_cb
;
1815 pa_source_set_get_mute_callback(u
->source
, source_get_mute_cb
);
1816 pa_source_set_set_mute_callback(u
->source
, source_set_mute_cb
);
1817 if (!u
->use_volume_sharing
) {
1818 pa_source_set_get_volume_callback(u
->source
, source_get_volume_cb
);
1819 pa_source_set_set_volume_callback(u
->source
, source_set_volume_cb
);
1820 pa_source_enable_decibel_volume(u
->source
, TRUE
);
1822 u
->source
->userdata
= u
;
1824 pa_source_set_asyncmsgq(u
->source
, source_master
->asyncmsgq
);
1827 pa_sink_new_data_init(&sink_data
);
1828 sink_data
.driver
= __FILE__
;
1829 sink_data
.module
= m
;
1830 if (!(sink_data
.name
= pa_xstrdup(pa_modargs_get_value(ma
, "sink_name", NULL
))))
1831 sink_data
.name
= pa_sprintf_malloc("%s.echo-cancel", sink_master
->name
);
1832 pa_sink_new_data_set_sample_spec(&sink_data
, &sink_ss
);
1833 pa_sink_new_data_set_channel_map(&sink_data
, &sink_map
);
1834 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_MASTER_DEVICE
, sink_master
->name
);
1835 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_CLASS
, "filter");
1837 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_INTENDED_ROLES
, "phone");
1839 if (pa_modargs_get_proplist(ma
, "sink_properties", sink_data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1840 pa_log("Invalid properties");
1841 pa_sink_new_data_done(&sink_data
);
1845 if ((u
->sink_auto_desc
= !pa_proplist_contains(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
))) {
1848 y
= pa_proplist_gets(source_master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1849 z
= pa_proplist_gets(sink_master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
1850 pa_proplist_setf(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, "%s (echo cancelled with %s)",
1851 z
? z
: sink_master
->name
, y
? y
: source_master
->name
);
1854 u
->sink
= pa_sink_new(m
->core
, &sink_data
, (sink_master
->flags
& (PA_SINK_LATENCY
| PA_SINK_DYNAMIC_LATENCY
))
1855 | (u
->use_volume_sharing
? PA_SINK_SHARE_VOLUME_WITH_MASTER
: 0));
1856 pa_sink_new_data_done(&sink_data
);
1859 pa_log("Failed to create sink.");
1863 u
->sink
->parent
.process_msg
= sink_process_msg_cb
;
1864 u
->sink
->set_state
= sink_set_state_cb
;
1865 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
1866 u
->sink
->request_rewind
= sink_request_rewind_cb
;
1867 pa_sink_set_set_mute_callback(u
->sink
, sink_set_mute_cb
);
1868 if (!u
->use_volume_sharing
) {
1869 pa_sink_set_set_volume_callback(u
->sink
, sink_set_volume_cb
);
1870 pa_sink_enable_decibel_volume(u
->sink
, TRUE
);
1872 u
->sink
->userdata
= u
;
1874 pa_sink_set_asyncmsgq(u
->sink
, sink_master
->asyncmsgq
);
1876 /* Create source output */
1877 pa_source_output_new_data_init(&source_output_data
);
1878 source_output_data
.driver
= __FILE__
;
1879 source_output_data
.module
= m
;
1880 pa_source_output_new_data_set_source(&source_output_data
, source_master
, FALSE
);
1881 source_output_data
.destination_source
= u
->source
;
1883 pa_proplist_sets(source_output_data
.proplist
, PA_PROP_MEDIA_NAME
, "Echo-Cancel Source Stream");
1884 pa_proplist_sets(source_output_data
.proplist
, PA_PROP_MEDIA_ROLE
, "filter");
1885 pa_source_output_new_data_set_sample_spec(&source_output_data
, &source_output_ss
);
1886 pa_source_output_new_data_set_channel_map(&source_output_data
, &source_output_map
);
1888 pa_source_output_new(&u
->source_output
, m
->core
, &source_output_data
);
1889 pa_source_output_new_data_done(&source_output_data
);
1891 if (!u
->source_output
)
1894 u
->source_output
->parent
.process_msg
= source_output_process_msg_cb
;
1895 u
->source_output
->push
= source_output_push_cb
;
1896 u
->source_output
->process_rewind
= source_output_process_rewind_cb
;
1897 u
->source_output
->update_max_rewind
= source_output_update_max_rewind_cb
;
1898 u
->source_output
->update_source_requested_latency
= source_output_update_source_requested_latency_cb
;
1899 u
->source_output
->update_source_latency_range
= source_output_update_source_latency_range_cb
;
1900 u
->source_output
->update_source_fixed_latency
= source_output_update_source_fixed_latency_cb
;
1901 u
->source_output
->kill
= source_output_kill_cb
;
1902 u
->source_output
->attach
= source_output_attach_cb
;
1903 u
->source_output
->detach
= source_output_detach_cb
;
1904 u
->source_output
->state_change
= source_output_state_change_cb
;
1905 u
->source_output
->may_move_to
= source_output_may_move_to_cb
;
1906 u
->source_output
->moving
= source_output_moving_cb
;
1907 u
->source_output
->userdata
= u
;
1909 u
->source
->output_from_master
= u
->source_output
;
1911 /* Create sink input */
1912 pa_sink_input_new_data_init(&sink_input_data
);
1913 sink_input_data
.driver
= __FILE__
;
1914 sink_input_data
.module
= m
;
1915 pa_sink_input_new_data_set_sink(&sink_input_data
, sink_master
, FALSE
);
1916 sink_input_data
.origin_sink
= u
->sink
;
1917 pa_proplist_sets(sink_input_data
.proplist
, PA_PROP_MEDIA_NAME
, "Echo-Cancel Sink Stream");
1918 pa_proplist_sets(sink_input_data
.proplist
, PA_PROP_MEDIA_ROLE
, "filter");
1919 pa_sink_input_new_data_set_sample_spec(&sink_input_data
, &sink_ss
);
1920 pa_sink_input_new_data_set_channel_map(&sink_input_data
, &sink_map
);
1921 sink_input_data
.flags
= PA_SINK_INPUT_VARIABLE_RATE
;
1923 pa_sink_input_new(&u
->sink_input
, m
->core
, &sink_input_data
);
1924 pa_sink_input_new_data_done(&sink_input_data
);
1929 u
->sink_input
->parent
.process_msg
= sink_input_process_msg_cb
;
1930 u
->sink_input
->pop
= sink_input_pop_cb
;
1931 u
->sink_input
->process_rewind
= sink_input_process_rewind_cb
;
1932 u
->sink_input
->update_max_rewind
= sink_input_update_max_rewind_cb
;
1933 u
->sink_input
->update_max_request
= sink_input_update_max_request_cb
;
1934 u
->sink_input
->update_sink_requested_latency
= sink_input_update_sink_requested_latency_cb
;
1935 u
->sink_input
->update_sink_latency_range
= sink_input_update_sink_latency_range_cb
;
1936 u
->sink_input
->update_sink_fixed_latency
= sink_input_update_sink_fixed_latency_cb
;
1937 u
->sink_input
->kill
= sink_input_kill_cb
;
1938 u
->sink_input
->attach
= sink_input_attach_cb
;
1939 u
->sink_input
->detach
= sink_input_detach_cb
;
1940 u
->sink_input
->state_change
= sink_input_state_change_cb
;
1941 u
->sink_input
->may_move_to
= sink_input_may_move_to_cb
;
1942 u
->sink_input
->moving
= sink_input_moving_cb
;
1943 if (!u
->use_volume_sharing
)
1944 u
->sink_input
->volume_changed
= sink_input_volume_changed_cb
;
1945 u
->sink_input
->mute_changed
= sink_input_mute_changed_cb
;
1946 u
->sink_input
->userdata
= u
;
1948 u
->sink
->input_to_master
= u
->sink_input
;
1950 pa_sink_input_get_silence(u
->sink_input
, &silence
);
1952 u
->source_memblockq
= pa_memblockq_new("module-echo-cancel source_memblockq", 0, MEMBLOCKQ_MAXLENGTH
, 0,
1953 &source_output_ss
, 1, 1, 0, &silence
);
1954 u
->sink_memblockq
= pa_memblockq_new("module-echo-cancel sink_memblockq", 0, MEMBLOCKQ_MAXLENGTH
, 0,
1955 &sink_ss
, 0, 1, 0, &silence
);
1957 pa_memblock_unref(silence
.memblock
);
1959 if (!u
->source_memblockq
|| !u
->sink_memblockq
) {
1960 pa_log("Failed to create memblockq.");
1964 if (u
->adjust_time
> 0 && !u
->ec
->params
.drift_compensation
)
1965 u
->time_event
= pa_core_rttime_new(m
->core
, pa_rtclock_now() + u
->adjust_time
, time_callback
, u
);
1966 else if (u
->ec
->params
.drift_compensation
) {
1967 pa_log_info("Canceller does drift compensation -- built-in compensation will be disabled");
1969 /* Perform resync just once to give the canceller a leg up */
1970 pa_atomic_store(&u
->request_resync
, 1);
1974 pa_log("Creating AEC files in /tmp");
1975 u
->captured_file
= fopen("/tmp/aec_rec.sw", "wb");
1976 if (u
->captured_file
== NULL
)
1977 perror ("fopen failed");
1978 u
->played_file
= fopen("/tmp/aec_play.sw", "wb");
1979 if (u
->played_file
== NULL
)
1980 perror ("fopen failed");
1981 u
->canceled_file
= fopen("/tmp/aec_out.sw", "wb");
1982 if (u
->canceled_file
== NULL
)
1983 perror ("fopen failed");
1984 if (u
->ec
->params
.drift_compensation
) {
1985 u
->drift_file
= fopen("/tmp/aec_drift.txt", "w");
1986 if (u
->drift_file
== NULL
)
1987 perror ("fopen failed");
1991 u
->ec
->msg
= pa_msgobject_new(pa_echo_canceller_msg
);
1992 u
->ec
->msg
->parent
.process_msg
= canceller_process_msg_cb
;
1993 u
->ec
->msg
->userdata
= u
;
1995 u
->thread_info
.current_volume
= u
->source
->reference_volume
;
1997 pa_sink_put(u
->sink
);
1998 pa_source_put(u
->source
);
2000 pa_sink_input_put(u
->sink_input
);
2001 pa_source_output_put(u
->source_output
);
2002 pa_modargs_free(ma
);
2008 pa_modargs_free(ma
);
2015 /* Called from main context. */
2016 int pa__get_n_used(pa_module
*m
) {
2020 pa_assert_se(u
= m
->userdata
);
2022 return pa_sink_linked_by(u
->sink
) + pa_source_linked_by(u
->source
);
2025 /* Called from main context. */
2026 void pa__done(pa_module
*m
) {
2031 if (!(u
= m
->userdata
))
2036 /* See comments in source_output_kill_cb() above regarding
2037 * destruction order! */
2040 u
->core
->mainloop
->time_free(u
->time_event
);
2042 if (u
->source_output
)
2043 pa_source_output_unlink(u
->source_output
);
2045 pa_sink_input_unlink(u
->sink_input
);
2048 pa_source_unlink(u
->source
);
2050 pa_sink_unlink(u
->sink
);
2052 if (u
->source_output
)
2053 pa_source_output_unref(u
->source_output
);
2055 pa_sink_input_unref(u
->sink_input
);
2058 pa_source_unref(u
->source
);
2060 pa_sink_unref(u
->sink
);
2062 if (u
->source_memblockq
)
2063 pa_memblockq_free(u
->source_memblockq
);
2064 if (u
->sink_memblockq
)
2065 pa_memblockq_free(u
->sink_memblockq
);
2075 pa_asyncmsgq_unref(u
->asyncmsgq
);
2079 fclose(u
->played_file
);
2080 if (u
->captured_file
)
2081 fclose(u
->captured_file
);
2082 if (u
->canceled_file
)
2083 fclose(u
->canceled_file
);
2085 fclose(u
->drift_file
);
2091 #ifdef ECHO_CANCEL_TEST
2093 * Stand-alone test program for running in the canceller on pre-recorded files.
2095 int main(int argc
, char* argv
[]) {
2097 pa_sample_spec source_output_ss
, source_ss
, sink_ss
;
2098 pa_channel_map source_output_map
, source_map
, sink_map
;
2099 pa_modargs
*ma
= NULL
;
2100 uint8_t *rdata
= NULL
, *pdata
= NULL
, *cdata
= NULL
;
2101 int unused PA_GCC_UNUSED
;
2107 if (!getenv("MAKE_CHECK"))
2108 pa_log_set_level(PA_LOG_DEBUG
);
2110 pa_memzero(&u
, sizeof(u
));
2112 if (argc
< 4 || argc
> 7) {
2116 u
.captured_file
= fopen(argv
[2], "rb");
2117 if (u
.captured_file
== NULL
) {
2118 perror ("Could not open capture file");
2121 u
.played_file
= fopen(argv
[1], "rb");
2122 if (u
.played_file
== NULL
) {
2123 perror ("Could not open play file");
2126 u
.canceled_file
= fopen(argv
[3], "wb");
2127 if (u
.canceled_file
== NULL
) {
2128 perror ("Could not open canceled file");
2132 u
.core
= pa_xnew0(pa_core
, 1);
2133 u
.core
->cpu_info
.cpu_type
= PA_CPU_X86
;
2134 u
.core
->cpu_info
.flags
.x86
|= PA_CPU_X86_SSE
;
2136 if (!(ma
= pa_modargs_new(argc
> 4 ? argv
[4] : NULL
, valid_modargs
))) {
2137 pa_log("Failed to parse module arguments.");
2141 source_ss
.format
= PA_SAMPLE_S16LE
;
2142 source_ss
.rate
= DEFAULT_RATE
;
2143 source_ss
.channels
= DEFAULT_CHANNELS
;
2144 pa_channel_map_init_auto(&source_map
, source_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
);
2146 sink_ss
.format
= PA_SAMPLE_S16LE
;
2147 sink_ss
.rate
= DEFAULT_RATE
;
2148 sink_ss
.channels
= DEFAULT_CHANNELS
;
2149 pa_channel_map_init_auto(&sink_map
, sink_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
);
2151 if (init_common(ma
, &u
, &source_ss
, &source_map
) < 0)
2154 source_output_ss
= source_ss
;
2155 source_output_map
= source_map
;
2157 if (!u
.ec
->init(u
.core
, u
.ec
, &source_output_ss
, &source_output_map
, &sink_ss
, &sink_map
, &source_ss
, &source_map
, &nframes
,
2158 pa_modargs_get_value(ma
, "aec_args", NULL
))) {
2159 pa_log("Failed to init AEC engine");
2162 u
.source_output_blocksize
= nframes
* pa_frame_size(&source_output_ss
);
2163 u
.source_blocksize
= nframes
* pa_frame_size(&source_ss
);
2164 u
.sink_blocksize
= nframes
* pa_frame_size(&sink_ss
);
2166 if (u
.ec
->params
.drift_compensation
) {
2168 pa_log("Drift compensation enabled but drift file not specified");
2172 u
.drift_file
= fopen(argv
[5], "rt");
2174 if (u
.drift_file
== NULL
) {
2175 perror ("Could not open drift file");
2180 rdata
= pa_xmalloc(u
.source_output_blocksize
);
2181 pdata
= pa_xmalloc(u
.sink_blocksize
);
2182 cdata
= pa_xmalloc(u
.source_blocksize
);
2184 if (!u
.ec
->params
.drift_compensation
) {
2185 while (fread(rdata
, u
.source_output_blocksize
, 1, u
.captured_file
) > 0) {
2186 if (fread(pdata
, u
.sink_blocksize
, 1, u
.played_file
) == 0) {
2187 perror("Played file ended before captured file");
2191 u
.ec
->run(u
.ec
, rdata
, pdata
, cdata
);
2193 unused
= fwrite(cdata
, u
.source_blocksize
, 1, u
.canceled_file
);
2196 while (fscanf(u
.drift_file
, "%c", &c
) > 0) {
2199 if (!fscanf(u
.drift_file
, "%a", &drift
)) {
2200 perror("Drift file incomplete");
2204 u
.ec
->set_drift(u
.ec
, drift
);
2209 if (!fscanf(u
.drift_file
, "%d", &i
)) {
2210 perror("Drift file incomplete");
2214 if (fread(rdata
, i
, 1, u
.captured_file
) <= 0) {
2215 perror("Captured file ended prematurely");
2219 u
.ec
->record(u
.ec
, rdata
, cdata
);
2221 unused
= fwrite(cdata
, i
, 1, u
.canceled_file
);
2226 if (!fscanf(u
.drift_file
, "%d", &i
)) {
2227 perror("Drift file incomplete");
2231 if (fread(pdata
, i
, 1, u
.played_file
) <= 0) {
2232 perror("Played file ended prematurely");
2236 u
.ec
->play(u
.ec
, pdata
);
2242 if (fread(rdata
, i
, 1, u
.captured_file
) > 0)
2243 pa_log("All capture data was not consumed");
2244 if (fread(pdata
, i
, 1, u
.played_file
) > 0)
2245 pa_log("All playback data was not consumed");
2251 if (u
.captured_file
)
2252 fclose(u
.captured_file
);
2254 fclose(u
.played_file
);
2255 if (u
.canceled_file
)
2256 fclose(u
.canceled_file
);
2258 fclose(u
.drift_file
);
2268 pa_modargs_free(ma
);
2273 pa_log("Usage: %s play_file rec_file out_file [module args] [drift_file]", argv
[0]);
2279 #endif /* ECHO_CANCEL_TEST */