Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/mutap.aec~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<c74object name='mutap.aec~' category='audio, adaptive, echo, cleaning'>

<digest>Acoustic echo canceller</digest>
<description>Acoustic echo canceller. Subtracts an adaptive estimate of the loudspeaker-to-microphone echo path from the microphone signal — the open-loop cousin of mutap.afc~, for the case where a clean far-end reference exists. Adaptation runs on a PEM-prewhitened signal pair, so it survives double-talk without a double-talk detector (FDAF-PEM, MuTap pem_afc). Inlet 1 takes the microphone, inlet 2 the far-end signal feeding the loudspeaker; the cleaned output is delayed by @block samples. The right outlet reports the IPC double-talk indicator (0..1). @warp selects the frequency-warped near-end model for music/tonal sources; @kalman selects the frequency-domain Kalman engine (v2), the measured double-talk winner. @postfilter engages the full measured AEC chain — raw Kalman canceller, coherence-driven residual suppressor, comfort noise, initial receive guard — the configuration MuTap's ITU-T compliance battery certifies. </description>
<description>Acoustic echo canceller. Subtracts an adaptive estimate of the loudspeaker-to-microphone echo path from the microphone signal — the open-loop cousin of mutap.afc~, for the case where a clean far-end reference exists. Adaptation runs on a PEM-prewhitened signal pair, so it survives double-talk without a double-talk detector (FDAF-PEM, MuTap pem_afc). Inlet 1 takes the microphone, inlet 2 the far-end signal feeding the loudspeaker; the cleaned output is delayed by @block samples. The right outlet reports the IPC double-talk indicator (0..1). @warp selects the frequency-warped near-end model for music/tonal sources; @kalman selects the frequency-domain Kalman engine (v2), the measured double-talk winner. @postfilter selects the residual-echo post-filter engine: 1 engages the full measured AEC chain — raw Kalman canceller, coherence-driven residual suppressor, comfort noise, initial receive guard — the configuration MuTap's ITU-T compliance battery certifies; 2 swaps the suppressor for a small trained network (see @model). </description>


<!--METADATA-->
Expand Down Expand Up @@ -76,8 +76,12 @@
</attribute>

