[asterisk-dev] [RFC] Modularising echo cancellers
Nic Bellamy
nic.bellamy at vadacom.co.nz
Tue Jun 27 20:40:02 MST 2006
Hi all,
I've developed a patch to Zaptel that modularises the software echo
cancelers, allowing multiple ones to be loaded simultaneously.
In conjunction with this, I've developed a patch to Asterisk's chan_zap
that allows setting which echo canceler to use on a per-channel basis
(an "echocanceltype" parameter).
We have found this invaluable for evaluating different software
cancelers in varying situations, and we're using in production at a
number of sites on both E1 PRI and TDM400 analogue lines. It has allowed
me to do fun things like modularising the MG2 changes from trunk,
loading the module on a production system, and starting the use the new
canceler after just issuing a "reload".
The patch is currently for Zaptel 1.2.x, and I'm looking for comments as
to whether there's sufficient interest in it for me to forward-port it
to trunk, and submit it for inclusion.
The basic API looks like this:
/* Register an echo canceler with Zaptel */
int zt_register_echocan(struct zt_echo_can *ec);
/* Unregister an echo canceler */
int zt_unregister_echocan(struct zt_echo_can *ec);
/* Find the canceler structure called "name". Handles locking and module
use counts. */
struct zt_echo_can *zt_echo_can_get(char *name);
/* Return an instance of an echo canceler back to Zaptel, handling
locking and module use counts */
void zt_echo_can_put(struct zt_echo_can *ec);
struct zt_echo_can {
/* Module-visible bits */
char name[ZT_ECHO_CAN_NAMELEN];
struct module *owner;
zt_echo_can_state_t *(*create)(int taps);
void (*free)(zt_echo_can_state_t *ec);
short (*update)(zt_echo_can_state_t *ec, short tx, short rx);
/* update_block: run the echo canceler over a block of data.
*
* It must deal with the possibility of rx == out.
*/
void (*update_block)(zt_echo_can_state_t *ec,
short *tx, short *rx, short *out, size_t len);
int (*traintap)(zt_echo_can_state_t *ec, int pos, short val);
/* Bits for Zaptel only */
struct list_head list;
};
The userspace-kernelspace interface required changes to allow sending a
canceler name, rather than just on/off requests, so I added a new IOCTL
interface:
#define ZT_ECHO_CAN_NAMELEN (16)
typedef struct zt_echocancelv2
{
char name[ZT_ECHO_CAN_NAMELEN];
int taps;
} ZT_ECHOCANCELV2_DATA;
/* Enable or disable echo cancellation on a channel (new version)
* The number is zero to disable echo cancellation and non-zero
* to enable echo cancellation. If the number is between 32
* and 256, it will also set the number of taps in the echo canceler
*/
#define ZT_ECHOCANCELV2 _IOW (ZT_CODE, 93, struct zt_echocancelv2)
The patch to chan_zap tries the V2 interface, then falls back to the
original if it doesn't work - on the assumption that in general, the
wrong canceler is better than no canceler.
One of the things I'd like to do going forward is to add a way of
sending options from userspace up to the canceler to add runtime control
of things like nonlinear processing, suppression, comfort noise
generation, convergence speed, etc. (admittedly, most cancelers don't
even have these knobs - yet). At this point it's only possible to
specify the tail length.
Your thoughts?
If anyone wants to try out the full patch, send me an email offlist -
I'll have to separate it out from my other fiddling, which I haven't
done as yet. Oh, and it's only tested on Linux 2.6.x; I doubt it'll even
compile on 2.4 without changes.
Regards,
Nic.
--
Nic Bellamy - <nic.bellamy at vadacom.co.nz>
Head Of Engineering, Vadacom Ltd - http://www.vadacom.co.nz/
Ph. +64-9-974-2790 - DDI +64-9-974-2639 - Mob. +64-21-251-8954
More information about the asterisk-dev
mailing list