[svn-commits] kpfleming: branch linux/kpfleming/modular_ec r4397 - /linux/team/kpfleming/mo...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jun 18 17:05:53 CDT 2008


Author: kpfleming
Date: Wed Jun 18 17:05:53 2008
New Revision: 4397

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4397
Log:
convert rest of echo cans to modules, bring single-use header files into the modules that use them, and disable calling echo can functions for now until the code is ready to test

Added:
    linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c
      - copied, changed from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c
      - copied, changed from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c
      - copied, changed from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/sec-2.h
Removed:
    linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec_const.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec_const.h
    linux/team/kpfleming/modular_ec/drivers/dahdi/sec-2.h
Modified:
    linux/team/kpfleming/modular_ec/drivers/dahdi/Kbuild
    linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi-base.c
    linux/team/kpfleming/modular_ec/drivers/dahdi/fir.h

Modified: linux/team/kpfleming/modular_ec/drivers/dahdi/Kbuild
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/Kbuild?view=diff&rev=4397&r1=4396&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/Kbuild (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/Kbuild Wed Jun 18 17:05:53 2008
@@ -26,6 +26,9 @@
 
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_JPAH)	+= dahdi_echocan_jpah.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE)	+= dahdi_echocan_sec.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE2)	+= dahdi_echocan_sec2.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
 
 CFLAGS_MODULE += -I$(src)
 EXTRA_CFLAGS += $(ECHO_CAN_CFLAGS)

Modified: linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi-base.c?view=diff&rev=4397&r1=4396&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi-base.c Wed Jun 18 17:05:53 2008
@@ -333,22 +333,7 @@
 
 static struct dahdi_zone *tone_zones[DAHDI_TONE_ZONE_MAX];
 
-#define NUM_SIGS	10	
-
-/* Echo cancellation */
-#if defined(ECHO_CAN_HPEC)
-#include "hpec/hpec_dahdi.h"
-#elif defined(ECHO_CAN_STEVE)
-#include "sec.h"
-#elif defined(ECHO_CAN_STEVE2)
-#include "sec-2.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"
-#endif
+#define NUM_SIGS	10
 
 #ifdef DEFINE_RWLOCK
 static DEFINE_RWLOCK(echocan_list_lock);
@@ -1078,8 +1063,8 @@
 
 	if (rxgain)
 		kfree(rxgain);
-	if (ec)
-		echo_can_free(ec);
+//	if (ec)
+//		echo_can_free(ec);
 	if (readchunkpreec)
 		kfree(readchunkpreec);
 
@@ -2282,8 +2267,8 @@
 
 	if (rxgain)
 		kfree(rxgain);
-	if (ec)
-		echo_can_free(ec);
+//	if (ec)
+//		echo_can_free(ec);
 	return 0;
 }
 
@@ -4514,8 +4499,8 @@
 		chan->echotimer = 0;
 		spin_unlock_irqrestore(&chan->lock, flags);
 		hw_echocancel_off(chan);
-		if (tec)
-			echo_can_free(tec);
+//		if (tec)
+//			echo_can_free(tec);
 
 		return 0;
 	}
@@ -4543,8 +4528,8 @@
 	chan->ec = NULL;
 	spin_unlock_irqrestore(&chan->lock, flags);
 	
-	if (tec)
-		echo_can_free(tec);
+//	if (tec)
+//		echo_can_free(tec);
 
 	ret = -ENODEV;
 	
@@ -4570,8 +4555,8 @@
 			ecp->tap_length = deftaps;
 		}
 		
-		if ((ret = echo_can_create(ecp, params, &ec)))
-			goto exit_with_free;
+//		if ((ret = echo_can_create(ecp, params, &ec)))
+//			goto exit_with_free;
 		
 		spin_lock_irqsave(&chan->lock, flags);
 		chan->echocancel = ecp->tap_length;
@@ -4668,8 +4653,8 @@
 
 			if (rxgain)
 				kfree(rxgain);
-			if (ec)
-				echo_can_free(ec);
+//			if (ec)
+//				echo_can_free(ec);
 			if (oldconf) dahdi_check_conf(oldconf);
 		}
 		break;
