Ah, I've got it! Merely loading the echo cancellation plugin isn't enough; you then need to start using it. In particular, it will only cancel echos of sounds passed into it, and if no sounds go through it, nothing will be cancelled. So, open /etc/pulse/default.pa
and add the line
load-module module-echo-cancel
towards the bottom (I put it right after the line that loads module-filter-apply
). Then, restart the PulseAudio daemon by running (as a non-root user) pulseaudio -k
. Next, run pacmd
to get a command line interface to PulseAudio, and give it the commands list-sources
and list-sinks
. Note the indices of the echo canceller in the responses. Edit /etc/pulse/default.pa
again, and uncomment the two lines at the end about set-default
, replacing the words input
and output
with the indices of the echo canceller's source and sink. Finally, restart PulseAudio again with pulseaudio -k
(again, run as a non-root user).
Now, by default all sounds to be output get sent through the echo canceller before heading to the speakers, and all sounds to be input get pulled from the echo canceller after coming in through the microphone, and things actually work. You can verify that it's working by running pavucontrol
and looking at the sound levels on the Input Devices screen (try playing some music and speaking, and note that the echo cancelled input shows normal sound levels when you speak but very low levels (verging on nothing) when you're silent but the music is playing).
This answer mostly comes from this post, which I wish I'd found weeks ago.