Index: mg2ec.h
===================================================================
--- mg2ec.h	(revision 890)
+++ mg2ec.h	(working copy)
@@ -43,6 +43,15 @@
 
 #define ABS(a) abs(a!=-32768?a:-32767)
 
+#define RESTORE_COEFFS {\
+				int x;\
+				memcpy(ec->a_i, ec->c_i, ec->N_d*sizeof(int));\
+				for (x=0;x<ec->N_d;x++) {\
+					ec->a_s[x] = ec->a_i[x] >> 16;\
+				}\
+				ec->backup = BACKUP;\
+			}
+
 /* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */ 
 /* #define MEC2_STATS 4000 */
 
@@ -113,6 +122,9 @@
 	int *a_i;
 	/* ... */
 	short *a_s;
+	/* Backups */
+	int *b_i;
+	int *c_i;
 	/* Reference samples of far-end receive signal */
 	echo_can_cb_s y_s;
 	/* Reference samples of near-end signal */
@@ -142,6 +154,7 @@
 #endif 
 	short lastsig[256];
 	int lastpos;
+	int backup;
 
 } echo_can_state_t;
 
@@ -193,6 +206,12 @@
 	ec->a_s = ptr;
 	ptr += (sizeof(short) * ec->N_d);
 
+	/* Allocate backup memory */
+	ec->b_i = ptr;
+	ptr += (sizeof(int) * ec->N_d);
+	ec->c_i = ptr;
+	ptr += (sizeof(int) * ec->N_d);
+
 	/* Reset Y circular buffer (short version) */
 	init_cb_s(&ec->y_s, maxy, ptr);
 	ptr += (sizeof(short) * (maxy) * 2);
@@ -301,20 +320,17 @@
 		if (rs < -32768) {
 			rs = -32768;
 			ec->HCNTR_d = DEFAULT_HANGT;
-			memset(ec->a_i, 0, sizeof(int) * ec->N_d);
-			memset(ec->a_s, 0, sizeof(short) * ec->N_d);
+			RESTORE_COEFFS;
 		} else if (rs > 32767) {
 			rs = 32767;
 			ec->HCNTR_d = DEFAULT_HANGT;
-			memset(ec->a_i, 0, sizeof(int) * ec->N_d);
-			memset(ec->a_s, 0, sizeof(short) * ec->N_d);
+			RESTORE_COEFFS;
 		}
 
-		if (ABS(ABS(rs)-ABS(isig)) > 3000)
+		if (ABS(ABS(rs)-ABS(isig)) > MAX_SIGN_ERROR)
 		{
 			rs = 0;
-			memset(ec->a_i, 0, sizeof(int) * ec->N_d);
-			memset(ec->a_s, 0, sizeof(short) * ec->N_d);
+			RESTORE_COEFFS;
 		}
 
 		/* eq. (3): compute the output value (see figure 3) and the error
@@ -330,7 +346,15 @@
 	/* Push a copy of the output value sample into its circular buffer */
 	add_cc_s(&ec->u_s, u);
 
+	if (!ec->backup) {
+		/* Backup coefficients periodically */
+		ec->backup = BACKUP;
+		memcpy(ec->c_i,ec->b_i,ec->N_d*sizeof(int));
+		memcpy(ec->b_i,ec->a_i,ec->N_d*sizeof(int));
+	} else
+		ec->backup--;
 
+
 	/* Update the Near-end hybrid signal circular buffers and accumulators */
 	/* ------------------------------------------------------------------- */
 	/* Delete the oldest sample from the power estimate accumulator */
@@ -415,6 +439,7 @@
 	    && (ec->max_y_tilde > 0))  {
 		/* Then start the Hangover counter */
 		ec->HCNTR_d = DEFAULT_HANGT;
+		RESTORE_COEFFS;
 #ifdef MEC2_STATS_DETAILED
 		printk(KERN_INFO "Reset near end speech timer with: s_tilde_i %d, stmnt %d, max_y_tilde %d\n", ec->s_tilde_i, (ec->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)), ec->max_y_tilde);
 #endif
@@ -437,6 +462,13 @@
 		!(ec->i_d % DEFAULT_M)) {		/* we only update on every DEFAULM_M'th sample from the stream */
   			if (ec->Lu_i > MIN_UPDATE_THRESH_I) {	/* there is sufficient energy above the noise floor to contain meaningful data */
   							/* so loop over all the filter coefficients */
+#ifdef USED_COEFFS
+				int max_coeffs[USED_COEFFS];
+				int *pos;
+
+				if (ec->N_d > USED_COEFFS)
+					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);
 #endif
@@ -453,7 +485,31 @@
 					/* eq. (7): update the coefficient */
 					ec->a_i[k] += grad2 / two_beta_i;
 					ec->a_s[k] = ec->a_i[k] >> 16;
+
+#ifdef USED_COEFFS
+					if (ec->N_d > USED_COEFFS) {
+						if (abs(ec->a_i[k]) > max_coeffs[USED_COEFFS-1]) {
+							/* More or less insertion-sort... */
+							pos = max_coeffs;
+							while (*pos > abs(ec->a_i[k]))
+								pos++;
+
+							if (*pos > max_coeffs[USED_COEFFS-1])
+								memmove(pos+1, pos, (USED_COEFFS-(pos-max_coeffs)-1)*sizeof(int));
+
+							*pos = abs(ec->a_i[k]);
+						}
+					}
+#endif
 				}
+
+#ifdef USED_COEFFS
+				/* Filter out irrelevant coefficients */
+				if (ec->N_d > USED_COEFFS)
+					for (k=0; k < ec->N_d; k++)
+						if (abs(ec->a_i[k]) < max_coeffs[USED_COEFFS-1])
+							ec->a_i[k] = ec->a_s[k] = 0;
+#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);
@@ -573,6 +629,8 @@
 									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 */
@@ -582,6 +640,8 @@
 									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 */
@@ -598,14 +658,20 @@
 	 */
 	ec->HCNTR_d = ec->N_d << 1;
 
-	if (pos >= ec->N_d)
+	if (pos >= ec->N_d) {
+		memcpy(ec->b_i,ec->a_i,ec->N_d*sizeof(int));
+		memcpy(ec->c_i,ec->a_i,ec->N_d*sizeof(int));
 		return 1;
+	}
 
 	ec->a_i[pos] = val << 17;
 	ec->a_s[pos] = val << 1;
 
-	if (++pos >= ec->N_d)
+	if (++pos >= ec->N_d) {
+		memcpy(ec->b_i,ec->a_i,ec->N_d*sizeof(int));
+		memcpy(ec->c_i,ec->a_i,ec->N_d*sizeof(int));
 		return 1;
+	}
 
 	return 0;
 }
Index: mg2ec_const.h
===================================================================
--- mg2ec_const.h	(revision 890)
+++ mg2ec_const.h	(working copy)
@@ -57,7 +57,23 @@
  #define RESIDUAL_SUPRESSION_PASSES 1
 #endif
 
+/* 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 */
 