@@ -4718,8 +4703,8 @@
 					chan->flags |= (DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
 					hw_echocancel_off(chan);
 					
-					if (tec)
-						echo_can_free(tec);
+//					if (tec)
+//						echo_can_free(tec);
 				} else
 					return -ENOMEM;
 			}
@@ -5321,7 +5306,7 @@
 				ms->echostate = ECHO_STATE_IDLE;
 				ms->echolastupdate = 0;
 				ms->echotimer = 0;
-				echo_can_free(ms->ec);
+//				echo_can_free(ms->ec);
 				ms->ec = NULL;
 				__qevent(ss, DAHDI_EVENT_EC_DISABLED);
 				break;
@@ -6147,33 +6132,25 @@
 					ss->echostate = ECHO_STATE_TRAINING;
 				}
 				if (ss->echostate == ECHO_STATE_TRAINING) {
-					if (echo_can_traintap(ss->ec, ss->echolastupdate++, rxlin)) {
+//					if (echo_can_traintap(ss->ec, ss->echolastupdate++, rxlin)) {
 #if 0
-						printk("Finished training (%d taps trained)!\n", ss->echolastupdate);
+//						printk("Finished training (%d taps trained)!\n", ss->echolastupdate);
 #endif						
-						ss->echostate = ECHO_STATE_ACTIVE;
-					}
+//						ss->echostate = ECHO_STATE_ACTIVE;
+//					}
 				}
 				rxlin = 0;
 				rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss);
 			}
 		} else {
-#if !defined(DAHDI_EC_ARRAY_UPDATE)
-			for (x=0;x<DAHDI_CHUNKSIZE;x++) {
-				rxlin = DAHDI_XLAW(rxchunk[x], ss);
-				rxlin = echo_can_update(ss->ec, DAHDI_XLAW(txchunk[x], ss), rxlin);
-				rxchunk[x] = DAHDI_LIN2X((int) rxlin, ss);
-			}
-#else /* defined(DAHDI_EC_ARRAY_UPDATE) */
 			short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE];
 			for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
 				rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
 				txlins[x] = DAHDI_XLAW(txchunk[x], ss);
 			}
-			echo_can_array_update(ss->ec, rxlins, txlins);
+//			echo_can_array_update(ss->ec, rxlins, txlins);
 			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
 				rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
-#endif /* defined(DAHDI_EC_ARRAY_UPDATE) */
 		}
 #if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
 		kernel_fpu_end();
@@ -6275,7 +6252,7 @@
 				ms->echostate = ECHO_STATE_IDLE;
 				ms->echolastupdate = 0;
 				ms->echotimer = 0;
-				echo_can_free(ms->ec);
+//				echo_can_free(ms->ec);
 				ms->ec = NULL;
 				break;
 			}
@@ -7570,8 +7547,6 @@
 #ifdef CONFIG_DAHDI_WATCHDOG
 	watchdog_cleanup();
 #endif
-
-	echo_can_shutdown();
 }
 
 module_init(dahdi_init);

