misdn.patch

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· PATCH 代码 · 共 2,345 行 · 第 1/5 页

PATCH
2,345
字号
+ */+#ifndef _MEC2_CONST_H+#define _MEC2_CONST_H+++/* Convergence speed -- higher means slower */+#define DEFAULT_BETA1_I 2048+#define DEFAULT_SIGMA_LY_I 7+#define DEFAULT_SIGMA_LU_I 7+#define DEFAULT_ALPHA_ST_I 5+#define DEFAULT_ALPHA_YT_I 5+#define DEFAULT_CUTOFF_I 128+#define DEFAULT_HANGT 600+#define DEFAULT_SUPPR_I 16+#define MIN_UPDATE_THRESH_I 4096+#define DEFAULT_M 16+#define SUPPR_FLOOR -64+#define SUPPR_CEIL -24+#define RES_SUPR_FACTOR -20+#define AGGRESSIVE_HCNTR 160	/* 20ms */++#endif /* _MEC2_CONST_H */+diff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/mec2.h mISDN/drivers/isdn/hardware/mISDN/mec2.h--- /tmp/mISDN/drivers/isdn/hardware/mISDN/mec2.h	1970-01-01 01:00:00.000000000 +0100+++ mISDN/drivers/isdn/hardware/mISDN/mec2.h	2005-12-02 09:57:08.000000000 +0100@@ -0,0 +1,409 @@+/*+ * Mark's Second Echo Canceller+ * + * Copyright (C) 2002, Digium, Inc.+ *+ * This program is free software and may be used and+ * distributed according to the terms of the GNU+ * General Public License, incorporated herein by+ * reference.+ *+ */+#ifndef _MARK2_ECHO_H+#define _MARK2_ECHO_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>+#include <math.h>+#define MALLOC(a) malloc(a)+#define FREE(a) free(a)+#endif++/* Get optimized routines for math */+#include "arith.h"++#ifndef NULL+#define NULL 0+#endif+#ifndef FALSE+#define FALSE 0+#endif+#ifndef TRUE+#define TRUE (!FALSE)+#endif++#include "mec2_const.h"++/* Circular buffer definition */+typedef struct {+  int idx_d;+  int size_d;+  short *buf_d;	/* Twice as large as we need */+} echo_can_cb_s;++// class definition+//+typedef struct  {+  /* Echo canceller definition */++  /* absolute time */+  int i_d;+  +  /* pre-computed constants */++  int N_d;+  int beta2_i;++  // declare accumulators for power computations+  //+  int Ly_i;+  int Lu_i;++  // declare an accumulator for the near-end signal detector+  //+  int s_tilde_i;+  int HCNTR_d;++  // circular buffers and coefficients+  //+  int *a_i;+  short *a_s;+  echo_can_cb_s y_s;+  echo_can_cb_s s_s;+  echo_can_cb_s u_s;+  echo_can_cb_s y_tilde_s;+  int y_tilde_i;++  /* Max memory */+  short max_y_tilde;+  int max_y_tilde_pos;++} echo_can_state_t;++static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)+{+	cb->buf_d = (short *)where;+	cb->idx_d = 0;+	cb->size_d = len;+}++static inline void add_cc_s(echo_can_cb_s *cb, short newval)+{+    /* Can't use modulus because N+M isn't a power of two (generally) */+    cb->idx_d--;+    if (cb->idx_d < (int)0)+     {cb->idx_d += cb->size_d;}+	/* Load two copies into memory */+	cb->buf_d[cb->idx_d] = newval;+	cb->buf_d[cb->idx_d + cb->size_d] = newval;+}++static inline short get_cc_s(echo_can_cb_s *cb, int pos)+{+	/* Load two copies into memory */+	return cb->buf_d[cb->idx_d + pos];+}++static inline void init_cc(echo_can_state_t *ec, int N, int maxy, int maxu) {++  void *ptr = ec;+  unsigned long tmp;+  /* double-word align past end of state */+  ptr += sizeof(echo_can_state_t);+  tmp = (unsigned long)ptr;+  tmp += 3;+  tmp &= ~3L;+  ptr = (void *)tmp;+  +  // reset parameters+  //+  ec->N_d = N;+  ec->beta2_i = DEFAULT_BETA1_I;+  +  // allocate coefficient memory+  //+  ec->a_i = ptr;+  ptr += (sizeof(int) * ec->N_d);+  ec->a_s = ptr;+  ptr += (sizeof(short) * ec->N_d);++  /* Reset Y circular buffer (short version) */+  init_cb_s(&ec->y_s, maxy, ptr);+  ptr += (sizeof(short) * (maxy) * 2);+  +  /* Reset Sig circular buffer (short version for FIR filter) */+  init_cb_s(&ec->s_s, (1 << DEFAULT_ALPHA_ST_I), ptr);+  ptr += (sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) * 2);++  init_cb_s(&ec->u_s, maxu, ptr);+  ptr += (sizeof(short) * maxu * 2);++  // allocate a buffer for the reference signal power computation+  //+  init_cb_s(&ec->y_tilde_s, ec->N_d, ptr);+++  // reset absolute time+  //+  ec->i_d = (int)0;+  +  // reset the power computations (for y and u)+  //+  ec->Ly_i = DEFAULT_CUTOFF_I;+  ec->Lu_i = DEFAULT_CUTOFF_I;++  // reset the near-end speech detector+  //+  ec->s_tilde_i = 0;+  ec->HCNTR_d = (int)0;++  // exit gracefully+  //+}++static inline void echo_can_free(echo_can_state_t *ec)+{+	FREE(ec);+}++static inline short echo_can_update(echo_can_state_t *ec, short iref, short isig) {++  /* declare local variables that are used more than once+  */+  int k;+  int rs;+  short u;+  int Py_i;+  int two_beta_i;+  +  /***************************************************************************+  //+  // flow A on pg. 428+  //+   ***************************************************************************/++  /* eq. (16): high-pass filter the input to generate the next value;+  //           push the current value into the circular buffer+  //+  // sdc_im1_d = sdc_d;+  // sdc_d = sig;+  //  s_i_d = sdc_d;+  //  s_d = s_i_d;+  //  s_i_d = (float)(1.0 - gamma_d) * s_i_d+     + (float)(0.5 * (1.0 - gamma_d)) * (sdc_d - sdc_im1_d); */+  +  +  /* Delete last sample from power estimate */+  ec->y_tilde_i -= abs(get_cc_s(&ec->y_s, (1 << DEFAULT_ALPHA_YT_I) - 1 )) >> DEFAULT_ALPHA_YT_I;+  /* push the reference data onto the circular buffer */+  add_cc_s(&ec->y_s, iref);+ +  /* eq. (2): compute r in fixed-point */+  rs = CONVOLVE2(ec->a_s, ec->y_s.buf_d + ec->y_s.idx_d, ec->N_d);+  rs >>= 15;++  /* eq. (3): compute the output value (see figure 3) and the error+  // note: the error is the same as the output signal when near-end+  // speech is not present+  */+  u = isig - rs;  +  +  add_cc_s(&ec->u_s, u);+  +++  /* Delete oldest part of received s_tilde */+  ec->s_tilde_i -= abs(get_cc_s(&ec->s_s, (1 << DEFAULT_ALPHA_ST_I) - 1 ));++  /* push the signal on the circular buffer, too */+  add_cc_s(&ec->s_s, isig);+  ec->s_tilde_i += abs(isig);+  ec->y_tilde_i += abs(iref) >> DEFAULT_ALPHA_YT_I;++  /* Add to our list of recent y_tilde's */+  add_cc_s(&ec->y_tilde_s, ec->y_tilde_i);		++  /****************************************************************************+  //+  // flow B on pg. 428+  // +   ****************************************************************************/+  +  /* compute the new convergence factor+  */+  Py_i = (ec->Ly_i >> DEFAULT_SIGMA_LY_I) * (ec->Ly_i >> DEFAULT_SIGMA_LY_I);+  Py_i >>= 15;+  if (ec->HCNTR_d > 0) {+  	Py_i = (1 << 15);+  }+  +#if 0+  printf("Py: %e, Py_i: %e\n", Py, Py_i * AMPL_SCALE_1);+#endif  ++  /* Vary rate of adaptation depending on position in the file+  // Do not do this for the first (DEFAULT_UPDATE_TIME) secs after speech+  // has begun of the file to allow the echo cancellor to estimate the+  // channel accurately+  */+#if 0+  if (ec->start_speech_d != 0 ){+    if ( ec->i_d > (DEFAULT_T0 + ec->start_speech_d)*(SAMPLE_FREQ) ){+      ec->beta2_d = max_cc_float(MIN_BETA,+		       DEFAULT_BETA1 * exp((-1/DEFAULT_TAU)*((ec->i_d/(float)SAMPLE_FREQ) -+						 DEFAULT_T0 -+						 ec->start_speech_d)));+    }+  }+  else {ec->beta2_d = DEFAULT_BETA1;}+#endif+  +  ec->beta2_i = DEFAULT_BETA1_I;	/* Fixed point, inverted */+  +  two_beta_i = (ec->beta2_i * Py_i) >> 15;	/* Fixed point version, inverted */+  if (!two_beta_i)+  	two_beta_i++;++  /* Update Lu_i (Suppressed power estimate) */+  ec->Lu_i -= abs(get_cc_s(&ec->u_s, (1 << DEFAULT_SIGMA_LU_I) - 1 )) ;+  ec->Lu_i += abs(u);++  /* eq. (10): update power estimate of the reference+  */+  ec->Ly_i -= abs(get_cc_s(&ec->y_s, (1 << DEFAULT_SIGMA_LY_I) - 1)) ;+  ec->Ly_i += abs(iref);++  if (ec->Ly_i < DEFAULT_CUTOFF_I)+  	ec->Ly_i = DEFAULT_CUTOFF_I;++#if 0+  printf("Float: %e, Int: %e\n", ec->Ly_d, (ec->Ly_i >> DEFAULT_SIGMA_LY_I) * AMPL_SCALE_1);+#endif+  +  if (ec->y_tilde_i > ec->max_y_tilde) {+  	/* New highest y_tilde with full life */+	ec->max_y_tilde = ec->y_tilde_i;+	ec->max_y_tilde_pos = ec->N_d - 1;+  } else if (--ec->max_y_tilde_pos < 0) {+    /* Time to find new max y tilde... */+	ec->max_y_tilde = MAX16(ec->y_tilde_s.buf_d + ec->y_tilde_s.idx_d, ec->N_d, &ec->max_y_tilde_pos);+  }++  if ((ec->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)) > ec->max_y_tilde)+    {+      ec->HCNTR_d = DEFAULT_HANGT;+    }+  else if (ec->HCNTR_d > (int)0)+    {+      ec->HCNTR_d--;+    }++  /* update coefficients if no near-end speech and we have enough signal+   * to bother trying to update.+  */+  if (!ec->HCNTR_d && !(ec->i_d % DEFAULT_M) && +      (ec->Lu_i > MIN_UPDATE_THRESH_I)) {+	    // loop over all filter coefficients+	    //+	    for (k=0; k<ec->N_d; k++) {+	      +	      // eq. (7): compute an expectation over M_d samples +	      //+		  int grad2;+	      grad2 = CONVOLVE2(ec->u_s.buf_d + ec->u_s.idx_d,+		  					ec->y_s.buf_d + ec->y_s.idx_d + k, DEFAULT_M);+	      // eq. (7): update the coefficient+	      //+	      ec->a_i[k] += grad2 / two_beta_i;+		  ec->a_s[k] = ec->a_i[k] >> 16;+	    }+  }++  /* paragraph below eq. (15): if no near-end speech,+  // check for residual error suppression+  */+#ifndef NO_ECHO_SUPPRESSOR+#ifdef AGGRESSIVE_SUPPRESSOR+  if ((ec->HCNTR_d < AGGRESSIVE_HCNTR) && (ec->Ly_i > (ec->Lu_i << 1))) {+ 	u = u * (ec->Lu_i >> DEFAULT_SIGMA_LU_I) / ((ec->Ly_i >> (DEFAULT_SIGMA_LY_I)) + 1);+ 	u = u * (ec->Lu_i >> DEFAULT_SIGMA_LU_I) / ((ec->Ly_i >> (DEFAULT_SIGMA_LY_I)) + 1);+  }+#else	+  if ((ec->HCNTR_d == 0) && ((ec->Ly_i/(ec->Lu_i + 1)) > DEFAULT_SUPPR_I)) {+  	u = u * (ec->Lu_i >> DEFAULT_SIGMA_LU_I) / ((ec->Ly_i >> (DEFAULT_SIGMA_LY_I + 2)) + 1);+  }+#endif	+#endif  ++#if 0+  if ((ec->HCNTR_d == 0) && ((ec->Lu_d/ec->Ly_d) < DEFAULT_SUPPR) &&+      (ec->Lu_d/ec->Ly_d > EC_MIN_DB_VALUE)) { +    suppr_factor = (10/(float)(SUPPR_FLOOR-SUPPR_CEIL))*log(ec->Lu_d/ec->Ly_d)+      - SUPPR_CEIL/(float)(SUPPR_FLOOR - SUPPR_CEIL);++    u_suppr = pow(10.0,(suppr_factor)*RES_SUPR_FACTOR/10.0)*u_suppr;+    +  }+#endif  +  ec->i_d++;+  return u;+}++static inline echo_can_state_t *echo_can_create(int len, int adaption_mode)+{+	echo_can_state_t *ec;+	int maxy;+	int maxu;+	maxy = len + DEFAULT_M;+	maxu = DEFAULT_M;+	if (maxy < (1 << DEFAULT_ALPHA_YT_I))+		maxy = (1 << DEFAULT_ALPHA_YT_I);+	if (maxy < (1 << DEFAULT_SIGMA_LY_I))+		maxy = (1 << DEFAULT_SIGMA_LY_I);+	if (maxu < (1 << DEFAULT_SIGMA_LU_I))+		maxu = (1 << DEFAULT_SIGMA_LU_I);+	ec = (echo_can_state_t *)MALLOC(sizeof(echo_can_state_t) ++									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(echo_can_state_t) ++									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;+}++static inline int echo_can_traintap(echo_can_state_t *ec, int pos, short val)+{+	/* Reset hang counter to avoid adjustments after+	   initial forced training */+	ec->HCNTR_d = ec->N_d << 1;+	if (pos >= ec->N_d)+		return 1;+	ec->a_i[pos] = val << 17;+	ec->a_s[pos] = val << 1;+	if (++pos >= ec->N_d)+		return 1;+	return 0;+}++#endifdiff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/mec3.h mISDN/drivers/isdn/hardware/mISDN/mec3.h--- /tmp/mISDN/drivers/isdn/hardware/mISDN/mec3.h	1970-01-01 01:00:00.000000000 +0100+++ mISDN/drivers/isdn/hardware/mISDN/mec3.h	2005-12-02 09:57:08.000000000 +0100@@ -0,0 +1,243 @@+/*+ * Mark's Third Echo Canceller+ *+ * Copyright (C) 2003, Digium, Inc.+ *+ * This program is free software and may be used+ * and distributed under the terms of the GNU General Public + * License, incorporated herein by reference.  + *+ * Dedicated to the crew of the Columbia, STS-107 for their+ * bravery and courageous sacrifice for science.+ *+ */++#ifndef _MARK3_ECHO_H+#define _MARK3_ECHO_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>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?