int AEC::doAEC(int d, int x) { // Mic Highpass Filter - to remove DC d = acMic.highpass(d); // Mic Highpass Filter - cut-off below 300Hz d = cutoff.highpass(d); // Amplify, for e.g. Soundcards with -6dB max. volume d = (gain * d) / 65536; // ambient mic level estimation micAvg += (labs(65536 * d) - micAvg) / 10000; // Spk Highpass Filter - to remove DC x = acSpk.highpass(x); // Double Talk Detector int update = !dtd(d, x); // Acoustic Echo Cancellation d = nlms_pw(d, x, update); // Acoustic Echo Suppression if (update) { // Non Linear Processor (NLP): attenuate low volumes // NLPAttenuation -6dB = d * 0.5 or d / 2 d /= 2; } return d; }
/* This function is expected to update the samples in sb to remove echo - once * it completes, they are ready to go out the tx side of the hybrid */ void echo_update_tx(echo *e, SAMPLE_BLOCK *sb) { size_t i; int any_doubletalk = 0; for (i=0; i<sb->count; i++) { SAMPLE rx_s, tx_s; float tx, rx; rx_s = cbuffer_pop(e->rx_buf); tx_s = sb->s[i]; tx = (float)tx_s; rx = (float)rx_s; /* High-pass filter - filter out sub-300Hz signals */ tx = update_fir(e->hp, tx); /* Geigel double-talk detector */ int update = !dtd(e, tx); /* nlms-pw */ tx = nlms_pw(e, tx, rx, update); /* If we're not talking, let's attenuate our signal */ if (update) { tx *= M12dB; } else { any_doubletalk = 1; } /* clipping */ tx = clip(tx); sb->s[i] = (int)tx; } VERBOSE_LOG("%s\n", any_doubletalk ? "doubletalk" : " "); }
int AEC::doAEC(int d, int x) { REAL s0 = (REAL)d; REAL s1 = (REAL)x; // Mic Highpass Filter - to remove DC s0 = hp00.highpass(s0); // Mic Highpass Filter - telephone users are used to 300Hz cut-off s0 = hp0.highpass(s0); // ambient mic level estimation s0avg += 1e-4f*(fabsf(s0) - s0avg); // Spk Highpass Filter - to remove DC s1 = hp1.highpass(s1); // Double Talk Detector int update = !dtd(s0, s1); // Acoustic Echo Cancellation s0 = nlms_pw(s0, s1, update); // Acoustic Echo Suppression if (update) { // Non Linear Processor (NLP): attenuate low volumes s0 *= NLPAttenuation; } // Saturation if (s0 > MAXPCM) { return (int)MAXPCM; } else if (s0 < -MAXPCM) { return (int)-MAXPCM; } else { return (int)(s0); } }