/*1* SpanDSP - a series of DSP components for telephony2*3* ec_disable_detector.h - A detector which should eventually meet the4* G.164/G.165 requirements for detecting the5* 2100Hz echo cancellor disable tone.6*7* Written by Steve Underwood <[email protected]>8*9* Copyright (C) 2001 Steve Underwood10*11* All rights reserved.12*13* This program is free software; you can redistribute it and/or modify14* it under the terms of the GNU General Public License as published by15* the Free Software Foundation; either version 2 of the License, or16* (at your option) any later version.17*18* This program is distributed in the hope that it will be useful,19* but WITHOUT ANY WARRANTY; without even the implied warranty of20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the21* GNU General Public License for more details.22*23* You should have received a copy of the GNU General Public License24* along with this program; if not, write to the Free Software25* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.26*27*/2829#include "dsp_biquad.h"3031struct ec_disable_detector_state {32struct biquad2_state notch;33int notch_level;34int channel_level;35int tone_present;36int tone_cycle_duration;37int good_cycles;38int hit;39};404142#define FALSE 043#define TRUE (!FALSE)4445static inline void46echo_can_disable_detector_init(struct ec_disable_detector_state *det)47{48/* Elliptic notch */49/* This is actually centred at 2095Hz, but gets the balance we want, due50to the asymmetric walls of the notch */51biquad2_init(&det->notch,52(int32_t) (-0.7600000*32768.0),53(int32_t) (-0.1183852*32768.0),54(int32_t) (-0.5104039*32768.0),55(int32_t) (0.1567596*32768.0),56(int32_t) (1.0000000*32768.0));5758det->channel_level = 0;59det->notch_level = 0;60det->tone_present = FALSE;61det->tone_cycle_duration = 0;62det->good_cycles = 0;63det->hit = 0;64}65/*- End of function --------------------------------------------------------*/6667static inline int68echo_can_disable_detector_update(struct ec_disable_detector_state *det,69int16_t amp)70{71int16_t notched;7273notched = biquad2(&det->notch, amp);74/* Estimate the overall energy in the channel, and the energy in75the notch (i.e. overall channel energy - tone energy => noise).76Use abs instead of multiply for speed (is it really faster?).77Damp the overall energy a little more for a stable result.78Damp the notch energy a little less, so we don't damp out the79blip every time the phase reverses */80det->channel_level += ((abs(amp) - det->channel_level) >> 5);81det->notch_level += ((abs(notched) - det->notch_level) >> 4);82if (det->channel_level > 280) {83/* There is adequate energy in the channel.84Is it mostly at 2100Hz? */85if (det->notch_level*6 < det->channel_level) {86/* The notch says yes, so we have the tone. */87if (!det->tone_present) {88/* Do we get a kick every 450+-25ms? */89if (det->tone_cycle_duration >= 425*890&& det->tone_cycle_duration <= 475*8) {91det->good_cycles++;92if (det->good_cycles > 2)93det->hit = TRUE;94}95det->tone_cycle_duration = 0;96}97det->tone_present = TRUE;98} else99det->tone_present = FALSE;100det->tone_cycle_duration++;101} else {102det->tone_present = FALSE;103det->tone_cycle_duration = 0;104det->good_cycles = 0;105}106return det->hit;107}108/*- End of function --------------------------------------------------------*/109/*- End of file ------------------------------------------------------------*/110111112