00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * tone_detect.h - General telephony tone detection, and specific 00005 * detection of DTMF, Bell MF, and MFC/R2. 00006 * 00007 * Written by Steve Underwood <steveu@coppice.org> 00008 * 00009 * Copyright (C) 2001, 2005 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 as published by 00015 * the Free Software Foundation; either version 2 of the License, or 00016 * (at your option) any later version. 00017 * 00018 * This program is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * You should have received a copy of the GNU General Public License 00024 * along with this program; if not, write to the Free Software 00025 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00026 * 00027 * $Id: tone_detect.h,v 1.20 2006/02/06 15:00:56 steveu Exp $ 00028 */ 00029 00030 #if !defined(_TONE_DETECT_H_) 00031 #define _TONE_DETECT_H_ 00032 00033 /*! \page dtmf_rx_page DTMF receiver 00034 \section dtmf_rx_page_sec_1 What does it do? 00035 The DTMF receiver detects the standard DTMF digits. It is compliant with 00036 ITU-T Q.23, ITU-T Q.24, and the local DTMF specifications of most administrations. 00037 Its passes the test suites. It also scores *very* well on the standard 00038 talk-off tests. 00039 00040 The current design uses floating point extensively. It is not 00041 tolerant of DC or dial tone. It is expected that a DC restore stage will be 00042 placed before the DTMF detector. Whether dial tone tolerance matter depends on 00043 your application. If you are using the code in an IVR application you will need 00044 proper echo cancellation to get good performance in the prescence of speech 00045 prompts. 00046 00047 \section dtmf_rx_page_sec_2 How does it work? 00048 Like most other DSP based DTMF detector's, this one uses the Goertzel algorithm 00049 to look for the DTMF tones. What makes each detector design different is just how 00050 that algorithm is used. 00051 00052 Basic DTMF specs: 00053 - Minimum tone on = 40ms 00054 - Minimum tone off = 50ms 00055 - Maximum digit rate = 10 per second 00056 - Normal twist <= 8dB accepted 00057 - Reverse twist <= 4dB accepted 00058 - S/N >= 15dB will detect OK 00059 - Attenuation <= 26dB will detect OK 00060 - Frequency tolerance +- 1.5% will detect, +-3.5% will reject 00061 00062 TODO: 00063 */ 00064 00065 /*! \page mfc_r2_tone_rx_page MFC/R2 tone receiver 00066 00067 \section mfc_r2_tone_rx_page_sec_1 What does it do? 00068 The MFC/R2 tone receiver module provides for the detection of the 00069 repertoire of 15 dual tones needs for the digital MFC/R2 signalling protocol. 00070 It is compliant with ITU-T Q.441D. 00071 00072 \section mfc_r2_tone_rx_page_sec_2 How does it work? 00073 Basic MFC/R2 tone detection specs: 00074 - Receiver response range: -5dBm to -35dBm 00075 - Difference in level for a pair of frequencies 00076 - Adjacent tones: <5dB 00077 - Non-adjacent tones: <7dB 00078 - Receiver not to detect a signal of 2 frequencies of level -5dB and 00079 duration <7ms. 00080 - Receiver not to recognise a signal of 2 frequencies having a difference 00081 in level >=20dB. 00082 - Max received signal frequency error: +-10Hz 00083 - The sum of the operate and release times of a 2 frequency signal not to 00084 exceed 80ms (there are no individual specs for the operate and release 00085 times). 00086 - Receiver not to release for signal interruptions <=7ms. 00087 - System malfunction due to signal interruptions >7ms (typically 20ms) is 00088 prevented by further logic elements. 00089 */ 00090 00091 /*! \page bell_mf_tone_rx_page Bell MF tone receiver 00092 00093 \section bell_mf_tone_rx_page_sec_1 What does it do? 00094 The Bell MF tone receiver module provides for the detection of the 00095 repertoire of 15 dual tones needs for various Bell MF signalling protocols. 00096 It is compliant with ITU-T Q.320, ITU-T Q.322, ITU-T Q.323B. 00097 00098 \section bell_mf_tone_rx_page_sec_2 How does it work? 00099 Basic Bell MF tone detection specs: 00100 - Frequency tolerance +- 1.5% +-10Hz 00101 - Signal level -14dBm to 0dBm 00102 - Perform a "two and only two tones present" test. 00103 - Twist <= 6dB accepted 00104 - Receiver sensitive to signals above -22dBm per frequency 00105 - Test for a minimum of 55ms if KP, or 30ms of other signals. 00106 - Signals to be recognised if the two tones arrive within 8ms of each other. 00107 - Invalid signals result in the return of the re-order tone. 00108 00109 Note: Above -3dBm the signal starts to clip. We can detect with a little clipping, 00110 but not up to 0dBm, which the above spec seems to require. There isn't a lot 00111 we can do about that. Is the spec. incorrectly worded about the dBm0 reference 00112 point, or have I misunderstood it? 00113 */ 00114 00115 /*! 00116 Floating point Goertzel filter descriptor. 00117 */ 00118 typedef struct 00119 { 00120 float fac; 00121 int samples; 00122 } goertzel_descriptor_t; 00123 00124 /*! 00125 Floating point Goertzel filter state descriptor. 00126 */ 00127 typedef struct 00128 { 00129 float v2; 00130 float v3; 00131 float fac; 00132 int samples; 00133 int current_sample; 00134 } goertzel_state_t; 00135 00136 #if !defined(MAX_DTMF_DIGITS) 00137 #define MAX_DTMF_DIGITS 128 00138 #endif 00139 00140 /*! 00141 DTMF digit detector descriptor. 00142 */ 00143 typedef struct 00144 { 00145 void (*callback)(void *data, const char *digits, int len); 00146 void *callback_data; 00147 void (*realtime_callback)(void *data, int signal); 00148 void *realtime_callback_data; 00149 /*! TRUE if dialtone should be filtered before processing */ 00150 int filter_dialtone; 00151 float normal_twist; 00152 float reverse_twist; 00153 00154 /*! The state of the dialtone filter */ 00155 float z350_1; 00156 float z350_2; 00157 float z440_1; 00158 float z440_2; 00159 00160 /*! Tone detector working states */ 00161 goertzel_state_t row_out[4]; 00162 goertzel_state_t col_out[4]; 00163 float energy; 00164 int hits[3]; 00165 int in_digit; 00166 int current_sample; 00167 00168 /*! Received digit buffer */ 00169 char digits[MAX_DTMF_DIGITS + 1]; 00170 int current_digits; 00171 int lost_digits; 00172 } dtmf_rx_state_t; 00173 00174 /*! 00175 Bell MF digit detector descriptor. 00176 */ 00177 typedef struct 00178 { 00179 void (*callback)(void *data, const char *digits, int len); 00180 void *callback_data; 00181 /*! Tone detector working states */ 00182 goertzel_state_t out[6]; 00183 int hits[5]; 00184 int current_sample; 00185 00186 char digits[MAX_DTMF_DIGITS + 1]; 00187 int current_digits; 00188 int lost_digits; 00189 } bell_mf_rx_state_t; 00190 00191 /*! 00192 MFC/R2 tone detector descriptor. 00193 */ 00194 typedef struct 00195 { 00196 /*! Tone detector working states */ 00197 goertzel_state_t out[6]; 00198 int hits[3]; 00199 int fwd; 00200 int samples; 00201 int current_sample; 00202 } r2_mf_rx_state_t; 00203 00204 #ifdef __cplusplus 00205 extern "C" { 00206 #endif 00207 00208 /*! \brief Create a descriptor for use with either a Goertzel transform */ 00209 void make_goertzel_descriptor(goertzel_descriptor_t *t, 00210 int freq, 00211 int samples); 00212 00213 /*! \brief Initialise the state of a Goertzel transform. 00214 \param s The Goertzel state. If NULL, a state is allocated with malloc. 00215 \param t The Goertzel descriptor. 00216 \return A pointer to the Goertzel state. */ 00217 goertzel_state_t *goertzel_init(goertzel_state_t *s, 00218 goertzel_descriptor_t *t); 00219 00220 /*! \brief Update the state of a Goertzel transform. 00221 \param s The Goertzel state 00222 \param amp The samples to be transformed 00223 \param samples The number of samples 00224 \return The number of samples unprocessed */ 00225 int goertzel_update(goertzel_state_t *s, 00226 const int16_t amp[], 00227 int samples); 00228 00229 /*! \brief Evaluate the final result of a Goertzel transform. 00230 \param s The Goertzel state 00231 \return The result of the transform. */ 00232 float goertzel_result(goertzel_state_t *s); 00233 00234 /*! \brief Initialise a DTMF receiver context. 00235 \param s The DTMF receiver context. 00236 \param callback Callback routine used to report received digits. 00237 \param user_data An opaque pointer which is associated with the context, 00238 and supplied in callbacks. 00239 \return A pointer to the DTMF receiver context. */ 00240 dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t *s, 00241 void (*callback)(void *user_data, const char *digits, int len), 00242 void *user_data); 00243 00244 /*! \brief Set a realtime callback for a DTMF receiver context. 00245 \param s The DTMF receiver context. 00246 \param callback Callback routine used to report the start and end of digits. 00247 \param user_data An opaque pointer which is associated with the context, 00248 and supplied in callbacks. */ 00249 void dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s, 00250 void (*callback)(void *user_data, int signal), 00251 void *user_data); 00252 00253 /*! \brief Adjust a DTMF receiver context. 00254 \param s The DTMF receiver context. 00255 \param filter_dialtone TRUE to enable filtering of dialtone, FALSE 00256 to disable, < 0 to leave unchanged. 00257 \param twist Acceptable twist, in dB. < 0 to leave unchanged. 00258 \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged. */ 00259 void dtmf_rx_parms(dtmf_rx_state_t *s, int filter_dialtone, int twist, int reverse_twist); 00260 00261 /*! Process a block of received DTMF audio samples. 00262 \brief Process a block of received DTMF audio samples. 00263 \param s The DTMF receiver context. 00264 \param amp The audio sample buffer. 00265 \param samples The number of samples in the buffer. 00266 \return The number of samples unprocessed. */ 00267 int dtmf_rx(dtmf_rx_state_t *s, const int16_t *amp, int samples); 00268 00269 int dtmf_get(dtmf_rx_state_t *s, char *buf, int max); 00270 00271 /*! \brief Initialise a Bell MF receiver context. 00272 \param s The Bell MF receiver context. 00273 \param callback Callback routine used to report received digits. 00274 \param user_data An opaque pointer which is associated with the context, 00275 and supplied in callbacks. 00276 \return A pointer to the Bell MF receiver context.*/ 00277 bell_mf_rx_state_t *bell_mf_rx_init(bell_mf_rx_state_t *s, 00278 void (*callback)(void *user_data, const char *digits, int len), 00279 void *user_data); 00280 00281 /*! Process a block of received bell MF audio samples. 00282 \brief Process a block of received Bell MF audio samples. 00283 \param s The Bell MF receiver context. 00284 \param amp The audio sample buffer. 00285 \param samples The number of samples in the buffer. 00286 \return The number of samples unprocessed. */ 00287 int bell_mf_rx(bell_mf_rx_state_t *s, const int16_t *amp, int samples); 00288 00289 int bell_mf_get(bell_mf_rx_state_t *s, char *buf, int max); 00290 00291 /*! \brief Initialise an R2 MF receiver context. 00292 \param s The R2 MF receiver context. 00293 \param fwd TRUE if the context is for forward signals. FALSE if the 00294 context is for backward signals. 00295 \return A pointer to the R2 MF receiver context. */ 00296 r2_mf_rx_state_t *r2_mf_rx_init(r2_mf_rx_state_t *s, int fwd); 00297 00298 /*! Process a block of received R2 MF audio samples. 00299 \brief Process a block of received R2 MF audio samples. 00300 \param s The R2 MF receiver context. 00301 \param amp The audio sample buffer. 00302 \param samples The number of samples in the buffer. 00303 \return The number of samples unprocessed. */ 00304 int r2_mf_rx(r2_mf_rx_state_t *s, const int16_t *amp, int samples); 00305 00306 #ifdef __cplusplus 00307 } 00308 #endif 00309 00310 #endif 00311 /*- End of file ------------------------------------------------------------*/