www.pudn.com > fast.zip > cancel.C


/* Modem for MIPS   AJF	  October 1996 
   Echo canceller routines */ 
 
#include  
#include  
#include 	/* memset */ 
 
#include  
#include  
 
#include "modem.h" 
#include "cancel.h" 
 
 
void canceller::reset() 
  { memset(coeffs, 0, ncs * sizeof(complex)); 
    memset(in, 0, size * sizeof(complex)); 
    next = 0; 
  } 
 
void canceller::insert(complex z) 
  { /* circular buffer */ 
    in[next] = z; 
    if (++next >= size) next = 0; 
  } 
 
complex canceller::get() 
  { /* get predicted echo value */ 
    complex z = 0.0; 
    int j = 0; 
    int k = size + ebeg - TRDELAY; 
    while (j < ncs) 
      { int p = (next+k) & (size-1); 
	z += coeffs[j] * in[p]; 
	j++; k += SYMBLEN/2; 
      } 
    return z; 
  } 
 
void canceller::update(complex eps) 
  { complex deps = (delta / (float) ncs) * eps; 
    int j = 0; 
    int k = size + ebeg - TRDELAY; 
    while (j < ncs) 
      { int p = (next+k) & (size-1); 
	coeffs[j] += deps * cconj(in[p]); 
	j++; k += SYMBLEN/2; 
      } 
  } 
 
inline float hypot(complex z) 
  { return hypot(z.im, z.re); 
  } 
 
inline float atan2(complex z) 
  { return atan2(z.im, z.re); 
  } 
 
void canceller::print(char *fn) 
  { FILE *fi = fopen(fn, "w"); 
    if (fi != NULL) 
      { int spc = SYMBLEN/2; 
	fprintf(fi, ".sp 0.5i\n"); 
	fprintf(fi, ".G1 8i\n"); 
	fprintf(fi, "new solid\n"); 
	for (int j=0; j < ncs; j++) fprintf(fi, "%4d %g\n", ebeg + (j*spc), coeffs[j].re); 
	fprintf(fi, ".G2\n.bp\n"); 
	fprintf(fi, ".sp 0.5i\n.G1 8i\n"); 
	fprintf(fi, "new solid\n"); 
	for (int j=0; j < ncs; j++) fprintf(fi, "%4d %g\n", ebeg + (j*spc), coeffs[j].im); 
	fprintf(fi, ".G2\n.bp\n"); 
	fprintf(fi, ".sp 0.5i\n.G1 8i\n"); 
	fprintf(fi, "new solid\n"); 
	for (int j=0; j < ncs; j++) fprintf(fi, "%4d %g\n", ebeg + (j*spc), hypot(coeffs[j])); 
	fprintf(fi, ".G2\n.bp\n"); 
	fprintf(fi, ".sp 0.5i\n.G1 8i\n"); 
	fprintf(fi, "new solid\n"); 
	for (int j=0; j < ncs; j++) fprintf(fi, "%4d %g\n", ebeg + (j*spc), atan2(coeffs[j])); 
	fprintf(fi, ".G2\n.bp\n"); 
	fprintf(fi, ".sp 0.5i\n"); 
	for (int j=0; j < ncs; j++) fprintf(fi, "{ %10.6f, %10.6f },\n", coeffs[j].re, coeffs[j].im); 
	fclose(fi); 
      } 
    else fprintf(stderr, "can't create %s\n", fn); 
  }