spandsp  0.0.6
dtmf.h
1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * dtmf.h - DTMF tone generation and detection.
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 Lesser General Public License version 2.1,
14  * as 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 Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25 
26 #if !defined(_SPANDSP_DTMF_H_)
27 #define _SPANDSP_DTMF_H_
28 
29 /*! \page dtmf_rx_page DTMF receiver
30 \section dtmf_rx_page_sec_1 What does it do?
31 The DTMF receiver detects the standard DTMF digits. It is compliant with
32 ITU-T Q.23, ITU-T Q.24, and the local DTMF specifications of most administrations.
33 Its passes the test suites. It also scores *very* well on the standard
34 talk-off tests.
35 
36 The current design uses floating point extensively. It is not tolerant of DC.
37 It is expected that a DC restore stage will be placed before the DTMF detector.
38 Unless the dial tone filter is switched on, the detector has poor tolerance
39 of dial tone. Whether this matter depends on your application. If you are using
40 the detector in an IVR application you will need proper echo cancellation to
41 get good performance in the presence of speech prompts, so dial tone will not
42 exist. If you do need good dial tone tolerance, a dial tone filter can be
43 enabled in the detector.
44 
45 The DTMF receiver's design assumes the channel is free of any DC component.
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 typedef void (*digits_rx_callback_t)(void *user_data, const char *digits, int len);
77 
78 /*!
79  DTMF generator state descriptor. This defines the state of a single
80  working instance of a DTMF generator.
81 */
82 typedef struct dtmf_tx_state_s dtmf_tx_state_t;
83 
84 /*!
85  DTMF digit detector descriptor.
86 */
87 typedef struct dtmf_rx_state_s dtmf_rx_state_t;
88 
89 #if defined(__cplusplus)
90 extern "C"
91 {
92 #endif
93 
94 /*! \brief Generate a buffer of DTMF tones.
95  \param s The DTMF generator context.
96  \param amp The buffer for the generated signal.
97  \param max_samples The required number of generated samples.
98  \return The number of samples actually generated. This may be less than
99  max_samples if the input buffer empties. */
100 SPAN_DECLARE(int) dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples);
101 
102 /*! \brief Put a string of digits in a DTMF generator's input buffer.
103  \param s The DTMF generator context.
104  \param digits The string of digits to be added.
105  \param len The length of the string of digits. If negative, the string is
106  assumed to be a NULL terminated string.
107  \return The number of digits actually added. This may be less than the
108  length of the digit string, if the buffer fills up. */
109 SPAN_DECLARE(int) dtmf_tx_put(dtmf_tx_state_t *s, const char *digits, int len);
110 
111 /*! \brief Change the transmit level for a DTMF tone generator context.
112  \param s The DTMF generator context.
113  \param level The level of the low tone, in dBm0.
114  \param twist The twist, in dB. */
115 SPAN_DECLARE(void) dtmf_tx_set_level(dtmf_tx_state_t *s, int level, int twist);
116 
117 /*! \brief Change the transmit on and off time for a DTMF tone generator context.
118  \param s The DTMF generator context.
119  \param on-time The on time, in ms.
120  \param off_time The off time, in ms. */
121 SPAN_DECLARE(void) dtmf_tx_set_timing(dtmf_tx_state_t *s, int on_time, int off_time);
122 
123 /*! \brief Initialise a DTMF tone generator context.
124  \param s The DTMF generator context.
125  \return A pointer to the DTMF generator context. */
126 SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s);
127 
128 /*! \brief Release a DTMF tone generator context.
129  \param s The DTMF tone generator context.
130  \return 0 for OK, else -1. */
131 SPAN_DECLARE(int) dtmf_tx_release(dtmf_tx_state_t *s);
132 
133 /*! \brief Free a DTMF tone generator context.
134  \param s The DTMF tone generator context.
135  \return 0 for OK, else -1. */
136 SPAN_DECLARE(int) dtmf_tx_free(dtmf_tx_state_t *s);
137 
138 /*! Set a optional realtime callback for a DTMF receiver context. This function
139  is called immediately a confirmed state change occurs in the received DTMF. It
140  is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone
141  is being received.
142  \brief Set a realtime callback for a DTMF receiver context.
143  \param s The DTMF receiver context.
144  \param callback Callback routine used to report the start and end of digits.
145  \param user_data An opaque pointer which is associated with the context,
146  and supplied in callbacks. */
147 SPAN_DECLARE(void) dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s,
148  tone_report_func_t callback,
149  void *user_data);
150 
151 /*! \brief Adjust a DTMF receiver context.
152  \param s The DTMF receiver context.
153  \param filter_dialtone TRUE to enable filtering of dialtone, FALSE
154  to disable, < 0 to leave unchanged.
155  \param twist Acceptable twist, in dB. < 0 to leave unchanged.
156  \param reverse_twist Acceptable reverse twist, in dB. < 0 to leave unchanged.
157  \param threshold The minimum acceptable tone level for detection, in dBm0.
158  <= -99 to leave unchanged. */
159 SPAN_DECLARE(void) dtmf_rx_parms(dtmf_rx_state_t *s,
160  int filter_dialtone,
161  int twist,
162  int reverse_twist,
163  int threshold);
164 
165 /*! Process a block of received DTMF audio samples.
166  \brief Process a block of received DTMF audio samples.
167  \param s The DTMF receiver context.
168  \param amp The audio sample buffer.
169  \param samples The number of samples in the buffer.
170  \return The number of samples unprocessed. */
171 SPAN_DECLARE(int) dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples);
172 
173 /*! Fake processing of a missing block of received DTMF audio samples.
174  (e.g due to packet loss).
175  \brief Fake processing of a missing block of received DTMF audio samples.
176  \param s The DTMF receiver context.
177  \param len The number of samples to fake.
178  \return The number of samples unprocessed. */
179 SPAN_DECLARE(int) dtmf_rx_fillin(dtmf_rx_state_t *s, int samples);
180 
181 /*! Get the status of DTMF detection during processing of the last audio
182  chunk.
183  \brief Get the status of DTMF detection during processing of the last
184  audio chunk.
185  \param s The DTMF receiver context.
186  \return The current digit status. Either 'x' for a "maybe" condition, or the
187  digit being detected. */
188 SPAN_DECLARE(int) dtmf_rx_status(dtmf_rx_state_t *s);
189 
190 /*! \brief Get a string of digits from a DTMF receiver's output buffer.
191  \param s The DTMF receiver context.
192  \param digits The buffer for the received digits.
193  \param max The maximum number of digits to be returned,
194  \return The number of digits actually returned. */
195 SPAN_DECLARE(size_t) dtmf_rx_get(dtmf_rx_state_t *s, char *digits, int max);
196 
197 /*! \brief Get the logging context associated with a DTMF receiver context.
198  \param s The DTMF receiver context.
199  \return A pointer to the logging context */
201 
202 /*! \brief Initialise a DTMF receiver context.
203  \param s The DTMF receiver context.
204  \param callback An optional callback routine, used to report received digits. If
205  no callback routine is set, digits may be collected, using the dtmf_rx_get()
206  function.
207  \param user_data An opaque pointer which is associated with the context,
208  and supplied in callbacks.
209  \return A pointer to the DTMF receiver context. */
210 SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
211  digits_rx_callback_t callback,
212  void *user_data);
213 
214 /*! \brief Release a DTMF receiver context.
215  \param s The DTMF receiver context.
216  \return 0 for OK, else -1. */
217 SPAN_DECLARE(int) dtmf_rx_release(dtmf_rx_state_t *s);
218 
219 /*! \brief Free a DTMF receiver context.
220  \param s The DTMF receiver context.
221  \return 0 for OK, else -1. */
222 SPAN_DECLARE(int) dtmf_rx_free(dtmf_rx_state_t *s);
223 
224 #if defined(__cplusplus)
225 }
226 #endif
227 
228 #endif
229 /*- End of file ------------------------------------------------------------*/
make_goertzel_descriptor
void make_goertzel_descriptor(goertzel_descriptor_t *t, float freq, int samples)
Create a descriptor for use with either a Goertzel transform.
Definition: tone_detect.c:59
dtmf_rx_state_s::reverse_twist
float reverse_twist
Definition: private/dtmf.h:83
dds_lookup_complexi
complexi_t dds_lookup_complexi(uint32_t phase)
Lookup the complex integer value of a specified phase.
Definition: dds_int.c:388
dds_advance
void dds_advance(uint32_t *phase_acc, int32_t phase_rate)
Advance the phase, without returning any new signal sample.
Definition: dds_int.c:362
dds_complexi32_mod
complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase)
Generate a complex 32 bit integer tone sample, with modulation.
Definition: dds_int.c:458
tone_generate.h
dtmf_rx_init
dtmf_rx_state_t * dtmf_rx_init(dtmf_rx_state_t *s, digits_rx_callback_t callback, void *user_data)
Initialise a DTMF receiver context.
Definition: dtmf.c:407
dtmf_rx_fillin
int dtmf_rx_fillin(dtmf_rx_state_t *s, int samples)
Fake processing of a missing block of received DTMF audio samples.
Definition: dtmf.c:316
dds_lookup_complexi32
complexi32_t dds_lookup_complexi32(uint32_t phase)
Generate a complex 32 bit integer tone sample.
Definition: dds_int.c:442
QUEUE_WRITE_ATOMIC
#define QUEUE_WRITE_ATOMIC
Definition: queue.h:48
dds_mod
int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase)
Generate an integer tone sample, with modulation.
Definition: dds_int.c:378
dtmf_rx_set_realtime_callback
void dtmf_rx_set_realtime_callback(dtmf_rx_state_t *s, tone_report_func_t callback, void *user_data)
Set a realtime callback for a DTMF receiver context.
Definition: dtmf.c:363
span_log_test
int span_log_test(logging_state_t *s, int level)
Test if logging of a specified severity level is enabled.
Definition: logging.c:76
dds_scaling_dbov
int16_t dds_scaling_dbov(float level)
Find the scaling factor needed to achieve a specified level in dBmov.
Definition: dds_int.c:334
dtmf_rx_get
size_t dtmf_rx_get(dtmf_rx_state_t *s, char *buf, int max)
Get a string of digits from a DTMF receiver's output buffer.
Definition: dtmf.c:348
dds_complexi_mod
complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase)
Generate a complex integer tone sample, with modulation.
Definition: dds_int.c:404
goertzel_init
goertzel_state_t * goertzel_init(goertzel_state_t *s, goertzel_descriptor_t *t)
Initialise the state of a Goertzel transform.
Definition: tone_detect.c:70
complexf_t
Definition: complex.h:43
dds_advancef
void dds_advancef(uint32_t *phase_acc, int32_t phase_rate)
Advance the phase, without returning any new signal sample.
Definition: dds_float.c:2133
power_meter_current_dbm0
float power_meter_current_dbm0(power_meter_t *s)
Get the current power meter reading, in dBm0.
Definition: power_meter.c:120
dds_phase_rate
int32_t dds_phase_rate(float frequency)
Find the phase rate value to achieve a particular frequency.
Definition: dds_int.c:316
dtmf_rx_state_s::digits_callback_data
void * digits_callback_data
Definition: private/dtmf.h:55
dtmf_rx_parms
void dtmf_rx_parms(dtmf_rx_state_t *s, int filter_dialtone, int twist, int reverse_twist, int threshold)
Adjust a DTMF receiver context.
Definition: dtmf.c:373
goertzel_result
float goertzel_result(goertzel_state_t *s)
Evaluate the final result of a Goertzel transform.
Definition: tone_detect.c:156
dtmf_tx
int dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples)
Generate a buffer of DTMF tones.
Definition: dtmf.c:501
dtmf_rx_state_s::realtime_callback
tone_report_func_t realtime_callback
Definition: private/dtmf.h:57
dds_complexi16
complexi16_t dds_complexi16(uint32_t *phase_acc, int32_t phase_rate)
Generate a complex 16 bit integer tone sample.
Definition: dds_int.c:421
dds_lookupf
float dds_lookupf(uint32_t phase)
Lookup the floating point value of a specified phase.
Definition: dds_float.c:2149
dds_phase_ratef
int32_t dds_phase_ratef(float frequency)
Find the phase rate equivalent to a frequency, in Hz.
Definition: dds_float.c:2109
dds_scaling_dbm0
int16_t dds_scaling_dbm0(float level)
Find the scaling factor needed to achieve a specified level in dBm0.
Definition: dds_int.c:328
dds_complexf
complexf_t dds_complexf(uint32_t *phase_acc, int32_t phase_rate)
Generate a complex floating point tone sample.
Definition: dds_float.c:2165
dtmf_rx_state_s::z350
float z350[2]
Definition: private/dtmf.h:77
dtmf_rx_release
int dtmf_rx_release(dtmf_rx_state_t *s)
Release a DTMF receiver context.
Definition: dtmf.c:461
dtmf_rx_state_s::threshold
float threshold
Definition: private/dtmf.h:85
power_meter_update
int32_t power_meter_update(power_meter_t *s, int16_t amp)
Update a power meter.
Definition: power_meter.c:84
dtmf_rx_state_s::realtime_callback_data
void * realtime_callback_data
Definition: private/dtmf.h:59
dtmf_rx_state_s::lost_digits
int lost_digits
Definition: private/dtmf.h:104
dtmf_tx_free
int dtmf_tx_free(dtmf_tx_state_t *s)
Free a DTMF tone generator context.
Definition: dtmf.c:590
dds_offset
int16_t dds_offset(uint32_t phase_acc, int32_t phase_offset)
Find the amplitude for a particular phase offset from an accumulated phase.
Definition: dds_int.c:356
dds_complexi32
complexi32_t dds_complexi32(uint32_t *phase_acc, int32_t phase_rate)
Generate a complex 32 bit integer tone sample.
Definition: dds_int.c:448
dtmf_rx_status
int dtmf_rx_status(dtmf_rx_state_t *s)
Get the status of DTMF detection during processing of the last audio chunk.
Definition: dtmf.c:338
queue_read_byte
int queue_read_byte(queue_state_t *s)
Read a byte from a queue.
Definition: queue.c:188
power_meter_t
Definition: power_meter.h:49
complex.h
complexf_t::im
float im
Imaginary part.
Definition: complex.h:47
dds_phase_to_radians
float dds_phase_to_radians(uint32_t phase)
Convert a 32 bit phase angle to an angle in radians, between 0 and 2*PI.
Definition: dds_float.c:2103
dtmf_tx_release
int dtmf_tx_release(dtmf_tx_state_t *s)
Release a DTMF tone generator context.
Definition: dtmf.c:584
dtmf_rx_free
int dtmf_rx_free(dtmf_rx_state_t *s)
Free a DTMF receiver context.
Definition: dtmf.c:467
dds_frequency
float dds_frequency(int32_t phase_rate)
Find the frequency, in Hz, equivalent to a phase rate.
Definition: dds_int.c:322
dtmf_rx_state_s::digits_callback
digits_rx_callback_t digits_callback
Definition: private/dtmf.h:53
dds_lookup_complexi16
complexi16_t dds_lookup_complexi16(uint32_t phase)
Generate a complex 16 bit integer tone sample.
Definition: dds_int.c:415
dtmf_tx_set_level
void dtmf_tx_set_level(dtmf_tx_state_t *s, int level, int twist)
Change the transmit level for a DTMF tone generator context.
Definition: dtmf.c:551
complexi32_t
Definition: complex.h:100
queue_init
queue_state_t * queue_init(queue_state_t *s, int len, int flags)
Initialise a queue.
Definition: queue.c:394
dds_lookup_complexf
complexf_t dds_lookup_complexf(uint32_t phase)
Lookup the complex value of a specified phase.
Definition: dds_float.c:2176
dtmf_rx_state_s::z440
float z440[2]
Definition: private/dtmf.h:79
dtmf_rx_state_s::row_out
goertzel_state_t row_out[4]
Definition: private/dtmf.h:90
dtmf_rx_state_s::digits
char digits[MAX_DTMF_DIGITS+1]
Definition: private/dtmf.h:108
dds
int16_t dds(uint32_t *phase_acc, int32_t phase_rate)
Generate an integer tone sample.
Definition: dds_int.c:368
queue.h
dtmf_rx_state_s::last_hit
uint8_t last_hit
Definition: private/dtmf.h:94
queue_free_space
int queue_free_space(queue_state_t *s)
Check available free space.
Definition: queue.c:52
dtmf_rx_state_s::normal_twist
float normal_twist
Definition: private/dtmf.h:81
tone_gen_descriptor_s
Definition: private/tone_generate.h:43
dtmf_rx_state_s::energy
float energy
Definition: private/dtmf.h:87
complexi16_t
Definition: complex.h:89
span_log
int span_log(logging_state_t *s, int level, const char *format,...)
Generate a log entry.
Definition: logging.c:84
dds_scaling_dbovf
float dds_scaling_dbovf(float level)
Find the scaling factor equivalent to a dBmov value.
Definition: dds_float.c:2127
dtmf_rx_state_s::filter_dialtone
int filter_dialtone
Definition: private/dtmf.h:61
dds_frequencyf
float dds_frequencyf(int32_t phase_rate)
Find the frequency, in Hz, equivalent to a phase rate.
Definition: dds_float.c:2115
dtmf_tx_init
dtmf_tx_state_t * dtmf_tx_init(dtmf_tx_state_t *s)
Initialise a DTMF tone generator context.
Definition: dtmf.c:565
power_meter_current_dbov
float power_meter_current_dbov(power_meter_t *s)
Get the current power meter reading, in dBOv.
Definition: power_meter.c:129
dtmf_rx_state_s::duration
int duration
Definition: private/dtmf.h:101
dds_modf
float dds_modf(uint32_t *phase_acc, int32_t phase_rate, float scale, int32_t phase)
Generate a floating point tone sample, with modulation.
Definition: dds_float.c:2155
spandsp-sim.h
tone_gen_descriptor_init
tone_gen_descriptor_t * tone_gen_descriptor_init(tone_gen_descriptor_t *s, int f1, int l1, int f2, int l2, int d1, int d2, int d3, int d4, int repeat)
Create a tone generator descriptor.
Definition: tone_generate.c:60
dtmf_rx_state_s::current_sample
int current_sample
Definition: private/dtmf.h:98
dtmf_tx_put
int dtmf_tx_put(dtmf_tx_state_t *s, const char *digits, int len)
Put a string of digits in a DTMF generator's input buffer.
Definition: dtmf.c:531
queue_write
int queue_write(queue_state_t *s, const uint8_t *buf, int len)
Write bytes to a queue.
Definition: queue.c:214
ddsf
float ddsf(uint32_t *phase_acc, int32_t phase_rate)
Generate a floating point tone sample.
Definition: dds_float.c:2139
goertzel_descriptor_s
Definition: tone_detect.h:33
QUEUE_READ_ATOMIC
#define QUEUE_READ_ATOMIC
Definition: queue.h:45
logging.h
dtmf_rx_state_s::in_digit
uint8_t in_digit
Definition: private/dtmf.h:96
dds_lookup
int16_t dds_lookup(uint32_t phase)
Lookup the integer value of a specified phase.
Definition: dds_int.c:340
complexf_t::re
float re
Real part.
Definition: complex.h:45
dtmf_rx_state_s::logging
logging_state_t logging
Error and flow logging control.
Definition: private/dtmf.h:111
dtmf_rx_state_s
Definition: private/dtmf.h:51
dds_complexi16_mod
complexi16_t dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase)
Generate a complex 16bit integer tone sample, with modulation.
Definition: dds_int.c:431
dtmf_tx_set_timing
void dtmf_tx_set_timing(dtmf_tx_state_t *s, int on_time, int off_time)
Change the transmit on and off time for a DTMF tone generator context.
Definition: dtmf.c:558
goertzel_reset
void goertzel_reset(goertzel_state_t *s)
Reset the state of a Goertzel transform.
Definition: tone_detect.c:106
dtmf_rx_state_s::current_digits
int current_digits
Definition: private/dtmf.h:106
power_meter_init
power_meter_t * power_meter_init(power_meter_t *s, int shift)
Initialise a power meter context.
Definition: power_meter.c:50
dds_complex_modf
complexf_t dds_complex_modf(uint32_t *phase_acc, int32_t phase_rate, float scale, int32_t phase)
Generate a complex floating point tone sample, with modulation.
Definition: dds_float.c:2183
dtmf_tx_state_s
Definition: private/dtmf.h:34
dtmf_rx
int dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples)
Process a block of received DTMF audio samples.
Definition: dtmf.c:102
dtmf_rx_get_logging_state
logging_state_t * dtmf_rx_get_logging_state(dtmf_rx_state_t *s)
Get the logging context associated with a DTMF receiver context.
Definition: dtmf.c:401
logging_state_s
Definition: private/logging.h:34
dds_scaling_dbm0f
float dds_scaling_dbm0f(float level)
Find the scaling factor equivalent to a dBm0 value.
Definition: dds_float.c:2121
dtmf_rx_state_s::col_out
goertzel_state_t col_out[4]
Definition: private/dtmf.h:92
dds_complexi
complexi_t dds_complexi(uint32_t *phase_acc, int32_t phase_rate)
Generate a complex integer tone sample.
Definition: dds_int.c:394
dds.h
complexi_t
Definition: complex.h:78