--- oslec.h | 28 +++++++ zaptel-base.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ zconfig.h | 3 3 files changed, 236 insertions(+), 1 deletion(-) Index: zaptel-1.4.7.1/oslec.h =================================================================== --- /dev/null +++ zaptel-1.4.7.1/oslec.h @@ -0,0 +1,28 @@ +/* + oslec.h + David Rowe + 7 Feb 2007 + + Interface for OSLEC module. +*/ + +#ifndef __OSLEC__ + +struct echo_can_state { + void *ec; +}; + +struct echo_can_state *oslec_echo_can_create(int len, int adaption_mode); +void oslec_echo_can_free(struct echo_can_state *ec); +short oslec_echo_can_update(struct echo_can_state *ec, short iref, short isig); +int oslec_echo_can_traintap(struct echo_can_state *ec, int pos, short val); +static inline void echo_can_init(void) {} +static inline void echo_can_shutdown(void) {} +short oslec_hpf_tx(struct echo_can_state *ec, short txlin); +static inline void echo_can_identify(char *buf, size_t len) +{ + strncpy(buf, "OSLEC", len); +} + +#endif + Index: zaptel-1.4.7.1/zaptel-base.c =================================================================== --- zaptel-1.4.7.1.orig/zaptel-base.c +++ zaptel-1.4.7.1/zaptel-base.c @@ -422,6 +422,14 @@ static struct zt_zone *tone_zones[ZT_TON #include "mg2ec.h" #elif defined(ECHO_CAN_JP1) #include "jpah.h" +/* Start Open Source Line Echo Canceller (OSLEC) -----------------*/ +#elif defined(ECHO_CAN_OSLEC) +#include "oslec.h" +#define echo_can_create oslec_echo_can_create +#define echo_can_free oslec_echo_can_free +#define echo_can_update oslec_echo_can_update +#define echo_can_traintap oslec_echo_can_traintap +/* End Open Source Line Echo Canceller (OSLEC) -------------------*/ #else #include "mec3.h" #endif @@ -5768,6 +5776,71 @@ void zt_rbsbits(struct zt_chan *chan, in spin_unlock_irqrestore(&chan->lock, flags); } +/* Zaptap code -----------------------------------------------------------*/ + +#define SAMPLE_BUF_SZ 1000 +#define SAMPLE_IDLE 0 +#define SAMPLE_PING 1 +#define SAMPLE_PONG 2 + +DECLARE_WAIT_QUEUE_HEAD(sample_wait); +static int sample_state = 0; +static int samples = 0; +static short *psample; +static short ping[3*SAMPLE_BUF_SZ]; +static short pong[3*SAMPLE_BUF_SZ]; +static int sample_ch = 1; +static int sample_impulse = 0; +static int tmp1,tmp2; + +static inline void sample_echo_before(int channo, short rxlin, short txlin) { + + // Sample echo canceller signals + // Notes: + // 1. Samples are multiplexed in buffer: + // tx sample + // rx sample + // ec sample + // 2. We needs to sample rx here before echo can as it is + // overwritten. + + tmp1++; + tmp2 = channo; + if ((sample_state != SAMPLE_IDLE) && (channo == sample_ch)) { + *psample++ = txlin; + *psample++ = rxlin; + } +} + +static inline void sample_echo_after(int channo, short rxlin) { + + if ((sample_state != SAMPLE_IDLE) && (channo == sample_ch)) { + + *psample++ = rxlin; + + // sample collection ping-pong buffer logic + + samples++; + if (samples >= SAMPLE_BUF_SZ) { + // time to swap buffers + samples = 0; + + if (sample_state == SAMPLE_PING) { + sample_state = SAMPLE_PONG; + psample = pong; + } + else { + sample_state = SAMPLE_PING; + psample = ping; + } + wake_up_interruptible(&sample_wait); + } + } +} + +/* end Zaptap code -----------------------------------------------------*/ + + static inline void __zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk) { short rxlin, txlin; @@ -5818,7 +5891,9 @@ static inline void __zt_ec_chunk(struct #if !defined(ZT_EC_ARRAY_UPDATE) for (x=0;xchanno, rxlin, ZT_XLAW(txchunk[x], ss)); /* Zaptap code */ rxlin = echo_can_update(ss->ec, ZT_XLAW(txchunk[x], ss), rxlin); + sample_echo_after(ss->channo, rxlin); /* Zaptap code */ rxchunk[x] = ZT_LIN2X((int) rxlin, ss); } #else /* defined(ZT_EC_ARRAY_UPDATE) */ @@ -6696,6 +6771,8 @@ static unsigned int zt_poll(struct file static void __zt_transmit_chunk(struct zt_chan *chan, unsigned char *buf) { unsigned char silly[ZT_CHUNKSIZE]; + int x; + /* Called with chan->lock locked */ if (!buf) buf = silly; @@ -6710,8 +6787,122 @@ static void __zt_transmit_chunk(struct z kernel_fpu_end(); #endif } + /* Start Zaptap code -----------------------------------------*/ + + if (sample_impulse && (samples == 0)) { + + // option impulse insertion, tx stream becomes one + // impulse followed by SAMPLE_BUF_SZ-1 0's + + buf[0] = ZT_LIN2MU(10000); + for (x=1;xlock held */ @@ -7195,12 +7386,27 @@ static int __init zt_init(void) { #ifdef CONFIG_ZAPTEL_WATCHDOG watchdog_init(); #endif + + /* start Zaptap code ----------------------------------------*/ + + sample_state = SAMPLE_IDLE; + sample_impulse = 0; + if ((res = register_chrdev (SAMPLE_MAJOR, SAMPLE_NAME, &sample_fops))) { + printk(KERN_ERR "Zaptap unable to register 'sample' char driver on %d\n", SAMPLE_MAJOR); + return res; + } + printk("Zaptap registered 'sample' char driver on major %d\n", SAMPLE_MAJOR); + + /* end Zaptap code ------------------------------------------*/ + return res; } static void __exit zt_cleanup(void) { int x; + unregister_chrdev (SAMPLE_MAJOR, SAMPLE_NAME); /* Zaptap code */ + #ifdef CONFIG_PROC_FS remove_proc_entry("zaptel", NULL); #endif Index: zaptel-1.4.7.1/zconfig.h =================================================================== --- zaptel-1.4.7.1.orig/zconfig.h +++ zaptel-1.4.7.1/zconfig.h @@ -66,7 +66,8 @@ /* #define ECHO_CAN_MARK3 */ /* #define ECHO_CAN_KB1 */ /* This is the new latest and greatest */ -#define ECHO_CAN_MG2 +/* #define ECHO_CAN_MG2 */ +#define ECHO_CAN_OSLEC /* * This is only technically an "echo canceller"...