Copied: linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c (from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec.h)
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c?view=diff&rev=4397&p1=linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec.h&r1=4392&p2=linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/kb1ec.h (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c Wed Jun 18 17:05:53 2008
@@ -3,7 +3,7 @@
  *
  * by Kris Boutilier
  *
- * Based upon mech2.h
+ * Based upon mec2.h
  * 
  * Copyright (C) 2002, Digium, Inc.
  *
@@ -23,15 +23,20 @@
  *
  */
 
-#ifndef _MARK2_ECHO_H
-#define _MARK2_ECHO_H
-
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/ctype.h>
-
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
+#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
 
 /* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */ 
 /* #define MEC2_STATS 4000 */
@@ -42,8 +47,71 @@
 /* Get optimized routines for math */
 #include "arith.h"
 
-/* Bring in definitions for the various constants and thresholds */
-#include "kb1ec_const.h"
+/*
+   Important constants for tuning kb1 echo can
+ */
+
+/* Convergence (aka. adaptation) speed -- higher means slower */
+#define DEFAULT_BETA1_I 2048
+
+/* Constants for various power computations */
+#define DEFAULT_SIGMA_LY_I 7
+#define DEFAULT_SIGMA_LU_I 7
+#define DEFAULT_ALPHA_ST_I 5 		/* near-end speech detection sensitivity factor */
+#define DEFAULT_ALPHA_YT_I 5
+
+#define DEFAULT_CUTOFF_I 128
+
+/* Define the near-end speech hangover counter: if near-end speech 
+ *  is declared, hcntr is set equal to hangt (see pg. 432)
+ */
+#define DEFAULT_HANGT 600  		/* in samples, so 600 samples = 75ms */
+
+/* define the residual error suppression threshold */
+#define DEFAULT_SUPPR_I 16		/* 16 = -24db */
+
+/* This is the minimum reference signal power estimate level 
+ *  that will result in filter adaptation.
+ * If this is too low then background noise will cause the filter 
+ *  coefficients to constantly be updated.
+ */
+#define MIN_UPDATE_THRESH_I 4096
+
+/* The number of samples used to update coefficients using the
+ *  the block update method (M). It should be related back to the 
+ *  length of the echo can.
+ * ie. it only updates coefficients when (sample number MOD default_m) = 0
+ *
+ *  Getting this wrong may cause an oops. Consider yourself warned!
+ */
+#define DEFAULT_M 16		  	/* every 16th sample */
+
+/* If AGGRESSIVE supression is enabled, then we start cancelling residual 
+ * echos again even while there is potentially the very end of a near-side 
+ *  signal present.
+ * This defines how many samples of DEFAULT_HANGT can remain before we
+ *  kick back in
+ */
+#define AGGRESSIVE_HCNTR 160		/* in samples, so 160 samples = 20ms */
+
+
+/***************************************************************/
+/* The following knobs are not implemented in the current code */
+
+/* we need a dynamic level of suppression varying with the ratio of the 
+   power of the echo to the power of the reference signal this is 
+   done so that we have a  smoother background. 		
+   we have a higher suppression when the power ratio is closer to
+   suppr_ceil and reduces logarithmically as we approach suppr_floor.
+ */
+#define SUPPR_FLOOR -64
+#define SUPPR_CEIL -24
+
+/* in a second departure, we calculate the residual error suppression
+ * as a percentage of the reference signal energy level. The threshold
+ * is defined in terms of dB below the reference signal.
+ */
+#define RES_SUPR_FACTOR -20
 
 #ifndef NULL
 #define NULL 0
@@ -133,20 +201,6 @@
 	unsigned int aggressive:1;
 };
 
