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 Lesser General Public License version 2.1,
00014  * as 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 Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License 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.28 2008/06/13 14:46:52 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 The DTMF receiver's design assumes the channel is free of any DC component.
00048 
00049 \section dtmf_rx_page_sec_2 How does it work?
00050 Like most other DSP based DTMF detector's, this one uses the Goertzel algorithm
00051 to look for the DTMF tones. What makes each detector design different is just how
00052 that algorithm is used.
00053 
00054 Basic DTMF specs:
00055     - Minimum tone on = 40ms
00056     - Minimum tone off = 50ms
00057     - Maximum digit rate = 10 per second
00058     - Normal twist <= 8dB accepted
00059     - Reverse twist <= 4dB accepted
00060     - S/N >= 15dB will detect OK
00061     - Attenuation <= 26dB will detect OK
00062     - Frequency tolerance +- 1.5% will detect, +-3.5% will reject
00063 
00064 TODO:
00065 */
00066 
00067 /*! \page dtmf_tx_page DTMF tone generation
00068 \section dtmf_tx_page_sec_1 What does it do?
00069 
00070 The DTMF tone generation module provides for the generation of the
00071 repertoire of 16 DTMF dual tones. 
00072 
00073 \section dtmf_tx_page_sec_2 How does it work?
00074 */
00075 
00076 #define MAX_DTMF_DIGITS 128
00077 
00078 typedef void (*digits_rx_callback_t)(void *user_data, const char *digits, int len);
00079 
00080 /*!
00081     DTMF generator state descriptor. This defines the state of a single
00082     working instance of a DTMF generator.
00083 */
00084 typedef struct
00085 {
00086     tone_gen_state_t tones;
00087     float low_level;
00088     float high_level;
00089     int on_time;
00090     int off_time;
00091     union
00092     {
00093         queue_state_t queue;
00094         uint8_t buf[QUEUE_STATE_T_SIZE(MAX_DTMF_DIGITS)];
00095     } queue;
00096 } dtmf_tx_state_t;
00097 
00098 /*!
00099     DTMF digit detector descriptor.
00100 */
00101 typedef struct
00102 {
00103     /*! Optional callback funcion to deliver received digits. */
00104     digits_rx_callback_t digits_callback;
00105     /*! An opaque pointer passed to the callback function. */
00106     void *digits_callback_data;
00107     /*! Optional callback funcion to deliver real time digit state changes. */
00108     tone_report_func_t realtime_callback;
00109     /*! An opaque pointer passed to the real time callback function. */
00110     void *realtime_callback_data;
00111     /*! TRUE if dialtone should be filtered before processing */
00112     int filter_dialtone;
00113 #if defined(SPANDSP_USE_FIXED_POINT)
00114     /*! 350Hz filter state for the optional dialtone filter. */
00115     float z350[2];
00116     /*! 440Hz filter state for the optional dialtone filter. */
00117     float z440[2];
00118     /*! Maximum acceptable "normal" (lower bigger than higher) twist ratio. */
00119     float normal_twist;
00120     /*! Maximum acceptable "reverse" (higher bigger than lower) twist ratio. */
00121     float reverse_twist;
00122     /*! Minimum acceptable tone level for detection. */
00123     int32_t threshold;
00124     /*! The accumlating total energy on the same period over which the Goertzels work. */
00125     int32_t energy;
00126 #else
00127     /*! 350Hz filter state for the optional dialtone filter. */
00128     float z350[2];
00129     /*! 440Hz filter state for the optional dialtone filter. */
00130     float z440[2];
00131     /*! Maximum acceptable "normal" (lower bigger than higher) twist ratio. */
00132     float normal_twist;
00133     /*! Maximum acceptable "reverse" (higher bigger than lower) twist ratio. */
00134     float reverse_twist;
00135     /*! Minimum acceptable tone level for detection. */
00136     float threshold;
00137     /*! The accumlating total energy on the same period over which the Goertzels work. */
00138     float energy;
00139 #endif
00140     /*! Tone detector working states for the row tones. */
00141     goertzel_state_t row_out[4];
00142     /*! Tone detector working states for the column tones. */
00143     goertzel_state_t col_out[4];
00144     /*! The result of the last tone analysis. */
00145     uint8_t last_hit;
00146     /*! The confirmed digit we are currently receiving */
00147     uint8_t in_digit;
00148     /*! The current sample number within a processing block. */
00149     int current_sample;
00150 
00151     /*! The number of digits which have been lost due to buffer overflows. */
00152     int lost_digits;
00153     /*! The number of digits currently in the digit buffer. */
00154     int current_digits;
00155     /*! The received digits buffer. This is a NULL terminated string. */
00156     char digits[MAX_DTMF_DIGITS + 1];
00157 } dtmf_rx_state_t;
00158 
00159 #if defined(__cplusplus)
00160 extern "C"
00161 {
00162 #endif
00163 
00164 /*! \brief Generate a buffer of DTMF tones.
00165     \param s The DTMF generator context.
00166     \param amp The buffer for the generated signal.
00167     \param max_samples The required number of generated samples.
00168     \return The number of samples actually generated. This may be less than 
00169             max_samples if the input buffer empties. */
00170 int dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples);
00171 
00172 /*! \brief Put a string of digits in a DTMF generator's input buffer.
00173     \param s The DTMF generator context.
00174     \param digits The string of digits to be added.
00175     \param len The length of the string of digits. If negative, the string is
00176            assumed to be a NULL terminated string.
00177     \return The number of digits actually added. This may be less than the
00178             length of the digit string, if the buffer fills up. */
00179 size_t dtmf_tx_put(dtmf_tx_state_t *s, const char *digits, int len);
00180 
00181 /*! \brief Change the transmit level for a DTMF tone generator context.
00182     \param s The DTMF generator context.
00183     \param level The level of the low tone, in dBm0.
00184     \param twist The twist, in dB. */
00185 void dtmf_tx_set_level(dtmf_tx_state_t *s, int level, int twist);
00186 
00187 /*! \brief Change the transmit on and off time for a DTMF tone generator context.
00188     \param s The DTMF generator context.
00189     \param on-time The on time, in ms.
00190     \param off_time The off time, in ms. */
00191 void dtmf_tx_set_timing(dtmf_tx_state_t *s, int on_time, int off_time);
00192 
00193 /*! \brief Initialise a DTMF tone generator context.
00194     \param s The DTMF generator context.
00195     \return A pointer to the DTMF generator context. */
00196 dtmf_tx_state_t *dtmf_tx_init(dtmf_tx_state_t *s);
00197 
00198 /*! \brief Free a DTMF tone generator context.
00199     \param s The DTMF tone generator context.
00200     \return 0 for OK, else -1. */
00201 int dtmf_tx_free(dtmf_tx_state_t *s);
00202 
00203 /*! Set a optional realtime callback for a DTMF receiver context. This function
00204     is called immediately a confirmed state change occurs in the received DTMF. It
00205     is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone
00206     is being received.
00207     \brief Set a realtime callback for a DTMF receiver context.
00208     \param s The DTMF receiver context.
00209     \param callback Callback routine used to report the start and end of digits.
00210     \param user_data An opaque pointer which is associated with the context,
00211            and supplied in callbacks. */
00212 void dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s,
00213                                    tone_report_func_t callback,
00214                                    void *user_data);
00215 
00216 /*! \brief Adjust a DTMF receiver context.
00217     \param s The DTMF receiver context.
00218     \param filter_dialtone TRUE to enable filtering of dialtone, FALSE
00219            to disable, < 0 to leave unchanged.
00220     \param twist Acceptable twist, in dB. < 0 to leave unchanged.
00221     \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged.
00222     \param threshold The minimum acceptable tone level for detection, in dBm0.
00223            <= -99 to leave unchanged. */
00224 void dtmf_rx_parms(dtmf_rx_state_t *s,
00225                    int filter_dialtone,
00226                    int twist,
00227                    int reverse_twist,
00228                    int threshold);
00229 
00230 /*! Process a block of received DTMF audio samples.
00231     \brief Process a block of received DTMF audio samples.
00232     \param s The DTMF receiver context.
00233     \param amp The audio sample buffer.
00234     \param samples The number of samples in the buffer.
00235     \return The number of samples unprocessed. */
00236 int dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples);
00237 
00238 /*! Get the status of DTMF detection during processing of the last audio
00239     chunk.
00240     \brief Get the status of DTMF detection during processing of the last
00241            audio chunk.
00242     \param s The DTMF receiver context.
00243     \return The current digit status. Either 'x' for a "maybe" condition, or the
00244             digit being detected. */
00245 int dtmf_rx_status(dtmf_rx_state_t *s);
00246 
00247 /*! \brief Get a string of digits from a DTMF receiver's output buffer.
00248     \param s The DTMF receiver context.
00249     \param digits The buffer for the received digits.
00250     \param max The maximum  number of digits to be returned,
00251     \return The number of digits actually returned. */
00252 size_t dtmf_rx_get(dtmf_rx_state_t *s, char *digits, int max);
00253 
00254 /*! \brief Initialise a DTMF receiver context.
00255     \param s The DTMF receiver context.
00256     \param callback An optional callback routine, used to report received digits. If
00257            no callback routine is set, digits may be collected, using the dtmf_rx_get()
00258            function.
00259     \param user_data An opaque pointer which is associated with the context,
00260            and supplied in callbacks.
00261     \return A pointer to the DTMF receiver context. */
00262 dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t *s,
00263                               digits_rx_callback_t callback,
00264                               void *user_data);
00265 
00266 /*! \brief Free a DTMF receiver context.
00267     \param s The DTMF receiver context.
00268     \return 0 for OK, else -1. */
00269 int dtmf_rx_free(dtmf_rx_state_t *s);
00270 
00271 #if defined(__cplusplus)
00272 }
00273 #endif
00274 
00275 #endif
00276 /*- End of file ------------------------------------------------------------*/

Generated on Tue Oct 7 20:25:45 2008 for spandsp by  doxygen 1.5.6