[asterisk-dev] [svn-commits] kpfleming: branch 1.4 r3524 - /branches/1.4/

Patrick asterisk-list at puzzled.xs4all.nl
Wed Dec 19 07:02:24 CST 2007


Kevin,

Quickly browsing the commit I don't see any documentation how to do "per
channel" EC. Is there documentation available somewhere?

Regards,
Patrick

On Wed, 2007-12-19 at 04:04 +0000, SVN commits to the Digium
repositories wrote:
> 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
> 
> 
> _______________________________________________
> --Bandwidth and Colocation Provided by http://www.api-digital.com--
> 
> svn-commits mailing list
> To UNSUBSCRIBE or update options visit:
>    http://lists.digium.com/mailman/listinfo/svn-commits




More information about the asterisk-dev mailing list