From 9762f08c3e05e28570a32b94f6004136f464d22f Mon Sep 17 00:00:00 2001 From: mattf Date: Wed, 28 Dec 2005 20:28:28 +0000 Subject: Updating MG2 to latest set of tweaks and optimizatons. See bug #5520 for more details on changes. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@878 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- mg2ec.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 9 deletions(-) (limited to 'mg2ec.h') diff --git a/mg2ec.h b/mg2ec.h index e08adaf..03bb56b 100644 --- a/mg2ec.h +++ b/mg2ec.h @@ -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;xN_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 @@ struct echo_can_state { 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 @@ struct echo_can_state { #endif short lastsig[256]; int lastpos; + int backup; }; @@ -193,6 +206,12 @@ static inline void init_cc(struct echo_can_state *ec, int N, int maxy, int maxu) 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 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short 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,6 +346,14 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short /* 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 */ /* ------------------------------------------------------------------- */ @@ -415,6 +439,7 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short && (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,9 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short !(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 FILTER_PERCENT + int max = 0, max2 = 0; +#endif #ifdef MEC2_STATS_DETAILED printk( KERN_INFO "updating coefficients with: ec->Lu_i %9d\n", ec->Lu_i); #endif @@ -453,7 +481,23 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short /* eq. (7): update the coefficient */ ec->a_i[k] += grad2 / two_beta_i; ec->a_s[k] = ec->a_i[k] >> 16; + +#ifdef FILTER_PERCENT + /* Find the peaks */ + if (abs(ec->a_i[k]) > max) + { + max2 = max; + max = abs(ec->a_i[k]); + } +#endif } + +#ifdef FILTER_PERCENT + /* Filter out irrelevant coefficients */ + for (k=0; k < ec->N_d; k++) + if (abs(ec->a_i[k]) < (max2*FILTER_PERCENT)/100) + 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 +617,8 @@ static inline struct echo_can_state *echo_can_create(int len, int adaption_mode) 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 +628,8 @@ static inline struct echo_can_state *echo_can_create(int len, int adaption_mode) 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 +646,20 @@ static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short va */ 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; } -- cgit v1.2.3