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 Lesser General Public License version 2.1, 00015 * as 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 Lesser General Public 00023 * License 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.14 2008/04/02 12:41:19 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 Modem connect 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 up 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. This is the echo 00042 canceller disable tone. 00043 00044 The tone detector's design assumes the channel is free of any DC component. 00045 00046 \section modem_connect_tones_page_sec_2 How does it work? 00047 A sharp notch filter is implemented as a single bi-quad section. The presence of 00048 the 2100Hz disable tone is detected by comparing the notched filtered energy 00049 with the unfiltered energy. If the notch filtered energy is much lower than the 00050 unfiltered energy, then a large proportion of the energy must be at the notch 00051 frequency. This type of detector may seem less intuitive than using a narrow 00052 bandpass filter to isolate the energy at the notch freqency. However, a sharp 00053 bandpass implemented as an IIR filter rings badly. The reciprocal notch filter 00054 is very well behaved. 00055 */ 00056 00057 enum 00058 { 00059 MODEM_CONNECT_TONES_FAX_CNG, 00060 MODEM_CONNECT_TONES_FAX_CED, 00061 MODEM_CONNECT_TONES_EC_DISABLE, 00062 /*! \brief The version of EC disable with some 15Hz AM content, as in V.8 */ 00063 MODEM_CONNECT_TONES_EC_DISABLE_MOD, 00064 }; 00065 00066 /*! 00067 Modem connect tones generator descriptor. This defines the state 00068 of a single working instance of the tone generator. 00069 */ 00070 typedef struct 00071 { 00072 int tone_type; 00073 00074 tone_gen_state_t tone_tx; 00075 uint32_t tone_phase; 00076 int32_t tone_phase_rate; 00077 int level; 00078 /*! \brief Countdown to the next phase hop */ 00079 int hop_timer; 00080 uint32_t mod_phase; 00081 int32_t mod_phase_rate; 00082 int mod_level; 00083 } modem_connect_tones_tx_state_t; 00084 00085 /*! 00086 Modem connect tones receiver descriptor. This defines the state 00087 of a single working instance of the tone detector. 00088 */ 00089 typedef struct 00090 { 00091 /*! \brief The tone type being detected. */ 00092 int tone_type; 00093 /*! \brief Callback routine, using to report detection of the tone. */ 00094 tone_report_func_t tone_callback; 00095 /*! \brief An opaque pointer passed to tone_callback. */ 00096 void *callback_data; 00097 00098 /*! \brief The notch filter state. */ 00099 float z1; 00100 float z2; 00101 /*! \brief The in notch power estimate */ 00102 int notch_level; 00103 /*! \brief The total channel power estimate */ 00104 int channel_level; 00105 /*! \brief TRUE is the tone is currently confirmed present in the audio. */ 00106 int tone_present; 00107 int tone_on; 00108 /*! \brief A sample counter, to time the duration of tone sections. */ 00109 int tone_cycle_duration; 00110 /*! \brief A count of the number of good cycles of tone reversal seen. */ 00111 int good_cycles; 00112 /*! \brief TRUE if the tone has been seen since the last time the user tested for it */ 00113 int hit; 00114 /*! \brief A V.21 FSK modem context used when searching for FAX preamble. */ 00115 fsk_rx_state_t v21rx; 00116 /*! \brief The raw (stuffed) bit stream buffer. */ 00117 unsigned int raw_bit_stream; 00118 /*! \brief The current number of bits in the octet in progress. */ 00119 int num_bits; 00120 /*! \brief Number of consecutive flags seen so far. */ 00121 int flags_seen; 00122 /*! \brief TRUE if framing OK has been announced. */ 00123 int framing_ok_announced; 00124 } modem_connect_tones_rx_state_t; 00125 00126 #if defined(__cplusplus) 00127 extern "C" 00128 { 00129 #endif 00130 00131 /*! \brief Initialise an instance of the modem connect tones generator. 00132 \param s The context. 00133 */ 00134 modem_connect_tones_tx_state_t *modem_connect_tones_tx_init(modem_connect_tones_tx_state_t *s, 00135 int tone_type); 00136 00137 /*! \brief Free an instance of the modem connect tones generator. 00138 \param s The context. 00139 \return 0 for OK, else -1. 00140 */ 00141 int modem_connect_tones_tx_free(modem_connect_tones_tx_state_t *s); 00142 00143 /*! \brief Generate a block of modem connect tones samples. 00144 \param s The context. 00145 \param amp An array of signal samples. 00146 \param len The number of samples to generate. 00147 \return The number of samples generated. 00148 */ 00149 int modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, 00150 int16_t amp[], 00151 int len); 00152 00153 /*! \brief Process a block of samples through an instance of the modem connect 00154 tones detector. 00155 \param s The context. 00156 \param amp An array of signal samples. 00157 \param len The number of samples in the array. 00158 \return The number of unprocessed samples. 00159 */ 00160 int modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, 00161 const int16_t amp[], 00162 int len); 00163 00164 /*! \brief Test if a modem_connect tone has been detected. 00165 \param s The context. 00166 \return TRUE if tone is detected, else FALSE. 00167 */ 00168 int modem_connect_tones_rx_get(modem_connect_tones_rx_state_t *s); 00169 00170 /*! \brief Initialise an instance of the modem connect tones detector. 00171 \param s The context. 00172 \param tone_type The type of connect tone being tested for. 00173 \param tone_callback An optional callback routine, used to report tones 00174 \param user_data An opaque pointer passed to the callback routine, 00175 \return A pointer to the context. 00176 */ 00177 modem_connect_tones_rx_state_t *modem_connect_tones_rx_init(modem_connect_tones_rx_state_t *s, 00178 int tone_type, 00179 tone_report_func_t tone_callback, 00180 void *user_data); 00181 00182 /*! \brief Free an instance of the modem connect tones detector. 00183 \param s The context. 00184 \return 0 for OK, else -1. */ 00185 int modem_connect_tones_rx_free(modem_connect_tones_rx_state_t *s); 00186 00187 #if defined(__cplusplus) 00188 } 00189 #endif 00190 00191 #endif 00192 /*- End of file ------------------------------------------------------------*/