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 Lesser 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 5963 2008-07-27 13:06:19Z oron $ 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 for our purpose. 00055 */ 00056 00057 enum 00058 { 00059 MODEM_CONNECT_TONES_NONE = 0, 00060 /*! \brief CNG tone is a pure 1100Hz tone, in 0.5s bursts, with 3s silences in between. The 00061 bursts repeat for as long as is required. */ 00062 MODEM_CONNECT_TONES_FAX_CNG = 1, 00063 /*! \brief CED tone is a pure continuous 2100Hz+-15Hz tone for 3.3s+-0.7s. We might see FAX preamble 00064 instead of CED, of the FAX machine does not answer with CED. */ 00065 MODEM_CONNECT_TONES_FAX_CED = 2, 00066 /*! \brief ANS tone is a pure continuous 2100Hz+-15Hz tone for 3.3s+-0.7s. Nothing else is searched for. */ 00067 MODEM_CONNECT_TONES_ANS = 3, 00068 /*! \brief ANS with phase reversals tone is a 2100Hz+-15Hz tone for 3.3s+-0.7s, with a 180 degree phase 00069 jump every 450ms+-25ms. */ 00070 MODEM_CONNECT_TONES_ANS_PR = 4, 00071 /*! \brief The ANSam tone is a version of ANS with 20% of 15Hz+-0.1Hz AM modulation, as per V.8 */ 00072 MODEM_CONNECT_TONES_ANSAM = 5, 00073 /*! \brief The ANSam with phase reversals tone is a version of ANS_PR with 20% of 15Hz+-0.1Hz AM modulation, 00074 as per V.8 */ 00075 MODEM_CONNECT_TONES_ANSAM_PR = 6, 00076 /*! \brief FAX preamble in a string of V.21 HDLC flag octets. This is only valid as a result of tone 00077 detection. It should not be specified as a tone type to transmit or receive. */ 00078 MODEM_CONNECT_TONES_FAX_PREAMBLE = 7 00079 }; 00080 00081 /*! 00082 Modem connect tones generator descriptor. This defines the state 00083 of a single working instance of the tone generator. 00084 */ 00085 typedef struct 00086 { 00087 int tone_type; 00088 00089 int32_t tone_phase_rate; 00090 uint32_t tone_phase; 00091 int level; 00092 /*! \brief Countdown to the next phase hop */ 00093 int hop_timer; 00094 /*! \brief Maximum duration timer */ 00095 int duration_timer; 00096 uint32_t mod_phase; 00097 int32_t mod_phase_rate; 00098 int mod_level; 00099 } modem_connect_tones_tx_state_t; 00100 00101 /*! 00102 Modem connect tones receiver descriptor. This defines the state 00103 of a single working instance of the tone detector. 00104 */ 00105 typedef struct 00106 { 00107 /*! \brief The tone type being detected. */ 00108 int tone_type; 00109 /*! \brief Callback routine, using to report detection of the tone. */ 00110 tone_report_func_t tone_callback; 00111 /*! \brief An opaque pointer passed to tone_callback. */ 00112 void *callback_data; 00113 00114 /*! \brief The notch filter state. */ 00115 float z1; 00116 float z2; 00117 /*! \brief The in notch power estimate */ 00118 int notch_level; 00119 /*! \brief The total channel power estimate */ 00120 int channel_level; 00121 /*! \brief Sample counter for the small chunks of samples, after which a test is conducted. */ 00122 int chunk_remainder; 00123 /*! \brief TRUE is the tone is currently confirmed present in the audio. */ 00124 int tone_present; 00125 /*! \brief */ 00126 int tone_on; 00127 /*! \brief A millisecond counter, to time the duration of tone sections. */ 00128 int tone_cycle_duration; 00129 /*! \brief A count of the number of good cycles of tone reversal seen. */ 00130 int good_cycles; 00131 /*! \brief TRUE if the tone has been seen since the last time the user tested for it */ 00132 int hit; 00133 /*! \brief A V.21 FSK modem context used when searching for FAX preamble. */ 00134 fsk_rx_state_t v21rx; 00135 /*! \brief The raw (stuffed) bit stream buffer. */ 00136 unsigned int raw_bit_stream; 00137 /*! \brief The current number of bits in the octet in progress. */ 00138 int num_bits; 00139 /*! \brief Number of consecutive flags seen so far. */ 00140 int flags_seen; 00141 /*! \brief TRUE if framing OK has been announced. */ 00142 int framing_ok_announced; 00143 } modem_connect_tones_rx_state_t; 00144 00145 #if defined(__cplusplus) 00146 extern "C" 00147 { 00148 #endif 00149 00150 /*! \brief Initialise an instance of the modem connect tones generator. 00151 \param s The context. 00152 */ 00153 modem_connect_tones_tx_state_t *modem_connect_tones_tx_init(modem_connect_tones_tx_state_t *s, 00154 int tone_type); 00155 00156 /*! \brief Free an instance of the modem connect tones generator. 00157 \param s The context. 00158 \return 0 for OK, else -1. 00159 */ 00160 int modem_connect_tones_tx_free(modem_connect_tones_tx_state_t *s); 00161 00162 /*! \brief Generate a block of modem connect tones samples. 00163 \param s The context. 00164 \param amp An array of signal samples. 00165 \param len The number of samples to generate. 00166 \return The number of samples generated. 00167 */ 00168 int modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, 00169 int16_t amp[], 00170 int len); 00171 00172 /*! \brief Process a block of samples through an instance of the modem connect 00173 tones detector. 00174 \param s The context. 00175 \param amp An array of signal samples. 00176 \param len The number of samples in the array. 00177 \return The number of unprocessed samples. 00178 */ 00179 int modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, 00180 const int16_t amp[], 00181 int len); 00182 00183 /*! \brief Test if a modem_connect tone has been detected. 00184 \param s The context. 00185 \return TRUE if tone is detected, else FALSE. 00186 */ 00187 int modem_connect_tones_rx_get(modem_connect_tones_rx_state_t *s); 00188 00189 /*! \brief Initialise an instance of the modem connect tones detector. 00190 \param s The context. 00191 \param tone_type The type of connect tone being tested for. 00192 \param tone_callback An optional callback routine, used to report tones 00193 \param user_data An opaque pointer passed to the callback routine, 00194 \return A pointer to the context. 00195 */ 00196 modem_connect_tones_rx_state_t *modem_connect_tones_rx_init(modem_connect_tones_rx_state_t *s, 00197 int tone_type, 00198 tone_report_func_t tone_callback, 00199 void *user_data); 00200 00201 /*! \brief Free an instance of the modem connect tones detector. 00202 \param s The context. 00203 \return 0 for OK, else -1. */ 00204 int modem_connect_tones_rx_free(modem_connect_tones_rx_state_t *s); 00205 00206 #if defined(__cplusplus) 00207 } 00208 #endif 00209 00210 #endif 00211 /*- End of file ------------------------------------------------------------*/