[zaptel-commits] kpfleming: branch kpfleming/echocanparams r3507 - /team/kpfleming/echocanparams/
SVN commits to the Zaptel project
zaptel-commits at lists.digium.com
Tue Dec 18 09:35:19 CST 2007
Author: kpfleming
Date: Tue Dec 18 09:35:19 2007
New Revision: 3507
URL: http://svn.digium.com/view/zaptel?view=rev&rev=3507
Log:
initial work to enhance echocan interface so that parameters can be supplied when channels are turned on
Added:
team/kpfleming/echocanparams/
- copied from r3505, branches/1.4/
Modified:
team/kpfleming/echocanparams/zaptel-base.c
team/kpfleming/echocanparams/zaptel.h
Modified: team/kpfleming/echocanparams/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/team/kpfleming/echocanparams/zaptel-base.c?view=diff&rev=3507&r1=3505&r2=3507
==============================================================================
--- team/kpfleming/echocanparams/zaptel-base.c (original)
+++ team/kpfleming/echocanparams/zaptel-base.c Tue Dec 18 09:35:19 2007
@@ -4308,6 +4308,92 @@
}
#endif
+static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp, void *data)
+{
+ struct echo_can_state *ec, *tec;
+ int ret;
+ unsigned long flags;
+
+ if (ecp->param_count > 8)
+ return -EINVAL;
+
+ 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 */
+ struct zt_echocanparam params[ecp->param_count];
+
+ if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params)))
+ 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 (!(ec = echo_can_create(ecp, params))) {
+ if (tec)
+ echo_can_free(tec);
+ return -ENOMEM;
+ }
+
+ 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 +4403,7 @@
int oldconf;
void *rxgain=NULL;
struct echo_can_state *ec, *tec;
+ struct zt_echocanparams ecp;
if (!chan)
return -ENOSYS;
@@ -4481,62 +4568,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: team/kpfleming/echocanparams/zaptel.h
URL: http://svn.digium.com/view/zaptel/team/kpfleming/echocanparams/zaptel.h?view=diff&rev=3507&r1=3505&r2=3507
==============================================================================
--- team/kpfleming/echocanparams/zaptel.h (original)
+++ team/kpfleming/echocanparams/zaptel.h Tue Dec 18 09:35:19 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);
+struct echo_can_state *echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p);
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: */
More information about the zaptel-commits
mailing list