-static void echo_can_init(void)
-{
-	printk("DAHDI Echo Canceller: KB1\n");
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
-	dahdi_copy_string(buf, "KB1", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
 static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)
 {
 	cb->buf_d = (short *)where;
@@ -238,14 +292,13 @@
 
 }
 
-static inline void echo_can_free(struct echo_can_state *ec)
-{
-	FREE(ec);
-}
-
-static inline short echo_can_update(struct echo_can_state *ec, short iref, short isig) 
-{
-
+static void echo_can_free(struct echo_can_state *ec)
+{
+	kfree(ec);
+}
+
+static inline short sample_update(struct echo_can_state *ec, short iref, short isig) 
+{
 	/* Declare local variables that are used more than once */
 	/* ... */
 	int k;
@@ -521,6 +574,17 @@
 	return u;
 }
 
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+	unsigned int x;
+	short result;
+
+	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+		result = sample_update(ec, *iref, *isig);
+		*isig++ = result;
+	}
+}
+
 static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
 			   struct echo_can_state **ec)
 {
@@ -548,7 +612,7 @@
 		2 * sizeof(short) * (maxu) +			/* u_s */
 		2 * sizeof(short) * ecp->tap_length;		/* y_tilde_s */
 
-	if (!(*ec = MALLOC(size)))
+	if (!(*ec = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
 
 	memset(*ec, 0, size);
@@ -575,7 +639,7 @@
 	return 0;
 }
 
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
 {
 	/* Set the hangover counter to the length of the can to 
 	 * avoid adjustments occuring immediately after initial forced training 
@@ -594,4 +658,37 @@
 	return 0;
 }
 
-#endif
+static const struct dahdi_echocan me = {
+	.name = "KB1",
+	.echo_can_create = echo_can_create,
+	.echo_can_free = echo_can_free,
+	.echo_can_array_update = echo_can_update,
+	.echo_can_traintap = echo_can_traintap,
+};
+
+static int __init mod_init(void)
+{
+	if (dahdi_register_echocan(&me, THIS_MODULE)) {
+		module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+		return -EPERM;
+	}
+
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+	return 0;
+}
+
+static void __exit mod_exit(void)
+{
+	dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'KB1' Echo Canceler");
+MODULE_AUTHOR("Kris Boutilier");
+MODULE_LICENSE("GPL v2");
+
+module_init(mod_init);
+module_exit(mod_exit);

Copied: linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c (from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec.h)
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c?view=diff&rev=4397&p1=linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec.h&r1=4392&p2=linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/mg2ec.h (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c Wed Jun 18 17:05:53 2008
@@ -23,15 +23,20 @@
  *
  */
 
-#ifndef _MG2_ECHO_H
-#define _MG2_ECHO_H
-
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/ctype.h>
-
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
+#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
 
 #define ABS(a) abs(a!=-32768?a:-32767)
 
@@ -56,8 +61,87 @@
 /* Get optimized routines for math */
 #include "arith.h"
 
-/* Bring in definitions for the various constants and thresholds */
-#include "mg2ec_const.h"
+/*
+   Important constants for tuning mg2 echo can
+ */
+
+/* Convergence (aka. adaptation) speed -- higher means slower */
+#define DEFAULT_BETA1_I 2048
+
+/* Constants for various power computations */
+#define DEFAULT_SIGMA_LY_I 7
+#define DEFAULT_SIGMA_LU_I 7
+#define DEFAULT_ALPHA_ST_I 5 		/* near-end speech detection sensitivity factor */
+#define DEFAULT_ALPHA_YT_I 5
+
+#define DEFAULT_CUTOFF_I 128
+
+/* Define the near-end speech hangover counter: if near-end speech 
+ *  is declared, hcntr is set equal to hangt (see pg. 432)
+ */
+#define DEFAULT_HANGT 600  		/* in samples, so 600 samples = 75ms */
+
+/* define the residual error suppression threshold */
+#define DEFAULT_SUPPR_I 16		/* 16 = -24db */
+
+/* This is the minimum reference signal power estimate level 
+ *  that will result in filter adaptation.
+ * If this is too low then background noise will cause the filter 
+ *  coefficients to constantly be updated.
+ */
+#define MIN_UPDATE_THRESH_I 2048
+
+/* The number of samples used to update coefficients using the
+ *  the block update method (M). It should be related back to the 
+ *  length of the echo can.
+ * ie. it only updates coefficients when (sample number MOD default_m) = 0
+ *
+ *  Getting this wrong may cause an oops. Consider yourself warned!
+ */
+#define DEFAULT_M 16		  	/* every 16th sample */
+
+/* If AGGRESSIVE supression is enabled, then we start cancelling residual 
+ * echos again even while there is potentially the very end of a near-side 
+ *  signal present.
+ * This defines how many samples of DEFAULT_HANGT can remain before we
+ *  kick back in
+ */
+#define AGGRESSIVE_HCNTR 160		/* in samples, so 160 samples = 20ms */
+
+/* Treat sample as error if it has a different sign as the
+ * input signal and is this number larger in ABS() as
+ * the input-signal */
+#define MAX_SIGN_ERROR 3000
+
+/* Number of coefficients really used for calculating the
+ * simulated echo. The value specifies how many of the
+ * biggest coefficients are used for calculating rs.
+ * This helps on long echo-tails by artificially limiting
+ * the number of coefficients for the calculation and
+ * preventing overflows.
+ * Comment this to deactivate the code */
+#define USED_COEFFS 64
+
+/* Backup coefficients every this number of samples */
+#define BACKUP 256
+
+/***************************************************************/
+/* The following knobs are not implemented in the current code */
+
+/* we need a dynamic level of suppression varying with the ratio of the 
+   power of the echo to the power of the reference signal this is 
+   done so that we have a  smoother background. 		
+   we have a higher suppression when the power ratio is closer to
+   suppr_ceil and reduces logarithmically as we approach suppr_floor.
+ */
+#define SUPPR_FLOOR -64
+#define SUPPR_CEIL -24
+
+/* in a second departure, we calculate the residual error suppression
+ * as a percentage of the reference signal energy level. The threshold
+ * is defined in terms of dB below the reference signal.
+ */
+#define RES_SUPR_FACTOR -20
 
 #define DC_NORMALIZE
 
@@ -159,20 +243,6 @@
 
 };
 
-static void echo_can_init(void)
-{
-	printk("DAHDI Echo Canceller: MG2\n");
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
-	dahdi_copy_string(buf, "MG2", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
 static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)
 {
 	cb->buf_d = (short *)where;
@@ -270,12 +340,12 @@
 
 }
 
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
 {
 #if defined(DC_NORMALIZE) && defined(MEC2_DCBIAS_MESSAGE)
 	printk("EC: DC bias calculated: %d V\n", ec->dc_estimate >> 15);
 #endif
-	FREE(ec);
+	kfree(ec);
 }
 
 #ifdef DC_NORMALIZE
@@ -286,9 +356,8 @@
 }
 #endif
 
-static inline short echo_can_update(struct echo_can_state *ec, short iref, short isig) 
-{
-
+static inline short sample_update(struct echo_can_state *ec, short iref, short isig) 
+{
 	/* Declare local variables that are used more than once */
 	/* ... */
 	int k;
@@ -640,6 +709,17 @@
 	/* Increment the sample index and return the corrected sample */
 	ec->i_d++;
 	return u;
+}
+
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+	unsigned int x;
+	short result;
+
+	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+		result = sample_update(ec, *iref, *isig);
+		*isig++ = result;
+	}
 }
 
 static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
@@ -670,7 +750,7 @@
 		2 * sizeof(short) * (maxu) +			/* u_s */
 		2 * sizeof(short) * ecp->tap_length;		/* y_tilde_s */
 
-	if (!(*ec = MALLOC(size)))
+	if (!(*ec = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
 
 	memset(*ec, 0, size);
@@ -697,7 +777,7 @@
 	return 0;
 }
 
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
 {
 	/* Set the hangover counter to the length of the can to 
 	 * avoid adjustments occuring immediately after initial forced training 
@@ -722,4 +802,37 @@
 	return 0;
 }
 
-#endif
+static const struct dahdi_echocan me = {
+	.name = "MG2",
+	.echo_can_create = echo_can_create,
+	.echo_can_free = echo_can_free,
+	.echo_can_array_update = echo_can_update,
+	.echo_can_traintap = echo_can_traintap,
+};
+
+static int __init mod_init(void)
+{
+	if (dahdi_register_echocan(&me, THIS_MODULE)) {
+		module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+		return -EPERM;
+	}
+
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+	return 0;
+}
+
+static void __exit mod_exit(void)
+{
+	dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'MG2' Echo Canceler");
+MODULE_AUTHOR("Michael Gernoth");
+MODULE_LICENSE("GPL v2");
+
+module_init(mod_init);
+module_exit(mod_exit);

Copied: linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c (from r4392, linux/team/kpfleming/modular_ec/drivers/dahdi/sec-2.h)
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c?view=diff&rev=4397&p1=linux/team/kpfleming/modular_ec/drivers/dahdi/sec-2.h&r1=4392&p2=linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/sec-2.h (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c Wed Jun 18 17:05:53 2008
@@ -36,22 +36,20 @@
    Improve double talk detector (iterative!)
 */
 
-#ifndef _DAHDI_SEC_H
-#define _DAHDI_SEC_H
-
-#ifdef __KERNEL__
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
-#else
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#define MALLOC(a) malloc(a)
-#define FREE(a) free(a)
-#endif
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
+#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
 
 #include "fir.h"
 
@@ -97,23 +95,6 @@
 				   was skipped, for test purposes */
 };
 
-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);
-
-static void echo_can_init(void)
-{
-	printk("DAHDI Echo Canceller: STEVE2%s\n", DAHDI_ECHO_AGGRESSIVE);
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
-	dahdi_copy_string(buf, "STEVE2", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
 /*
  * According to Jim...
  */
@@ -138,7 +119,7 @@
 
 	size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
 	
-	if (!(*ec = MALLOC(size)))
+	if (!(*ec = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
 	
 	memset(*ec, 0, size);
@@ -160,14 +141,14 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
 {
 	fir16_free(&ec->fir_state);
-	FREE(ec);
+	kfree(ec);
 }
 /*- End of function --------------------------------------------------------*/
 
-static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
+static inline int16_t sample_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
 {
     int offset1;
     int offset2;
@@ -297,143 +278,21 @@
 
     return  clean_rx;
 }
-
-#if 0
-static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
-{
-    int offset;
-    int limit;
-    int32_t echo_value;
-    int clean_rx;
-    int nsuppr;
-    int i;
-    int correction;
-
-    ec->tx_history[ec->curr_pos] = tx;
-
-    /* Evaluate the echo - i.e. apply the FIR filter */
-    /* Assume the gain of the FIR does not exceed unity. Exceeding unity
-       would seem like a rather poor thing for an echo cancellor to do :)
-       This means we can compute the result with a total disregard for
-       overflows. 16bits x 16bits -> 31bits, so no overflow can occur in
-       any multiply. While accumulating we may overflow and underflow the
-       32 bit scale often. However, if the gain does not exceed unity,
-       everything should work itself out, and the final result will be
-       OK, without any saturation logic. */
-    /* Overflow is very much possible here, and we do nothing about it because
-       of the compute costs */
-    /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
-       bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
-       best */
-    offset = ec->curr_pos;
-    limit = ec->taps - offset;
-    echo_value = 0;
-    for (i = 0;  i < limit;  i++)
-        echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i + offset];
-    offset = ec->taps - ec->curr_pos;
-    for (  ;  i < ec->taps;  i++)
-        echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i - offset];
-    echo_value >>= 16;
-
-    /* And the answer is..... */
-    clean_rx = rx - echo_value;
-
-    /* That was the easy part. Now we need to adapt! */
-    if (ec->nonupdate_dwell > 0)
-    	ec->nonupdate_dwell--;
-
-    /* If there is very little being transmitted, any attempt to train is
-       futile. We would either be training on the far end's noise or signal,
-       the channel's own noise, or our noise. Either way, this is hardly good
-       training, so don't do it (avoid trouble). */
-    /* If the received power is very low, either we are sending very little or
-       we are already well adapted. There is little point in trying to improve
-       the adaption under these circumstanceson, so don't do it (reduce the
-       compute load). */
-    if (ec->tx_power > MIN_TX_POWER_FOR_ADAPTION
-    	&&
-	ec->rx_power > MIN_RX_POWER_FOR_ADAPTION)
-    {
-    	/* This is a really crude piece of decision logic, but it does OK
-	   for now. */
-    	if (ec->tx_power > 2*ec->rx_power)
-	{
-            /* There is no far-end speech detected */
-            if (ec->nonupdate_dwell == 0)
-	    {
-	    	/* ... and we are not in the dwell time from previous speech. */
-		//nsuppr = saturate((clean_rx << 16)/ec->tx_power);
-		nsuppr = clean_rx >> 3;
-
-		/* Update the FIR taps */
-    	        offset = ec->curr_pos;
-    	    	limit = ec->taps - offset;
-		ec->latest_correction = 0;
-    	    	for (i = 0;  i < limit;  i++)
-		{
-		    correction = ec->tx_history[i + offset]*nsuppr;
-		    ec->fir_taps[i] += correction;
-		    //ec->latest_correction += abs(correction);
-        	}
-		offset = ec->taps - ec->curr_pos;
-    		for (  ;  i < ec->taps;  i++)
-		{
-		    correction = ec->tx_history[i - offset]*nsuppr;
-		    ec->fir_taps[i] += correction;
-		    //ec->latest_correction += abs(correction);
-    	    	}
-    	    }
-	    else
-	    {
-        	ec->latest_correction = -3;
-    	    }
-	}
-	else
-	{
-            ec->nonupdate_dwell = NONUPDATE_DWELL_TIME;
-    	    ec->latest_correction = -2;
-	}
-    }
-    else
-    {
-        ec->nonupdate_dwell = 0;
-        ec->latest_correction = -1;
-    }
-    /* Calculate short term power levels using very simple single pole IIRs */
-    /* TODO: Is the nasty modulus approach the fastest, or would a real
-       tx*tx power calculation actually be faster? */
-    ec->tx_power += ((abs(tx) - ec->tx_power) >> 5);
-    ec->rx_power += ((abs(rx) - ec->rx_power) >> 5);
-    ec->clean_rx_power += ((abs(clean_rx) - ec->clean_rx_power) >> 5);
-
-#if defined(XYZZY)
-    if (ec->use_suppressor)
-    {
-    	ec->supp_test1 += (ec->tx_history[ec->curr_pos] - ec->tx_history[(ec->curr_pos - 7) & ec->tap_mask]);
-    	ec->supp_test2 += (ec->tx_history[(ec->curr_pos - 24) & ec->tap_mask] - ec->tx_history[(ec->curr_pos - 31) & ec->tap_mask]);
-    	if (ec->supp_test1 > 42  &&  ec->supp_test2 > 42)
-    	    supp_change = 25;
-    	else
-    	    supp_change = 50;
-    	supp = supp_change + k1*ec->supp1 + k2*ec->supp2;
-	ec->supp2 = ec->supp1;
-	ec->supp1 = supp;
-	clean_rx *= (1 - supp);
-    }
-#endif
-
-    if (ec->use_nlp  &&  ec->rx_power < 32)
-    	clean_rx = 0;
-
-    /* Roll around the rolling buffer */
-    ec->curr_pos = (ec->curr_pos + 1) & ec->tap_mask;
-
-    return clean_rx;
-}
 /*- End of function --------------------------------------------------------*/
-#endif
-
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+	unsigned int x;
+	short result;
+
+	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+		result = sample_update(ec, *iref, *isig);
+		*isig++ = result;
+	}
+}
+/*- End of function --------------------------------------------------------*/
+
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
 {
 	/* Reset hang counter to avoid adjustments after
 	   initial forced training */
@@ -447,5 +306,37 @@
 	return 0;
 }
 
-/*- End of file ------------------------------------------------------------*/
-#endif
+static const struct dahdi_echocan me = {
+	.name = "STEVE2",
+	.echo_can_create = echo_can_create,
+	.echo_can_free = echo_can_free,
+	.echo_can_array_update = echo_can_update,
+	.echo_can_traintap = echo_can_traintap,
+};
+
+static int __init mod_init(void)
+{
+	if (dahdi_register_echocan(&me, THIS_MODULE)) {
+		module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+		return -EPERM;
+	}
+
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+	return 0;
+}
+
+static void __exit mod_exit(void)
+{
+	dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'STEVE2' Echo Canceler");
+MODULE_AUTHOR("Steve Underwood <steveu at coppice.org>");
+MODULE_LICENSE("GPL");
+
+module_init(mod_init);
+module_exit(mod_exit);

Modified: linux/team/kpfleming/modular_ec/drivers/dahdi/fir.h
URL: http://svn.digium.com/view/dahdi/linux/team/kpfleming/modular_ec/drivers/dahdi/fir.h?view=diff&rev=4397&r1=4396&r2=4397
==============================================================================
--- linux/team/kpfleming/modular_ec/drivers/dahdi/fir.h (original)
+++ linux/team/kpfleming/modular_ec/drivers/dahdi/fir.h Wed Jun 18 17:05:53 2008
@@ -51,7 +51,7 @@
     fir->taps = taps;
     fir->curr_pos = taps - 1;
     fir->coeffs = coeffs;
-    fir->history = MALLOC (taps*sizeof (int16_t));
+    fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL);
     if (fir->history)
         memset (fir->history, '\0', taps*sizeof (int16_t));
 }
@@ -59,7 +59,7 @@
     
 static inline void fir16_free (fir16_state_t *fir)
 {
-    FREE (fir->history);
+    kfree(fir->history);
 }
 /*- End of function --------------------------------------------------------*/
     
@@ -92,7 +92,7 @@
     fir->taps = taps;
     fir->curr_pos = taps - 1;
     fir->coeffs = coeffs;
-    fir->history = MALLOC (taps*sizeof (int16_t));
+    fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL);
     if (fir->history)
     	memset (fir->history, '\0', taps*sizeof (int16_t));
 }
@@ -100,7 +100,7 @@
     
 static inline void fir32_free (fir32_state_t *fir)
 {
-    FREE (fir->history);
+    kfree(fir->history);
 }
 /*- End of function --------------------------------------------------------*/
     




More information about the svn-commits mailing list