[Asterisk-cvs] zaptel mec2.h,1.1.1.1,1.2 zaptel.c,1.31,1.32 zaptel.h,1.13,1.14
markster at lists.digium.com
markster at lists.digium.com
Mon Oct 27 10:33:57 CST 2003
Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv5761
Modified Files:
mec2.h zaptel.c zaptel.h
Log Message:
Create echo "Pretraining" ioctl
Index: mec2.h
===================================================================
RCS file: /usr/cvsroot/zaptel/mec2.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- mec2.h 12 Feb 2003 13:59:20 -0000 1.1.1.1
+++ mec2.h 27 Oct 2003 17:00:04 -0000 1.2
@@ -391,6 +391,18 @@
return ec;
}
-
+static inline int echo_can_traintap(echo_can_state_t *ec, int pos, short val)
+{
+ /* Reset hang counter to avoid adjustments after
+ initial forced training */
+ ec->HCNTR_d = ec->N_d << 1;
+ if (pos >= ec->N_d)
+ return 1;
+ ec->a_i[pos] = val << 17;
+ ec->a_s[pos] = val << 1;
+ if (++pos >= ec->N_d)
+ return 1;
+ return 0;
+}
#endif
Index: zaptel.c
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- zaptel.c 24 Oct 2003 19:51:33 -0000 1.31
+++ zaptel.c 27 Oct 2003 17:00:04 -0000 1.32
@@ -52,6 +52,14 @@
#include <linux/if_ppp.h>
#endif
+#define __ECHO_STATE_MUTE (1 << 8)
+#define ECHO_STATE_IDLE (0)
+#define ECHO_STATE_PRETRAINING (1 | (__ECHO_STATE_MUTE))
+#define ECHO_STATE_STARTTRAINING (2 | (__ECHO_STATE_MUTE))
+#define ECHO_STATE_AWAITINGECHO (3 | (__ECHO_STATE_MUTE))
+#define ECHO_STATE_TRAINING (4 | (__ECHO_STATE_MUTE))
+#define ECHO_STATE_ACTIVE (5)
+
/* #define BUF_MUNGE */
/* Grab fasthdlc with tables */
@@ -1791,6 +1799,9 @@
ec = chan->ec;
chan->ec = NULL;
chan->echocancel = 0;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
chan->txdisable = 0;
chan->rxdisable = 0;
@@ -2613,6 +2624,8 @@
mychan.confna, mychan._confn, mychan.confmode, mychan.confmute);
printk("ec: %08x, echocancel: %d, deflaw: %d, xlaw: %08x\n",
(int) mychan.ec, mychan.echocancel, mychan.deflaw, (int) mychan.xlaw);
+ printk("echostate: %02x, echotimer: %d, echolastupdate: %d\n",
+ (int) mychan.echostate, mychan.echotimer, mychan.echolastupdate);
printk("itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
mychan.itimer,mychan.otimer,mychan.ringdebtimer);
#if 0
@@ -3551,6 +3564,9 @@
tec = chan->ec;
chan->ec = NULL;
chan->echocancel = 0;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
/* Make sure there's no gain */
if (chan->gainalloc)
kfree(chan->rxgain);
@@ -3621,6 +3637,9 @@
tec = chan->ec;
chan->echocancel = j;
chan->ec = ec;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
echo_can_disable_detector_init(&chan->txecdis);
echo_can_disable_detector_init(&chan->rxecdis);
spin_unlock_irqrestore(&chan->lock, flags);
@@ -3631,11 +3650,26 @@
tec = chan->ec;
chan->echocancel = 0;
chan->ec = NULL;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
spin_unlock_irqrestore(&chan->lock, flags);
if (tec)
echo_can_free(tec);
}
break;
+ case ZT_ECHOTRAIN:
+ get_user(j, (int *)data); /* get pre-training time from user */
+ if ((j < 0) || (j >= ZT_MAX_PRETRAINING))
+ return -EINVAL;
+ j <<= 3;
+ if (chan->ec) {
+ /* Start pretraining stage */
+ chan->echostate = ECHO_STATE_PRETRAINING;
+ chan->echotimer = j;
+ } else
+ return -EINVAL;
+ break;
case ZT_SETTXBITS:
if (chan->sig != ZT_SIG_CAS)
return -EINVAL;
@@ -4112,6 +4146,9 @@
if (echo_can_disable_detector_update(&ms->txecdis, getlin[x])) {
printk("zaptel Disabled echo canceller because of tone (tx) on channel %d\n", ss->channo);
ms->echocancel = 0;
+ ms->echostate = ECHO_STATE_IDLE;
+ ms->echolastupdate = 0;
+ ms->echotimer = 0;
kfree(ms->ec);
ms->ec = NULL;
break;
@@ -4244,9 +4281,14 @@
break;
}
}
- if (ms->confmute) {
+ if (ms->confmute || (ms->echostate & __ECHO_STATE_MUTE)) {
txb[0] = ZT_LIN2X(0, ms);
memset(txb + 1, txb[0], ZT_CHUNKSIZE - 1);
+ if (ms->echostate == ECHO_STATE_STARTTRAINING) {
+ /* Transmit impulse now */
+ txb[0] = ZT_LIN2X(16384, ms);
+ ms->echostate = ECHO_STATE_AWAITINGECHO;
+ }
}
/* save value from last chunk */
memcpy(ms->getlin_lastchunk, ms->getlin, ZT_CHUNKSIZE * sizeof(short));
@@ -4405,7 +4447,7 @@
memset(txb, ZT_LIN2X(0, ms), bytes); /* Lastly we use silence on telephony channels */
bytes = 0;
}
- }
+ }
}
static inline void rbs_itimer_expire(struct zt_chan *chan)
@@ -4705,7 +4747,7 @@
void zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
{
- short rxlin;
+ short rxlin, txlin;
int x;
long flags;
spin_lock_irqsave(&ss->lock, flags);
@@ -4714,10 +4756,38 @@
#if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
zt_kernel_fpu_begin();
#endif
- for (x=0;x<ZT_CHUNKSIZE;x++) {
- rxlin = ZT_XLAW(rxchunk[x], ss);
- rxlin = echo_can_update(ss->ec, ZT_XLAW(txchunk[x], ss), rxlin);
- rxchunk[x] = ZT_LIN2X((int)rxlin, ss);
+ if (ss->echostate & __ECHO_STATE_MUTE) {
+ /* Special stuff for training the echo can */
+ for (x=0;x<ZT_CHUNKSIZE;x++) {
+ rxlin = ZT_XLAW(rxchunk[x], ss);
+ txlin = ZT_XLAW(txchunk[x], ss);
+ if (ss->echostate == ECHO_STATE_PRETRAINING) {
+ if (--ss->echotimer <= 0) {
+ ss->echotimer = 0;
+ ss->echostate = ECHO_STATE_STARTTRAINING;
+ }
+ }
+ if ((ss->echostate == ECHO_STATE_AWAITINGECHO) && (txlin > 8000)) {
+ ss->echolastupdate = 0;
+ ss->echostate = ECHO_STATE_TRAINING;
+ }
+ if (ss->echostate == ECHO_STATE_TRAINING) {
+ if (echo_can_traintap(ss->ec, ss->echolastupdate++, rxlin)) {
+#if 0
+ printk("Finished training (%d taps trained)!\n", ss->echolastupdate);
+#endif
+ ss->echostate = ECHO_STATE_ACTIVE;
+ }
+ }
+ rxlin = 0;
+ rxchunk[x] = ZT_LIN2X((int)rxlin, ss);
+ }
+ } else {
+ for (x=0;x<ZT_CHUNKSIZE;x++) {
+ rxlin = ZT_XLAW(rxchunk[x], ss);
+ rxlin = echo_can_update(ss->ec, ZT_XLAW(txchunk[x], ss), rxlin);
+ rxchunk[x] = ZT_LIN2X((int)rxlin, ss);
+ }
}
#if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
kernel_fpu_end();
@@ -4801,6 +4871,9 @@
if (echo_can_disable_detector_update(&ms->rxecdis, putlin[x])) {
printk("zaptel Disabled echo canceller because of tone (rx) on channel %d\n", ss->channo);
ms->echocancel = 0;
+ ms->echostate = ECHO_STATE_IDLE;
+ ms->echolastupdate = 0;
+ ms->echotimer = 0;
kfree(ms->ec);
ms->ec = NULL;
break;
Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- zaptel.h 24 Oct 2003 19:51:33 -0000 1.13
+++ zaptel.h 27 Oct 2003 17:00:04 -0000 1.14
@@ -539,11 +539,21 @@
#define ZT_TIMERACK _IOW (ZT_CODE, 48, int)
/*
- * Set Conference to mute mode
+ * Get Conference to mute mode
*/
#define ZT_GETCONFMUTE _IOR (ZT_CODE, 49, int)
/*
+ * Request echo training in some number of ms (with muting in the mean time)
+ */
+#define ZT_ECHOTRAIN _IOW (ZT_CODE, 50, int)
+
+/*
+ * Set on hook transfer for n number of ms -- implemnted by low level driver
+ */
+#define ZT_ONHOOKTRANSFER _IOW (ZT_CODE, 51, int)
+
+/*
* 60-80 are reserved for private drivers
* 80-85 are reserved for dynamic span stuff
*/
@@ -805,6 +815,8 @@
#define ZT_KEWLTIME 500 /* 500ms for kewl pulse */
#define ZT_AFTERKEWLTIME 300 /* 300ms after kewl pulse */
+#define ZT_MAX_PRETRAINING 1000 /* 1000ms max pretraining time */
+
#define ZT_MAX_SPANS 128 /* Max, 128 spans */
#define ZT_MAX_CHANNELS 1024 /* Max, 1024 channels */
#define ZT_MAX_CONF 1024 /* Max, 1024 conferences */
@@ -982,12 +994,12 @@
struct confq confin;
struct confq confout;
- short getlin[ZT_MAX_CHUNKSIZE]; /* Last transmitted samples */
+ short getlin[ZT_MAX_CHUNKSIZE]; /* Last transmitted samples */
unsigned char getraw[ZT_MAX_CHUNKSIZE]; /* Last received raw data */
short getlin_lastchunk[ZT_MAX_CHUNKSIZE]; /* Last transmitted samples from last chunk */
- short putlin[ZT_MAX_CHUNKSIZE]; /* Last received samples */
+ short putlin[ZT_MAX_CHUNKSIZE]; /* Last received samples */
unsigned char putraw[ZT_MAX_CHUNKSIZE]; /* Last received raw data */
- short conflast[ZT_MAX_CHUNKSIZE]; /* Last conference sample -- base part of channel */
+ short conflast[ZT_MAX_CHUNKSIZE]; /* Last conference sample -- base part of channel */
short conflast1[ZT_MAX_CHUNKSIZE]; /* Last conference sample -- pseudo part of channel */
short conflast2[ZT_MAX_CHUNKSIZE]; /* Previous last conference sample -- pseudo part of channel */
@@ -997,6 +1009,10 @@
echo_can_state_t *ec;
echo_can_disable_detector_state_t txecdis;
echo_can_disable_detector_state_t rxecdis;
+
+ int echostate; /* State of echo canceller */
+ int echolastupdate; /* Last echo can update pos */
+ int echotimer; /* Timer for echo update */
/* RBS timings */
int prewinktime; /* pre-wink time (ms) */
More information about the svn-commits
mailing list