dtmf.h

Go to the documentation of this file.
00001 /*
00002  * SpanDSP - a series of DSP components for telephony
00003  *
00004  * dtmf.h - 
00005  *
00006  * Written by Steve Underwood <steveu@coppice.org>
00007  *
00008  * Copyright (C) 2001, 2005 Steve Underwood
00009  *
00010  * All rights reserved.
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License version 2, as
00014  * published by the Free Software Foundation.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024  *
00025  * $Id: dtmf.h,v 1.9 2007/04/05 19:20:49 steveu Exp $
00026  */
00027 
00028 #if !defined(_SPANDSP_DTMF_H_)
00029 #define _SPANDSP_DTMF_H_
00030 
00031 /*! \page dtmf_rx_page DTMF receiver
00032 \section dtmf_rx_page_sec_1 What does it do?
00033 The DTMF receiver detects the standard DTMF digits. It is compliant with
00034 ITU-T Q.23, ITU-T Q.24, and the local DTMF specifications of most administrations.
00035 Its passes the test suites. It also scores *very* well on the standard
00036 talk-off tests. 
00037 
00038 The current design uses floating point extensively. It is not tolerant of DC.
00039 It is expected that a DC restore stage will be placed before the DTMF detector.
00040 Unless the dial tone filter is switched on, the detector has poor tolerance
00041 of dial tone. Whether this matter depends on your application. If you are using
00042 the detector in an IVR application you will need proper echo cancellation to
00043 get good performance in the presence of speech prompts, so dial tone will not
00044 exist. If you do need good dial tone tolerance, a dial tone filter can be
00045 enabled in the detector.
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 dtmf_tx_page DTMF tone generation
00066 \section dtmf_tx_page_sec_1 What does it do?
00067 
00068 The DTMF tone generation module provides for the generation of the
00069 repertoire of 16 DTMF dual tones. 
00070 
00071 \section dtmf_tx_page_sec_2 How does it work?
00072 */
00073 
00074 #define MAX_DTMF_DIGITS 128
00075 
00076 typedef void (*dtmf_rx_callback_t)(void *user_data, const char *digits, int len);
00077 
00078 /*!
00079     DTMF generator state descriptor. This defines the state of a single
00080     working instance of a DTMF generator.
00081 */
00082 typedef struct
00083 {
00084     tone_gen_descriptor_t *tone_descriptors;
00085     tone_gen_state_t tones;
00086     char digits[MAX_DTMF_DIGITS + 1];
00087     int current_sample;
00088     size_t current_digits;
00089 } dtmf_tx_state_t;
00090 
00091 /*!
00092     DTMF digit detector descriptor.
00093 */
00094 typedef struct
00095 {
00096     /*! Optional callback funcion to deliver received digits. */
00097     dtmf_rx_callback_t callback;
00098     /*! An opaque pointer passed to the callback function. */
00099     void *callback_data;
00100     /*! Optional callback funcion to deliver real time digit state changes. */
00101     tone_report_func_t realtime_callback;
00102     /*! An opaque pointer passed to the real time callback function. */
00103     void *realtime_callback_data;
00104     /*! TRUE if dialtone should be filtered before processing */
00105     int filter_dialtone;
00106     /*! Maximum acceptable "normal" (lower bigger than higher) twist ratio */
00107     float normal_twist;
00108     /*! Maximum acceptable "reverse" (higher bigger than lower) twist ratio */
00109     float reverse_twist;
00110 
00111     /*! 350Hz filter state for the optional dialtone filter */
00112     float z350_1;
00113     float z350_2;
00114     /*! 440Hz filter state for the optional dialtone filter */
00115     float z440_1;
00116     float z440_2;
00117 
00118     /*! Tone detector working states */
00119     goertzel_state_t row_out[4];
00120     goertzel_state_t col_out[4];
00121     /*! The accumlating total energy on the same period over which the Goertzels work. */
00122     float energy;
00123     /*! The result of the last tone analysis. */
00124     uint8_t last_hit;
00125     /*! The confirmed digit we are currently receiving */
00126     uint8_t in_digit;
00127     /*! The current sample number within a processing block. */
00128     int current_sample;
00129 
00130     /*! The received digits buffer. This is a NULL terminated string. */
00131     char digits[MAX_DTMF_DIGITS + 1];
00132     /*! The number of digits currently in the digit buffer. */
00133     int current_digits;
00134     /*! The number of digits which have been lost due to buffer overflows. */
00135     int lost_digits;
00136 } dtmf_rx_state_t;
00137 
00138 #ifdef __cplusplus
00139 extern "C"
00140 {
00141 #endif
00142 
00143 /*! \brief Generate a buffer of DTMF tones.
00144     \param s The DTMF generator context.
00145     \param amp The buffer for the generated signal.
00146     \param max_samples The required number of generated samples.
00147     \return The number of samples actually generated. This may be less than 
00148             samples if the input buffer empties. */
00149 int dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples);
00150 
00151 /*! \brief Put a string of digits in a DTMF generator's input buffer.
00152     \param s The DTMF generator context.
00153     \param digits The string of digits to be added.
00154     \return The number of digits actually added. This may be less than the
00155             length of the digit string, if the buffer fills up. */
00156 size_t dtmf_tx_put(dtmf_tx_state_t *s, const char *digits);
00157 
00158 /*! \brief Initialise a DTMF tone generator context.
00159     \param s The DTMF generator context.
00160     \return A pointer to the DTMF generator context. */
00161 dtmf_tx_state_t *dtmf_tx_init(dtmf_tx_state_t *s);
00162 
00163 /*! Set a optional realtime callback for a DTMF receiver context. This function
00164     is called immediately a confirmed state change occurs in the received DTMF. It
00165     is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone
00166     is being received.
00167     \brief Set a realtime callback for a DTMF receiver context.
00168     \param s The DTMF receiver context.
00169     \param callback Callback routine used to report the start and end of digits.
00170     \param user_data An opaque pointer which is associated with the context,
00171            and supplied in callbacks. */
00172 void dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s,
00173                                    tone_report_func_t callback,
00174                                    void *user_data);
00175 
00176 /*! \brief Adjust a DTMF receiver context.
00177     \param s The DTMF receiver context.
00178     \param filter_dialtone TRUE to enable filtering of dialtone, FALSE
00179            to disable, < 0 to leave unchanged.
00180     \param twist Acceptable twist, in dB. < 0 to leave unchanged.
00181     \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged. */
00182 void dtmf_rx_parms(dtmf_rx_state_t *s, int filter_dialtone, int twist, int reverse_twist);
00183 
00184 /*! Process a block of received DTMF audio samples.
00185     \brief Process a block of received DTMF audio samples.
00186     \param s The DTMF receiver context.
00187     \param amp The audio sample buffer.
00188     \param samples The number of samples in the buffer.
00189     \return The number of samples unprocessed. */
00190 int dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples);
00191 
00192 /*! \brief Get a string of digits from a DTMF receiver's output buffer.
00193     \param s The DTMF receiver context.
00194     \param digits The buffer for the received digits.
00195     \param max The maximum  number of digits to be returned,
00196     \return The number of digits actually returned. */
00197 size_t dtmf_rx_get(dtmf_rx_state_t *s, char *digits, int max);
00198 
00199 /*! \brief Initialise a DTMF receiver context.
00200     \param s The DTMF receiver context.
00201     \param callback An optional callback routine, used to report received digits. If
00202            no callback routine is set, digits may be collected, using the dtmf_rx_get()
00203            function.
00204     \param user_data An opaque pointer which is associated with the context,
00205            and supplied in callbacks.
00206     \return A pointer to the DTMF receiver context. */
00207 dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t *s,
00208                               dtmf_rx_callback_t callback,
00209                               void *user_data);
00210 
00211 #ifdef __cplusplus
00212 }
00213 #endif
00214 
00215 #endif
00216 /*- End of file ------------------------------------------------------------*/

Generated on Fri Apr 13 13:40:15 2007 for libspandsp by  doxygen 1.5.2