5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * dtmf.h -
|
|
5 *
|
|
6 * Written by Steve Underwood <steveu@coppice.org>
|
|
7 *
|
|
8 * Copyright (C) 2001, 2005 Steve Underwood
|
|
9 *
|
|
10 * All rights reserved.
|
|
11 *
|
|
12 * This program is free software; you can redistribute it and/or modify
|
|
13 * it under the terms of the GNU General Public License version 2, as
|
|
14 * published by the Free Software Foundation.
|
|
15 *
|
|
16 * This program is distributed in the hope that it will be useful,
|
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 * GNU General Public License for more details.
|
|
20 *
|
|
21 * You should have received a copy of the GNU General Public License
|
|
22 * along with this program; if not, write to the Free Software
|
|
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
24 *
|
|
25 * $Id: dtmf.h,v 1.5 2006/10/24 13:45:28 steveu Exp $
|
|
26 */
|
|
27
|
|
28 #if !defined(_DTMF_H_)
|
|
29 #define _DTMF_H_
|
|
30
|
|
31 /*! \page dtmf_rx_page DTMF receiver
|
|
32 \section dtmf_rx_page_sec_1 What does it do?
|
|
33 The DTMF receiver detects the standard DTMF digits. It is compliant with
|
|
34 ITU-T Q.23, ITU-T Q.24, and the local DTMF specifications of most administrations.
|
|
35 Its passes the test suites. It also scores *very* well on the standard
|
|
36 talk-off tests.
|
|
37
|
|
38 The current design uses floating point extensively. It is not tolerant of DC.
|
|
39 It is expected that a DC restore stage will be placed before the DTMF detector.
|
|
40 Unless the dial tone filter is switched on, the detector has poor tolerance
|
|
41 of dial tone. Whether this matter depends on your application. If you are using
|
|
42 the detector in an IVR application you will need proper echo cancellation to
|
|
43 get good performance in the presence of speech prompts, so dial tone will not
|
|
44 exist. If you do need good dial tone tolerance, a dial tone filter can be
|
|
45 enabled in the detector.
|
|
46
|
|
47 \section dtmf_rx_page_sec_2 How does it work?
|
|
48 Like most other DSP based DTMF detector's, this one uses the Goertzel algorithm
|
|
49 to look for the DTMF tones. What makes each detector design different is just how
|
|
50 that algorithm is used.
|
|
51
|
|
52 Basic DTMF specs:
|
|
53 - Minimum tone on = 40ms
|
|
54 - Minimum tone off = 50ms
|
|
55 - Maximum digit rate = 10 per second
|
|
56 - Normal twist <= 8dB accepted
|
|
57 - Reverse twist <= 4dB accepted
|
|
58 - S/N >= 15dB will detect OK
|
|
59 - Attenuation <= 26dB will detect OK
|
|
60 - Frequency tolerance +- 1.5% will detect, +-3.5% will reject
|
|
61
|
|
62 TODO:
|
|
63 */
|
|
64
|
|
65 /*! \page dtmf_tx_page DTMF tone generation
|
|
66 \section dtmf_tx_page_sec_1 What does it do?
|
|
67
|
|
68 The DTMF tone generation module provides for the generation of the
|
|
69 repertoire of 16 DTMF dual tones.
|
|
70
|
|
71 \section dtmf_tx_page_sec_2 How does it work?
|
|
72 */
|
|
73
|
|
74 #define MAX_DTMF_DIGITS 128
|
|
75
|
|
76 /*!
|
|
77 DTMF generator state descriptor. This defines the state of a single
|
|
78 working instance of a DTMF generator.
|
|
79 */
|
|
80 typedef struct
|
|
81 {
|
|
82 tone_gen_descriptor_t *tone_descriptors;
|
|
83 tone_gen_state_t tones;
|
|
84 char digits[MAX_DTMF_DIGITS + 1];
|
|
85 int current_sample;
|
|
86 size_t current_digits;
|
|
87 } dtmf_tx_state_t;
|
|
88
|
|
89 /*!
|
|
90 DTMF digit detector descriptor.
|
|
91 */
|
|
92 typedef struct
|
|
93 {
|
|
94 /*! Optional callback funcion to deliver received digits. */
|
|
95 void (*callback)(void *data, const char *digits, int len);
|
|
96 /*! An opaque pointer passed to the callback function. */
|
|
97 void *callback_data;
|
|
98 /*! Optional callback funcion to deliver real time digit state changes. */
|
|
99 void (*realtime_callback)(void *data, int signal);
|
|
100 /*! An opaque pointer passed to the real time callback function. */
|
|
101 void *realtime_callback_data;
|
|
102 /*! TRUE if dialtone should be filtered before processing */
|
|
103 int filter_dialtone;
|
|
104 /*! Maximum acceptable "normal" (lower bigger than higher) twist ratio */
|
|
105 float normal_twist;
|
|
106 /*! Maximum acceptable "reverse" (higher bigger than lower) twist ratio */
|
|
107 float reverse_twist;
|
|
108
|
|
109 /*! 350Hz filter state for the optional dialtone filter */
|
|
110 float z350_1;
|
|
111 float z350_2;
|
|
112 /*! 440Hz filter state for the optional dialtone filter */
|
|
113 float z440_1;
|
|
114 float z440_2;
|
|
115
|
|
116 /*! Tone detector working states */
|
|
117 goertzel_state_t row_out[4];
|
|
118 goertzel_state_t col_out[4];
|
|
119 /*! The accumlating total energy on the same period over which the Goertzels work. */
|
|
120 float energy;
|
|
121 /*! The result of the last tone analysis. */
|
|
122 uint8_t last_hit;
|
|
123 /*! The confirmed digit we are currently receiving */
|
|
124 uint8_t in_digit;
|
|
125 /*! The current sample number within a processing block. */
|
|
126 int current_sample;
|
|
127
|
|
128 /*! The received digits buffer. This is a NULL terminated string. */
|
|
129 char digits[MAX_DTMF_DIGITS + 1];
|
|
130 /*! The number of digits currently in the digit buffer. */
|
|
131 int current_digits;
|
|
132 /*! The number of digits which have been lost due to buffer overflows. */
|
|
133 int lost_digits;
|
|
134 } dtmf_rx_state_t;
|
|
135
|
|
136 #ifdef __cplusplus
|
|
137 extern "C" {
|
|
138 #endif
|
|
139
|
|
140 /*! \brief Generate a buffer of DTMF tones.
|
|
141 \param s The DTMF generator context.
|
|
142 \param amp The buffer for the generated signal.
|
|
143 \param max_samples The required number of generated samples.
|
|
144 \return The number of samples actually generated. This may be less than
|
|
145 samples if the input buffer empties. */
|
|
146 int dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples);
|
|
147
|
|
148 /*! \brief Put a string of digits in a DTMF generator's input buffer.
|
|
149 \param s The DTMF generator context.
|
|
150 \param digits The string of digits to be added.
|
|
151 \return The number of digits actually added. This may be less than the
|
|
152 length of the digit string, if the buffer fills up. */
|
|
153 size_t dtmf_tx_put(dtmf_tx_state_t *s, const char *digits);
|
|
154
|
|
155 /*! \brief Initialise a DTMF tone generator context.
|
|
156 \param s The DTMF generator context.
|
|
157 \return A pointer to the DTMF generator context. */
|
|
158 dtmf_tx_state_t *dtmf_tx_init(dtmf_tx_state_t *s);
|
|
159
|
|
160 /*! Set a optional realtime callback for a DTMF receiver context. This function
|
|
161 is called immediately a confirmed state change occurs in the received DTMF. It
|
|
162 is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone
|
|
163 is being received.
|
|
164 \brief Set a realtime callback for a DTMF receiver context.
|
|
165 \param s The DTMF receiver context.
|
|
166 \param callback Callback routine used to report the start and end of digits.
|
|
167 \param user_data An opaque pointer which is associated with the context,
|
|
168 and supplied in callbacks. */
|
|
169 void dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s,
|
|
170 void (*callback)(void *user_data, int signal),
|
|
171 void *user_data);
|
|
172
|
|
173 /*! \brief Adjust a DTMF receiver context.
|
|
174 \param s The DTMF receiver context.
|
|
175 \param filter_dialtone TRUE to enable filtering of dialtone, FALSE
|
|
176 to disable, < 0 to leave unchanged.
|
|
177 \param twist Acceptable twist, in dB. < 0 to leave unchanged.
|
|
178 \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged. */
|
|
179 void dtmf_rx_parms(dtmf_rx_state_t *s, int filter_dialtone, int twist, int reverse_twist);
|
|
180
|
|
181 /*! Process a block of received DTMF audio samples.
|
|
182 \brief Process a block of received DTMF audio samples.
|
|
183 \param s The DTMF receiver context.
|
|
184 \param amp The audio sample buffer.
|
|
185 \param samples The number of samples in the buffer.
|
|
186 \return The number of samples unprocessed. */
|
|
187 int dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples);
|
|
188
|
|
189 /*! \brief Get a string of digits from a DTMF receiver's output buffer.
|
|
190 \param s The DTMF receiver context.
|
|
191 \param digits The buffer for the received digits.
|
|
192 \param max The maximum number of digits to be returned,
|
|
193 \return The number of digits actually returned. */
|
|
194 size_t dtmf_rx_get(dtmf_rx_state_t *s, char *digits, int max);
|
|
195
|
|
196 /*! \brief Initialise a DTMF receiver context.
|
|
197 \param s The DTMF receiver context.
|
|
198 \param callback An optional callback routine, used to report received digits. If
|
|
199 no callback routine is set, digits may be collected, using the dtmf_rx_get()
|
|
200 function.
|
|
201 \param user_data An opaque pointer which is associated with the context,
|
|
202 and supplied in callbacks.
|
|
203 \return A pointer to the DTMF receiver context. */
|
|
204 dtmf_rx_state_t *dtmf_rx_init(dtmf_rx_state_t *s,
|
|
205 void (*callback)(void *user_data, const char *digits, int len),
|
|
206 void *user_data);
|
|
207
|
|
208 #ifdef __cplusplus
|
|
209 }
|
|
210 #endif
|
|
211
|
|
212 #endif
|
|
213 /*- End of file ------------------------------------------------------------*/
|