00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * modem_connect_tones.c - Generation and detection of tones 00005 * associated with modems calling and answering calls. 00006 * 00007 * Written by Steve Underwood <steveu@coppice.org> 00008 * 00009 * Copyright (C) 2006 Steve Underwood 00010 * 00011 * All rights reserved. 00012 * 00013 * This program is free software; you can redistribute it and/or modify 00014 * it under the terms of the GNU General Public License version 2, as 00015 * published by the Free Software Foundation. 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with this program; if not, write to the Free Software 00024 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00025 * 00026 * $Id: modem_connect_tones.h,v 1.11 2007/12/13 11:31:32 steveu Exp $ 00027 */ 00028 00029 /*! \file */ 00030 00031 #if !defined(_SPANDSP_MODEM_CONNECT_TONES_H_) 00032 #define _SPANDSP_MODEM_CONNECT_TONES_H_ 00033 00034 /*! \page modem_connect_tones_page Echo cancellor disable tone detection 00035 00036 \section modem_connect_tones_page_sec_1 What does it do? 00037 Some telephony terminal equipment, such as modems, require a channel which is as 00038 clear as possible. They use their own echo cancellation. If the network is also 00039 performing echo cancellation the two cancellors can end of squabbling about the 00040 nature of the channel, with bad results. A special tone is defined which should 00041 cause the network to disable any echo cancellation processes. 00042 00043 \section modem_connect_tones_page_sec_2 How does it work? 00044 A sharp notch filter is implemented as a single bi-quad section. The presence of 00045 the 2100Hz disable tone is detected by comparing the notched filtered energy 00046 with the unfiltered energy. If the notch filtered energy is much lower than the 00047 unfiltered energy, then a large proportion of the energy must be at the notch 00048 frequency. This type of detector may seem less intuitive than using a narrow 00049 bandpass filter to isolate the energy at the notch freqency. However, a sharp 00050 bandpass implemented as an IIR filter rings badly, The reciprocal notch filter 00051 is very well behaved. 00052 */ 00053 00054 enum 00055 { 00056 MODEM_CONNECT_TONES_FAX_CNG, 00057 MODEM_CONNECT_TONES_FAX_CED, 00058 MODEM_CONNECT_TONES_EC_DISABLE, 00059 /*! \brief The version of EC disable with some 15Hz AM content, as in V.8 */ 00060 MODEM_CONNECT_TONES_EC_DISABLE_MOD, 00061 }; 00062 00063 /*! 00064 Modem connect tones generator descriptor. This defines the state 00065 of a single working instance of the tone generator. 00066 */ 00067 typedef struct 00068 { 00069 int tone_type; 00070 00071 tone_gen_state_t tone_tx; 00072 uint32_t tone_phase; 00073 int32_t tone_phase_rate; 00074 int level; 00075 /*! \brief Countdown to the next phase hop */ 00076 int hop_timer; 00077 uint32_t mod_phase; 00078 int32_t mod_phase_rate; 00079 int mod_level; 00080 } modem_connect_tones_tx_state_t; 00081 00082 /*! 00083 Modem connect tones receiver descriptor. This defines the state 00084 of a single working instance of the tone detector. 00085 */ 00086 typedef struct 00087 { 00088 /*! \brief The tone type being detected. */ 00089 int tone_type; 00090 /*! \brief Callback routine, using to report detection of the tone. */ 00091 tone_report_func_t tone_callback; 00092 /*! \brief An opaque pointer passed to tone_callback. */ 00093 void *callback_data; 00094 00095 float z1; 00096 float z2; 00097 int notch_level; 00098 int channel_level; 00099 /*! \brief TRUE is the tone is currently present in the audio. */ 00100 int tone_present; 00101 int tone_cycle_duration; 00102 int good_cycles; 00103 int hit; 00104 /*! \brief A V.21 FSK modem context used when searching for FAX preamble. */ 00105 fsk_rx_state_t v21rx; 00106 int one_zero_weight[2]; 00107 int odd_even; 00108 /*! \brief TRUE if V.21 HDLC preamble is being detected. */ 00109 int preamble_on; 00110 } modem_connect_tones_rx_state_t; 00111 00112 #if defined(__cplusplus) 00113 extern "C" 00114 { 00115 #endif 00116 00117 /*! \brief Initialise an instance of the modem connect tones generator. 00118 \param s The context. 00119 */ 00120 modem_connect_tones_tx_state_t *modem_connect_tones_tx_init(modem_connect_tones_tx_state_t *s, 00121 int tone_type); 00122 00123 /*! \brief Free an instance of the modem connect tones generator. 00124 \param s The context. 00125 \return 0 for OK, else -1. 00126 */ 00127 int modem_connect_tones_tx_free(modem_connect_tones_tx_state_t *s); 00128 00129 /*! \brief Generate a block of modem connect tones samples. 00130 \param s The context. 00131 \param amp An array of signal samples. 00132 \param len The number of samples to generate. 00133 \return The number of samples generated. 00134 */ 00135 int modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, 00136 int16_t amp[], 00137 int len); 00138 00139 /*! \brief Process a block of samples through an instance of the modem connect 00140 tones detector. 00141 \param s The context. 00142 \param amp An array of signal samples. 00143 \param len The number of samples in the array. 00144 \return The number of unprocessed samples. 00145 */ 00146 int modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, 00147 const int16_t amp[], 00148 int len); 00149 00150 /*! \brief Test if a modem_connect tone has been detected. 00151 \param s The context. 00152 \return TRUE if tone is detected, else FALSE. 00153 */ 00154 int modem_connect_tones_rx_get(modem_connect_tones_rx_state_t *s); 00155 00156 /*! \brief Initialise an instance of the modem connect tones detector. 00157 \param s The context. 00158 \param tone_type The type of connect tone being tested for. 00159 \param tone_callback An optional callback routine, used to report tones 00160 \param user_data An opaque pointer passed to the callback routine, 00161 \return A pointer to the context. 00162 */ 00163 modem_connect_tones_rx_state_t *modem_connect_tones_rx_init(modem_connect_tones_rx_state_t *s, 00164 int tone_type, 00165 tone_report_func_t tone_callback, 00166 void *user_data); 00167 00168 /*! \brief Free an instance of the modem connect tones detector. 00169 \param s The context. 00170 \return 0 for OK, else -1. */ 00171 int modem_connect_tones_rx_free(modem_connect_tones_rx_state_t *s); 00172 00173 #if defined(__cplusplus) 00174 } 00175 #endif 00176 00177 #endif 00178 /*- End of file ------------------------------------------------------------*/