diff options
author | Shaun Ruffell <sruffell@digium.com> | 2009-04-29 18:24:04 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2009-04-29 18:24:04 +0000 |
commit | 5f94a3b91de2c3835d6852d59cab9f6876177156 (patch) | |
tree | 4c25956b6ecdcd5b902ac80b40237bc3e938be44 /drivers/dahdi/dahdi_echocan_oslec.c | |
parent | 4a192a3e8f16ed6143377b5726e1fb53b446f5e9 (diff) |
echocan: Improve interface for echo cancelers.
Echo cancelers are now able to report if they are able to automatically disable
their NLP portions in the presence of tones in the audio stream. Also, the
interface is changed to allow user space to just disable the NLP portion of the
echo canceler. These changes improve fax and modem handling in DAHDI.
This commit merges in the changes on
http://svn.digium.com/svn/dahdi/linux/team/kpfleming/echocan_work
Patch by: kpfleming
Also contains improvements to CED tone detection.
(closes issue #13286)
Reported by: viniciusfontes
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6529 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi_echocan_oslec.c')
-rw-r--r-- | drivers/dahdi/dahdi_echocan_oslec.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/drivers/dahdi/dahdi_echocan_oslec.c b/drivers/dahdi/dahdi_echocan_oslec.c index 4d1c53f..a8d38b9 100644 --- a/drivers/dahdi/dahdi_echocan_oslec.c +++ b/drivers/dahdi/dahdi_echocan_oslec.c @@ -32,73 +32,107 @@ /* Fix this if OSLEC is elsewhere */ #include "../staging/echo/oslec.h" //#include <linux/oslec.h> -/* "provide" struct echo_can_state */ -//#define oslec_state echo_can_state #include <dahdi/kernel.h> #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) -static void echo_can_free(struct echo_can_state *ec) +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); + +static const struct dahdi_echocan_factory my_factory = { + .name = "OSLEC", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "OSLEC", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, +}; + +struct ec_pvt { + struct oslec_state *oslec; + struct dahdi_echocan_state dahdi; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) { - oslec_free((struct oslec_state *)ec); + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + oslec_free(pvt->oslec); + kfree(pvt); } -static void echo_can_update(struct echo_can_state *ec, short *isig, short *iref) +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) { - unsigned int SampleNum; + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 SampleNum; - for (SampleNum = 0; SampleNum < DAHDI_CHUNKSIZE; SampleNum++, iref++) - { + for (SampleNum = 0; SampleNum < size; SampleNum++, iref++) { short iCleanSample; - iCleanSample = (short) oslec_update((struct oslec_state *)ec, *iref, *isig); + + iCleanSample = oslec_update(pvt->oslec, *iref, *isig); *isig++ = iCleanSample; } } -static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p, - struct echo_can_state **ec) +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) { + struct ec_pvt *pvt; + if (ecp->param_count > 0) { printk(KERN_WARNING "OSLEC does not support parameters; failing request\n"); return -EINVAL; } - *ec = (struct echo_can_state *)oslec_create(ecp->tap_length, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CLIP | ECHO_CAN_USE_TX_HPF | ECHO_CAN_USE_RX_HPF); + pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + pvt->oslec = oslec_create(ecp->tap_length, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CLIP | ECHO_CAN_USE_TX_HPF | ECHO_CAN_USE_RX_HPF); - return *ec ? 0 : -ENOTTY; + if (!pvt->oslec) { + kfree(pvt); + *ec = NULL; + return -ENOTTY; + } else { + *ec = &pvt->dahdi; + return 0; + } } -static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val) +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) { return 1; } -static const struct dahdi_echocan me = { - .name = "OSLEC", - .owner = THIS_MODULE, - .echo_can_create = echo_can_create, - .echo_can_free = echo_can_free, - .echo_can_array_update = echo_can_update, - .echo_can_traintap = echo_can_traintap, -}; - static int __init mod_init(void) { - if (dahdi_register_echocan(&me)) { + if (dahdi_register_echocan_factory(&my_factory)) { module_printk(KERN_ERR, "could not register with DAHDI core\n"); return -EPERM; } - module_printk(KERN_INFO, "Registered echo canceler '%s'\n", me.name); + module_printk(KERN_INFO, "Registered echo canceler '%s'\n", my_factory.name); return 0; } static void __exit mod_exit(void) { - dahdi_unregister_echocan(&me); + dahdi_unregister_echocan_factory(&my_factory); } MODULE_DESCRIPTION("DAHDI OSLEC wrapper"); |