[svn-commits] kpfleming: branch 1.4 r3524 - /branches/1.4/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Dec 18 22:04:16 CST 2007
Author: kpfleming
Date: Tue Dec 18 22:04:16 2007
New Revision: 3524
URL: http://svn.digium.com/view/zaptel?view=rev&rev=3524
Log:
add ability to provide parameters to echo cancelers on a per-channel basis, and remove the three versions of the 'Mark' echo canceler (later replaced by KB1 and then by MG2)
Removed:
branches/1.4/mec.h
branches/1.4/mec2.h
branches/1.4/mec2_const.h
branches/1.4/mec3-float.h
branches/1.4/mec3.h
Modified:
branches/1.4/Makefile
branches/1.4/kb1ec.h
branches/1.4/mg2ec.h
branches/1.4/sec-2.h
branches/1.4/sec.h
branches/1.4/zaptel-base.c
branches/1.4/zaptel.h
branches/1.4/zconfig.h
Modified: branches/1.4/Makefile
URL: http://svn.digium.com/view/zaptel/branches/1.4/Makefile?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Tue Dec 18 22:04:16 2007
@@ -372,7 +372,7 @@
tor2.o: tor2-hw.h tor2fw.h
-zaptel-base.o: digits.h arith.h sec.h mec.h sec-2.h mec2.h mec3.h zconfig.h
+zaptel-base.o: digits.h arith.h sec.h sec-2.h kb1ec.h mg2ec.h zconfig.h
wcusb.o: wcusb.h
Modified: branches/1.4/kb1ec.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/kb1ec.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/kb1ec.h (original)
+++ branches/1.4/kb1ec.h Tue Dec 18 22:04:16 2007
@@ -529,12 +529,19 @@
return u;
}
-static inline struct echo_can_state *echo_can_create(int len, int adaption_mode)
-{
- struct echo_can_state *ec;
+static int echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p,
+ struct echo_can_state **ec)
+{
int maxy;
int maxu;
- maxy = len + DEFAULT_M;
+ size_t size;
+
+ if (ecp->param_count > 0) {
+ printk(KERN_WARNING "KB1 echo canceler does not support parameters; failing request\n");
+ return -EINVAL;
+ }
+
+ maxy = ecp->tap_length + DEFAULT_M;
maxu = DEFAULT_M;
if (maxy < (1 << DEFAULT_ALPHA_YT_I))
maxy = (1 << DEFAULT_ALPHA_YT_I);
@@ -542,26 +549,24 @@
maxy = (1 << DEFAULT_SIGMA_LY_I);
if (maxu < (1 << DEFAULT_SIGMA_LU_I))
maxu = (1 << DEFAULT_SIGMA_LU_I);
- ec = (struct echo_can_state *)MALLOC(sizeof(struct echo_can_state) +
- 4 + /* align */
- sizeof(int) * len + /* a_i */
- sizeof(short) * len + /* a_s */
- 2 * sizeof(short) * (maxy) + /* y_s */
- 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
- 2 * sizeof(short) * (maxu) + /* u_s */
- 2 * sizeof(short) * len); /* y_tilde_s */
- if (ec) {
- memset(ec, 0, sizeof(struct echo_can_state) +
- 4 + /* align */
- sizeof(int) * len + /* a_i */
- sizeof(short) * len + /* a_s */
- 2 * sizeof(short) * (maxy) + /* y_s */
- 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
- 2 * sizeof(short) * (maxu) + /* u_s */
- 2 * sizeof(short) * len); /* y_tilde_s */
- init_cc(ec, len, maxy, maxu);
- }
- return ec;
+
+ size = sizeof(*ec) +
+ 4 + /* align */
+ sizeof(int) * ecp->tap_length + /* a_i */
+ sizeof(short) * ecp->tap_length + /* a_s */
+ 2 * sizeof(short) * (maxy) + /* y_s */
+ 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
+ 2 * sizeof(short) * (maxu) + /* u_s */
+ 2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */
+
+ if (!(*ec = MALLOC(size)))
+ return -ENOMEM;
+
+ memset(*ec, 0, size);
+
+ init_cc(*ec, ecp->tap_length, maxy, maxu);
+
+ return 0;
}
static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
Modified: branches/1.4/mg2ec.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/mg2ec.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/mg2ec.h (original)
+++ branches/1.4/mg2ec.h Tue Dec 18 22:04:16 2007
@@ -508,7 +508,7 @@
memset(max_coeffs, 0, USED_COEFFS*sizeof(int));
#endif
#ifdef MEC2_STATS_DETAILED
- printk( KERN_INFO "updating coefficients with: ec->Lu_i %9d\n", ec->Lu_i);
+ printk(KERN_INFO "updating coefficients with: ec->Lu_i %9d\n", ec->Lu_i);
#endif
#ifdef MEC2_STATS
ec->avg_Lu_i_ok = ec->avg_Lu_i_ok + ec->Lu_i;
@@ -550,7 +550,7 @@
#endif
} else {
#ifdef MEC2_STATS_DETAILED
- printk( KERN_INFO "insufficient signal to update coefficients ec->Lu_i %5d < %5d\n", ec->Lu_i, MIN_UPDATE_THRESH_I);
+ printk(KERN_INFO "insufficient signal to update coefficients ec->Lu_i %5d < %5d\n", ec->Lu_i, MIN_UPDATE_THRESH_I);
#endif
#ifdef MEC2_STATS
ec->avg_Lu_i_toolow = ec->avg_Lu_i_toolow + ec->Lu_i;
@@ -565,7 +565,7 @@
*/
#ifdef MEC2_STATS_DETAILED
if (ec->HCNTR_d == 0)
- printk( KERN_INFO "possibily correcting frame with ec->Ly_i %9d ec->Lu_i %9d and expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
+ printk(KERN_INFO "possibily correcting frame with ec->Ly_i %9d ec->Lu_i %9d and expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
#endif
#ifndef NO_ECHO_SUPPRESSOR
@@ -575,7 +575,7 @@
u = u * (ec->Lu_i >> DEFAULT_SIGMA_LU_I) / ((ec->Ly_i >> (DEFAULT_SIGMA_LY_I)) + 1);
}
#ifdef MEC2_STATS_DETAILED
- printk( KERN_INFO "aggresively correcting frame with ec->Ly_i %9d ec->Lu_i %9d expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
+ printk(KERN_INFO "aggresively correcting frame with ec->Ly_i %9d ec->Lu_i %9d expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
#endif
#ifdef MEC2_STATS
++ec->cntr_residualcorrected_frames;
@@ -588,7 +588,7 @@
u = u * (ec->Lu_i >> DEFAULT_SIGMA_LU_I) / ((ec->Ly_i >> (DEFAULT_SIGMA_LY_I + 2)) + 1);
}
#ifdef MEC2_STATS_DETAILED
- printk( KERN_INFO "correcting frame with ec->Ly_i %9d ec->Lu_i %9d expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
+ printk(KERN_INFO "correcting frame with ec->Ly_i %9d ec->Lu_i %9d expression %d\n", ec->Ly_i, ec->Lu_i, (ec->Ly_i/(ec->Lu_i + 1)));
#endif
#ifdef MEC2_STATS
++ec->cntr_residualcorrected_frames;
@@ -628,7 +628,7 @@
else
ec->avg_Lu_i_ok = -1;
- printk( KERN_INFO "%d: Near end speech: %5d Residuals corrected/skipped: %5d/%5d Coefficients updated ok/low sig: %3d/%3d Lu_i avg ok/low sig %6d/%5d\n",
+ printk(KERN_INFO "%d: Near end speech: %5d Residuals corrected/skipped: %5d/%5d Coefficients updated ok/low sig: %3d/%3d Lu_i avg ok/low sig %6d/%5d\n",
ec->id,
ec->cntr_nearend_speech_frames,
ec->cntr_residualcorrected_frames, ec->cntr_residualcorrected_framesskipped,
@@ -650,12 +650,19 @@
return u;
}
-static inline struct echo_can_state *echo_can_create(int len, int adaption_mode)
-{
- struct echo_can_state *ec;
+static int echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p,
+ struct echo_can_state **ec)
+{
int maxy;
int maxu;
- maxy = len + DEFAULT_M;
+ size_t size;
+
+ if (ecp->param_count > 0) {
+ printk(KERN_WARNING "MG2 echo canceler does not support parameters; failing request\n");
+ return -EINVAL;
+ }
+
+ maxy = ecp->tap_length + DEFAULT_M;
maxu = DEFAULT_M;
if (maxy < (1 << DEFAULT_ALPHA_YT_I))
maxy = (1 << DEFAULT_ALPHA_YT_I);
@@ -663,30 +670,23 @@
maxy = (1 << DEFAULT_SIGMA_LY_I);
if (maxu < (1 << DEFAULT_SIGMA_LU_I))
maxu = (1 << DEFAULT_SIGMA_LU_I);
- ec = (struct echo_can_state *)MALLOC(sizeof(struct echo_can_state) +
- 4 + /* align */
- sizeof(int) * len + /* a_i */
- sizeof(short) * len + /* a_s */
- sizeof(int) * len + /* b_i */
- sizeof(int) * len + /* c_i */
- 2 * sizeof(short) * (maxy) + /* y_s */
- 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
- 2 * sizeof(short) * (maxu) + /* u_s */
- 2 * sizeof(short) * len); /* y_tilde_s */
- if (ec) {
- memset(ec, 0, sizeof(struct echo_can_state) +
- 4 + /* align */
- sizeof(int) * len + /* a_i */
- sizeof(short) * len + /* a_s */
- sizeof(int) * len + /* b_i */
- sizeof(int) * len + /* c_i */
- 2 * sizeof(short) * (maxy) + /* y_s */
- 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
- 2 * sizeof(short) * (maxu) + /* u_s */
- 2 * sizeof(short) * len); /* y_tilde_s */
- init_cc(ec, len, maxy, maxu);
- }
- return ec;
+ size = sizeof(**ec) +
+ 4 + /* align */
+ sizeof(int) * ecp->tap_length + /* a_i */
+ sizeof(short) * ecp->tap_length + /* a_s */
+ sizeof(int) * ecp->tap_length + /* b_i */
+ sizeof(int) * ecp->tap_length + /* c_i */
+ 2 * sizeof(short) * (maxy) + /* y_s */
+ 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */
+ 2 * sizeof(short) * (maxu) + /* u_s */
+ 2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */
+
+ if (!(*ec = MALLOC(size)))
+ return -ENOMEM;
+
+ memset(*ec, 0, size);
+
+ return 0;
}
static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
Modified: branches/1.4/sec-2.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/sec-2.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/sec-2.h (original)
+++ branches/1.4/sec-2.h Tue Dec 18 22:04:16 2007
@@ -97,7 +97,6 @@
was skipped, for test purposes */
};
-static struct echo_can_state *echo_can_create(int len, int adaption_mode);
static void echo_can_free(struct echo_can_state *ec);
static int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx);
@@ -127,36 +126,44 @@
/* #define MIN_TX_POWER_FOR_ADAPTION 4096
#define MIN_RX_POWER_FOR_ADAPTION 64 */
-static inline struct echo_can_state *echo_can_create(int len, int adaption_mode)
-{
- struct echo_can_state *ec;
- void *ptr;
-
- ptr = ec = (struct echo_can_state *) MALLOC(sizeof(*ec) + len * sizeof(int32_t) +
- len * sizeof(int16_t));
- if (ec == NULL)
- return NULL;
- memset(ec, 0, sizeof(*ec) + len * sizeof(int32_t) + len * sizeof(int16_t));
- ec->taps = len;
- ec->curr_pos = len - 1;
- ec->tap_mask = len - 1;
- ec->fir_taps32 = (int32_t *) (ptr + sizeof(*ec));
- ec->fir_taps16 = (int16_t *) (ptr + sizeof(*ec) + len * sizeof(int32_t));
- /* Create FIR filter */
- fir16_create(&ec->fir_state, ec->fir_taps16, ec->taps);
- ec->rx_power_threshold = 10000000;
- ec->use_suppressor = FALSE;
- /* Non-linear processor - a fancy way to say "zap small signals, to avoid
- accumulating noise". */
- ec->use_nlp = FALSE;
- return ec;
+static int echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p,
+ struct echo_can_state **ec)
+{
+ size_t size;
+
+ if (ecp->param_count > 0) {
+ printk(KERN_WARNING "SEC-2 echo canceler does not support parameters; failing request\n");
+ return -EINVAL;
+ }
+
+ size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
+
+ if (!(*ec = MALLOC(size)))
+ return -ENOMEM;
+
+ memset(*ec, 0, size);
+
+ (*ec)->taps = ecp->tap_length;
+ (*ec)->curr_pos = ecp->tap_length - 1;
+ (*ec)->tap_mask = ecp->tap_length - 1;
+ (*ec)->fir_taps32 = (int32_t *) (*ec + sizeof(**ec));
+ (*ec)->fir_taps16 = (int16_t *) (*ec + sizeof(**ec) + ecp->tap_length * sizeof(int32_t));
+ /* Create FIR filter */
+ fir16_create(&(*ec)->fir_state, (*ec)->fir_taps16, (*ec)->taps);
+ (*ec)->rx_power_threshold = 10000000;
+ (*ec)->use_suppressor = FALSE;
+ /* Non-linear processor - a fancy way to say "zap small signals, to avoid
+ accumulating noise". */
+ (*ec)->use_nlp = FALSE;
+
+ return 0;
}
/*- End of function --------------------------------------------------------*/
static inline void echo_can_free(struct echo_can_state *ec)
{
- fir16_free(&ec->fir_state);
- FREE(ec);
+ fir16_free(&ec->fir_state);
+ FREE(ec);
}
/*- End of function --------------------------------------------------------*/
Modified: branches/1.4/sec.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/sec.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/sec.h (original)
+++ branches/1.4/sec.h Tue Dec 18 22:04:16 2007
@@ -114,7 +114,6 @@
{
}
-static struct echo_can_state *echo_can_create(int len, int adaption_mode);
static void echo_can_free(struct echo_can_state *ec);
static int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx);
@@ -131,33 +130,44 @@
#define MIN_RX_POWER_FOR_ADAPTION 64
*/
-static inline struct echo_can_state *echo_can_create(int len, int adaption_mode)
-{
- struct echo_can_state *ec;
- void *ptr;
-
- ptr = ec = (struct echo_can_state *) MALLOC(sizeof(*ec) + len * sizeof(int32_t) +
- len * 3 * sizeof(int16_t));
- if (ec == NULL)
- return NULL;
- memset(ec, 0, sizeof(*ec) + len * sizeof(int32_t) + len * 3 * sizeof(int16_t));
- ec->taps = len;
- ec->tap_mask = len - 1;
- ec->tx_history = (int16_t *) (ptr + sizeof(*ec) );
- ec->fir_taps = (int32_t *) (ptr + sizeof(*ec) + len * 2 * sizeof(int16_t));
- ec->fir_taps_short = (int16_t *) (ptr + sizeof(*ec) + len * sizeof(int32_t) + len * 2 * sizeof(int16_t));
- ec->rx_power_threshold = 10000000;
- ec->use_suppressor = FALSE;
- /* Non-linear processor - a fancy way to say "zap small signals, to avoid
- accumulating noise". */
- ec->use_nlp = TRUE;
- return ec;
+static int echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p,
+ struct echo_can_state **ec)
+{
+ size_t size;
+
+ if (ecp->param_count > 0) {
+ printk(KERN_WARNING "SEC echo canceler does not support parameters; failing request\n");
+ return -EINVAL;
+ }
+
+ size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
+
+ if (!(*ec = MALLOC(size)))
+ return -ENOMEM;
+
+ memset(*ec, 0, size);
+
+ (*ec)->taps = ecp->tap_length;
+ (*ec)->tap_mask = ecp->tap_length - 1;
+ (*ec)->tx_history = (int16_t *) (*ec + sizeof(**ec));
+ (*ec)->fir_taps = (int32_t *) (*ec + sizeof(**ec) +
+ ecp->tap_length * 2 * sizeof(int16_t));
+ (*ec)->fir_taps_short = (int16_t *) (*ec + sizeof(**ec) +
+ ecp->tap_length * sizeof(int32_t) +
+ ecp->tap_length * 2 * sizeof(int16_t));
+ (*ec)->rx_power_threshold = 10000000;
+ (*ec)->use_suppressor = FALSE;
+ /* Non-linear processor - a fancy way to say "zap small signals, to avoid
+ accumulating noise". */
+ (*ec)->use_nlp = TRUE;
+
+ return 0;
}
/*- End of function --------------------------------------------------------*/
static inline void echo_can_free(struct echo_can_state *ec)
{
- FREE(ec);
+ FREE(ec);
}
/*- End of function --------------------------------------------------------*/
Modified: branches/1.4/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/zaptel-base.c?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/zaptel-base.c (original)
+++ branches/1.4/zaptel-base.c Tue Dec 18 22:04:16 2007
@@ -419,18 +419,12 @@
#include "sec.h"
#elif defined(ECHO_CAN_STEVE2)
#include "sec-2.h"
-#elif defined(ECHO_CAN_MARK)
-#include "mec.h"
-#elif defined(ECHO_CAN_MARK2)
-#include "mec2.h"
#elif defined(ECHO_CAN_KB1)
#include "kb1ec.h"
#elif defined(ECHO_CAN_MG2)
#include "mg2ec.h"
#elif defined(ECHO_CAN_JP1)
#include "jpah.h"
-#else
-#include "mec3.h"
#endif
static inline void rotate_sums(void)
@@ -4308,6 +4302,95 @@
}
#endif
+#define MAX_ECHOCANPARAMS 8
+
+static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp, void *data)
+{
+ struct echo_can_state *ec, *tec;
+ struct zt_echocanparam params[MAX_ECHOCANPARAMS];
+ int ret;
+ unsigned long flags;
+
+ if (ecp->param_count > MAX_ECHOCANPARAMS)
+ return -E2BIG;
+
+ if (ecp->tap_length == 0) {
+ /* disable mode, don't need to inspect params */
+ spin_lock_irqsave(&chan->lock, flags);
+ 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 (chan->span && chan->span->echocan)
+ chan->span->echocan(chan, 0);
+ if (tec)
+ echo_can_free(tec);
+
+ return 0;
+ }
+
+ /* if parameters were supplied and this channel's span provides an echocan,
+ but not one that takes params, then we must punt here and return an error */
+ if (ecp->param_count && chan->span && chan->span->echocan &&
+ !chan->span->echocan_with_params)
+ return -EINVAL;
+
+ /* enable mode, need the params */
+
+ if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params[0]) * ecp->param_count))
+ return -EFAULT;
+
+ spin_lock_irqsave(&chan->lock, flags);
+ tec = chan->ec;
+ chan->ec = NULL;
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ ret = -ENOTTY;
+
+ /* attempt to use the span's echo canceler; fall back to built-in
+ if it fails (but not if an error occurs) */
+ if (chan->span && chan->span->echocan_with_params)
+ ret = chan->span->echocan_with_params(chan, ecp, params);
+
+ if (ret == -ENOTTY) {
+ switch (ecp->tap_length) {
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ case 512:
+ case 1024:
+ break;
+ default:
+ ecp->tap_length = deftaps;
+ }
+
+ if ((ret = echo_can_create(ecp, params, &ec))) {
+ if (tec)
+ echo_can_free(tec);
+ return ret;
+ }
+
+ spin_lock_irqsave(&chan->lock, flags);
+ chan->echocancel = ecp->tap_length;
+ 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);
+ }
+
+ if (tec)
+ echo_can_free(tec);
+
+ return 0;
+}
+
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
{
struct zt_chan *chan = chans[unit];
@@ -4317,6 +4400,7 @@
int oldconf;
void *rxgain=NULL;
struct echo_can_state *ec, *tec;
+ struct zt_echocanparams ecp;
if (!chan)
return -ENOSYS;
@@ -4481,62 +4565,20 @@
case ZT_ECHOCANCEL:
if (!(chan->flags & ZT_FLAG_AUDIO))
return -EINVAL;
- get_user(j, (int *)data);
- if (j) {
- spin_lock_irqsave(&chan->lock, flags);
- /* If we had an old echo can, zap it now */
- tec = chan->ec;
- chan->ec = NULL;
- /* Attempt hardware native echo can */
- spin_unlock_irqrestore(&chan->lock, flags);
-
- if (chan->span && chan->span->echocan)
- ret = chan->span->echocan(chan, j);
- else
- ret = -ENOTTY;
-
- if (ret) {
- /* Use built-in echo can */
- if ((j == 32) ||
- (j == 64) ||
- (j == 128) ||
- (j == 256) ||
- (j == 512) ||
- (j == 1024)) {
- /* Okay */
- } else {
- j = deftaps;
- }
- ec = echo_can_create(j, 0);
- if (!ec)
- return -ENOMEM;
- spin_lock_irqsave(&chan->lock, flags);
- 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);
- }
- if (tec)
- echo_can_free(tec);
- } else {
- spin_lock_irqsave(&chan->lock, flags);
- 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);
- /* Attempt hardware native echo can */
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
- if (tec)
- echo_can_free(tec);
- }
+ if (copy_from_user(&ecp, (struct zt_echocanparams *) data, sizeof(ecp)))
+ return -EFAULT;
+ data += sizeof(ecp);
+ if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
+ return ret;
+ break;
+ case ZT_ECHOCANCEL_V1:
+ if (!(chan->flags & ZT_FLAG_AUDIO))
+ return -EINVAL;
+ get_user(j, (int *) data);
+ ecp.tap_length = j;
+ ecp.param_count = 0;
+ if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
+ return ret;
break;
case ZT_ECHOTRAIN:
get_user(j, (int *)data); /* get pre-training time from user */
Modified: branches/1.4/zaptel.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/zaptel.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/zaptel.h (original)
+++ branches/1.4/zaptel.h Tue Dec 18 22:04:16 2007
@@ -560,11 +560,18 @@
/*
* Enable or disable echo cancellation on a channel
+ *
+ * For ECHOCANCEL_V1:
* 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 canceller
- */
-#define ZT_ECHOCANCEL _IOW (ZT_CODE, 33, int)
+ * and 1024, it will also set the number of taps in the echo canceller
+ *
+ * For ECHOCANCEL:
+ * The structure contains parameters that should be passed to the
+ * echo canceler instance for the selected channel.
+ */
+#define ZT_ECHOCANCEL_V1 _IOW (ZT_CODE, 33, int)
+#define ZT_ECHOCANCEL _IOW (ZT_CODE, 33, struct zt_echocanparams)
/*
* Return a channel's channel number (useful for the /dev/zap/pseudo type interfaces
@@ -866,6 +873,17 @@
struct zt_ring_cadence {
int ringcadence[ZT_MAX_CADENCE];
+};
+
+struct zt_echocanparam {
+ char name[8];
+ unsigned int value;
+};
+
+struct zt_echocanparams {
+ unsigned int tap_length; /* 8 taps per millisecond */
+ unsigned int param_count; /* number of parameters supplied */
+ /* immediately follow this structure with zt_echocanparam structures */
};
struct zt_tone_def_header {
@@ -1165,7 +1183,7 @@
void echo_can_init(void);
void echo_chan_shutdown(void);
void echo_can_identify(char *buf, size_t len);
-struct echo_can_state *echo_can_create(int len, int adaption_mode);
+int echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p, struct echo_can_state **ec);
void echo_can_free(struct echo_can_state *ec);
short echo_can_update(struct echo_can_state *ec, short iref, short isig);
void echo_can_array_update(struct echo_can_state *ec, short *iref, short *isig);
@@ -1514,8 +1532,10 @@
/* Opt: IOCTL */
int (*ioctl)(struct zt_chan *chan, unsigned int cmd, unsigned long data);
- /* Opt: Native echo cancellation */
+ /* Opt: Native echo cancellation (simple) */
int (*echocan)(struct zt_chan *chan, int ecval);
+
+ int (*echocan_with_params)(struct zt_chan *chan, struct zt_echocanparams *ecp, struct zt_echocanparam *p);
/* Okay, now we get to the signalling. You have several options: */
Modified: branches/1.4/zconfig.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/zconfig.h?view=diff&rev=3524&r1=3523&r2=3524
==============================================================================
--- branches/1.4/zconfig.h (original)
+++ branches/1.4/zconfig.h Tue Dec 18 22:04:16 2007
@@ -63,9 +63,6 @@
*/
/* #define ECHO_CAN_STEVE */
/* #define ECHO_CAN_STEVE2 */
-/* #define ECHO_CAN_MARK */
-/* #define ECHO_CAN_MARK2 */
-/* #define ECHO_CAN_MARK3 */
/* #define ECHO_CAN_KB1 */
/* This is the new latest and greatest */
#define ECHO_CAN_MG2
More information about the svn-commits
mailing list