<attribute name='postfilter' get='1' set='1' type='long' size='1' >
<digest>The measured AEC chain: suppressor + comfort noise</digest>
<description>Residual-echo post-filter: off = the bare adaptive canceller selected by the attributes above, on = the measured AEC CHAIN — the raw frequency-domain Kalman canceller plus the coherence-driven residual suppressor, comfort noise matched to the near-end noise floor, and the initial receive guard. This is the configuration MuTap's ITU-T compliance battery certifies at 48 and 16 kHz (single-talk residual below -76 dBm0(A), double-talk near-end cost about 1 dB, full-duplex P.340 Category 1), with its time constants rescaled for the actual block size and sample rate. With postfilter on, mu, warp and kalman are ignored (the chain's canceller is already the Kalman core; PEM buys nothing open-loop) and gate selects the initial receive guard; the right outlet reports the suppressor's echo-explained fraction (0..1) instead of IPC. Adds one extra block of latency (the suppressor's constrained gain filter). Changing it rebuilds the canceller from scratch (the learned filter resets). </description>
<digest>Residual-echo post-filter engine (0 off, 1 classical, 2 learned)</digest>
<description>Residual-echo post-filter engine: 0 = the bare adaptive canceller selected by the attributes above, 1 = the measured AEC CHAIN — the raw frequency-domain Kalman canceller plus the coherence-driven residual suppressor, comfort noise matched to the near-end noise floor, and the initial receive guard. This is the configuration MuTap's ITU-T compliance battery certifies at 48 and 16 kHz (single-talk residual below -76 dBm0(A), double-talk near-end cost about 1 dB, full-duplex P.340 Category 1), with its time constants rescaled for the actual block size and sample rate. 2 = the LEARNED chain: the same canceller and guard with the post-filter replaced by a small trained network predicting per-band gains (see model) — measured stronger single-talk echo removal on speech-like material at equal near-end transparency, weaker double-talk suppression on material unlike its training data; the classical engine remains the certified default. The learned engine requires block to equal its model's trained block size (256 for the built-in model) and coerces it, with a console notice, if it does not. With postfilter nonzero, mu, warp and kalman are ignored (the chain's canceller is already the Kalman core; PEM buys nothing open-loop) and gate selects the initial receive guard; the right outlet reports the post-filter's echo-explained fraction (0..1) instead of IPC. Adds one extra block of latency (the suppressor's constrained gain filter). Changing it rebuilds the canceller from scratch (the learned filter resets). </description>
</attribute>
<attribute name='model' get='1' set='1' type='symbol' size='1' >
<digest>Learned-engine weights file (postfilter 2 only)</digest>
<description>Learned-engine weights (postfilter 2 only): a path to a trained MUNN model file (MuTap's tools/ml pipeline exports these), or empty for the package's built-in 48 kHz model. A model carries its own analysis geometry; block must equal its trained block size and is coerced, with a console notice, if it does not. A file that cannot be read or validated posts an error and leaves the running engine unchanged. Changing it rebuilds the canceller from scratch (the learned filter resets). </description>
</attribute>

<attribute name='comfort' get='1' set='1' type='long' size='1' >
Expand Down
40 changes: 35 additions & 5 deletions help/mutap.aec~.maxhelp
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,9 @@
20.0,
600.0,
760.0,
68.0
95.0
],
"text": "Try it: start the audio, raise the far-end fader \u2014 the noise 'echo' appears in the mic and the canceller learns it away within a second or two. Now TALK: that is double-talk, the hard part of echo cancellation. A naive filter would chase your voice and wreck its echo estimate; this one keeps adapting through it \u2014 the PEM near-end model whitens your voice out of the update, and @kalman 1 tracks it per frequency bin (the measured best, no detector, no tuning; see MuTap tests/test_aec.cpp). For the last 20-30 dB, @postfilter 1 engages the full ITU-certified chain: the residual the linear filter cannot reach is suppressed by coherence and replaced with comfort noise matched to the room, so the far end hears neither echo nor a breathing noise floor. Creation arg = echo-path length in samples (default 2048); partitions = filter length / block."
"text": "Try it: start the audio, raise the far-end fader \u2014 the noise 'echo' appears in the mic and the canceller learns it away within a second or two. Now TALK: that is double-talk, the hard part of echo cancellation. A naive filter would chase your voice and wreck its echo estimate; this one keeps adapting through it \u2014 the PEM near-end model whitens your voice out of the update, and @kalman 1 tracks it per frequency bin (the measured best, no detector, no tuning; see MuTap tests/test_aec.cpp). For the last 20-30 dB, @postfilter 1 engages the full ITU-certified chain: the residual the linear filter cannot reach is suppressed by coherence and replaced with comfort noise matched to the room, so the far end hears neither echo nor a breathing noise floor. @postfilter 2 swaps that suppressor for a small trained network (stronger single-talk echo removal on speech at equal transparency; the classical engine stays the certified default) \u2014 @model loads your own trained weights, and @block follows the model's trained block size. Creation arg = echo-path length in samples (default 2048); partitions = filter length / block."
}
},
{
Expand Down Expand Up @@ -688,10 +688,10 @@
"patching_rect": [
656.0,
426.0,
360.0,
20.0
380.0,
33.0
],
"text": "the measured ITU-certified chain (default off; rebuilds; +1 block latency)"
"text": "post-filter engine: 0 off, 1 the ITU-certified chain, 2 the learned (neural) chain (rebuilds; +1 block latency)"
}
},
{
Expand Down Expand Up @@ -744,6 +744,24 @@
],
"text": "comfort-noise fill at the room's noise floor (postfilter only; default on)"
}
},
{
"box": {
"id": "obj-90",
"maxclass": "message",
"numinlets": 2,
"numoutlets": 1,
"outlettype": [
""
],
"patching_rect": [
550.0,
450.0,
82.0,
22.0
],
"text": "postfilter 2"
}
}
],
"lines": [
Expand Down Expand Up @@ -1094,6 +1112,18 @@
0
]
}
},
{
"patchline": {
"destination": [
"obj-12",
0
],
"source": [
"obj-90",
0
]
}
}
]
}
Expand Down
Loading
Loading