The echo canceller module can pass arguments to the EC implementation
via the module parameter aec_args. However, the echo-cancel-test passes
EC arguments via a separate argv[] option, which is inconsistent. Fix
this.
computes EC block size in frames (rounded down to nearest power-of-2) based
on sample rate and milliseconds
move code from speex AEC implementation to module-echo-cancel such that
functionality can be reused by other AEC implementations
Signed-off-by: Peter Meerwald <p.meerwald@bct-electronic.com>
In order to support different blocksizes for source and sink (e.g, for
4-to-1 beamforming/echo canceling which involves 4 record channels and 1
playback channel) the AEC API is altered:
The blocksize for source and sink may differ (due to different sample
specs) but the number of frames that are processed in one invokation of
the AEC implementation's run() function is the same for the playback and
the record stream. Consequently, the AEC implementation's init()
function initalizes 'nframes' instead of 'blocksize' and the source's
and sink's blocksizes are derived from 'nframes'. The old API also
caused code duplication in each AEC implementation's init function for
the compution of the blocksize, which is eliminated by the new API.
Signed-off-by: Stefan Huber <s.huber@bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
In case that source and sink use different sample specs (e.g., different
number of channels) the computation of the latency difference fails.
To fix this, we obtain the corresponding latencies in terms of time using
the respective sample specs instead of buffer sizes.
Signed-off-by: Stefan Huber <s.huber@bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
In main() of echo-cancel-test it is wrongly assumed that the EC
implementation's init() function properly initializes sink_ss. In
contrast, pa__init() sets sink_ss by default to
sink_master->sample_spec. Fix this by setting sink_ss to default
parameters and let EC implementation's init() override these settings.
Signed-off-by: Stefan Huber <s.huber@bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
Argument argv[5] is accessed when argc>4, which leads to an invalid
access for argc==5. Fix this.
Signed-off-by: Stefan Huber <s.huber@bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
apply_diff_time() fails when dropping bytes from the playback stream
and the sample spec of sink and source differ as source's sample spec is
used. Fix this by using sink's sample spec.
Signed-off-by: Stefan Huber <s.huber@bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
makes the Adrian echo canceller implementation optional at compile time
this patch supersedes an earlier patch proposal and addresses the following
comments:
* separate patch from speex dependency rework (Arun)
* check that at least one EC implementation is available (Arun)
* properly align yes/no in configure summary for Adrian (Frederic)
make speex library dependency optional, this affects the resampler
and the echo canceller module
this patch supersedes an earlier patch proposal and addresses the following
comments:
* fix order of pa_echo_canceller_method_t enum and ec_table (Frederic)
* the default resampler is speex if available as before, otherwise ffmpeg (Arun)
* does not touch the Adrian EC implementation (see separate patch) (Arun)
When autoloaded, it is expected that module-filter-apply (or whatever is
loading us) will take care of applying the filter on the correct
sink/source master. Instead of adding complexity by tracking what is
currently being filtered, we just disallow filtering anything except the
original master sink/source and let module-filter-apply or whatever is
loading us deal with dynamic sink/source changes.
This makes what devices are being cancelled clearer in the UI (at the
cost of being somewhat less clear when multiple devices of the same name
are plugged, but at least that's a much smaller set than everyone).
This adds some infrastructure for canceller implementations to also
perform acoustic gain control. Cancellers now have a couple of new API
calls that allow them to get/set capture volume.
This is made slightly complex by the fact that cancellation happens in
thread context while most volume mangling needs to be done in main
context. To deal with this, while getting the volume we save source
volume updates as they are propagated to thread context and use this
cached value for queries. To set the volume, we send an async message to
main context and let that set the source volume.
This dumps out an additional file with each line having a command of the
form:
p <number of playback samples processed>
c <number of capture samples processed>
d <drift as passed to set_drift()>
The test program can be provided this file to "replay" the data exactly
as when it was run live.
The non-drift-compensation path is retained as-is since it is much
simpler.
This adds the ability for echo cancellers to provide their own drift
compensation, and hooks in the appropriate bits to implement this in the
WebRTC canceller.
We do this by introducing an alternative model for the canceller. So
far, the core engine just provided a run() method which was given
blocksize-sized chunks of playback and record samples. The new model has
the engine provide play() and record() methods that can (in theory) be
called by the playback and capture threads. The latter would actually do
the processing required.
In addition to this a set_drift() method may be provided by the
implementation. PA will provide periodic samples of the drift to the
engine. These values need to be aggregated and processed over some time,
since the point values vary quite a bit (but generally fit a linear
regression reasonably accurately). At some point of time, we might move
the actual drift calculation into PA and change the semantics of this
function.
NOTE: This needs further testing before being deemed ready for wider use.
This adds the WebRTC echo canceller as another module-echo-cancel
backend. We're exposing both the full echo canceller as well as the
mobile echo control version as modargs.
Pending items:
1. The mobile canceller doesn't seem to work at the moment.
2. We still need to add bits to hook in drift compensation (to support
sink and source from different devices).
The most controversial part of this patch would probably be the
mandatory build-time dependency on a C++ compiler. If the optional
--enable-webrtc-aec is set, then there's also a dependency on libstdc++.
This makes sure that we only perform any processing (resync or actual
cancellation) after the source provides enough data to actuall run the
canceller.
When a source-output isn't connected to our virtual source, we skip echo
cancellation altogether. This makes sense in general, and makes sure
that we don't end up adjusting for delay/drift when nothing is
connected. This should make convergence faster when the canceller
actually starts being used.
This increase the threshold for difference between the playback and
capture stream before samples are dropped from 1ms to 5ms (the
cancellers are generally robust to this much and higher). Also, we make
this a module parameter to allow easier experimentation with different
values.
Loading between a sink and its monitor causes a deadlock (while sending
messages for latency snapshots). It isn't a case that has any real
conceivable use, so let's just disallow it.
These are not used for anything at this point, but this
makes it easy to add ad-hoc debug prints that show the
memblockq name and to convert between bytes and usecs.
Uses the shared volume infrastructure by default with an option to
fallback on the old pretend-volume-sharing-that-kind-of-works if someone
wants it that way.
Users who keep left != right (or any sort of unbalanced channel volumes)
will likely want to disable shared volumes since it will cause their
master sink/source volume to be balanced.
This really isn't a very pleasant scenario since users would need to
manually set up echo cancellation in their config for this (until we
have a way to store module configuration). That said, the majority case
benefits from the volume sharing, so let's not wait for the
configuration infrastructure to be ready to use this.
When unloading, some module may end up trin to move a sink-input or
source-output back onto our virtual sink/source, causing an infinite
loop of us moving the stream away and having it moved back.
We prevent this from happening by preventing any stream from being
attached during unload.