tone_detect.h

Go to the documentation of this file.
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 ------------------------------------------------------------*/

Generated on Fri Nov 10 09:40:24 2006 for libspandsp by  doxygen 1.5.1