FreeSWITCH API Documentation  1.7.0
libteletone_detect.h
Go to the documentation of this file.
1 /*
2  * libteletone
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
18  *
19  *
20  * The Initial Developer of the Original Code is
21  * Stephen Underwood <steveu@coppice.org>
22  * Portions created by the Initial Developer are Copyright (C)
23  * the Initial Developer. All Rights Reserved.
24  *
25  * Contributor(s):
26  *
27  * The the original interface designed by Steve Underwood was preserved to retain
28  *the optimizations when considering DTMF tones though the names were changed in the interest
29  * of namespace.
30  *
31  * Much less efficient expansion interface was added to allow for the detection of
32  * a single arbitrary tone combination which may also exceed 2 simultaneous tones.
33  * (controlled by compile time constant TELETONE_MAX_TONES)
34  *
35  * Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
36  *
37  *
38  * libteletone_detect.c Tone Detection Code
39  *
40  *
41  *********************************************************************************
42  *
43  * Derived from tone_detect.h - General telephony tone detection, and specific
44  * detection of DTMF.
45  *
46  * Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
47  *
48  * Despite my general liking of the GPL, I place this code in the
49  * public domain for the benefit of all mankind - even the slimy
50  * ones who might try to proprietize my work and use it to my
51  * detriment.
52  *
53  *
54  * Exception:
55  * The author hereby grants the use of this source code under the
56  * following license if and only if the source code is distributed
57  * as part of the OpenZAP or FreeTDM library. Any use or distribution of this
58  * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
59  * following license and reinact the MPL 1.1 as stated above.
60  *
61  * Copyright (c) 2007, Anthony Minessale II
62  * All rights reserved.
63  *
64  * Redistribution and use in source and binary forms, with or without
65  * modification, are permitted provided that the following conditions
66  * are met:
67  *
68  * * Redistributions of source code must retain the above copyright
69  * notice, this list of conditions and the following disclaimer.
70  *
71  * * Redistributions in binary form must reproduce the above copyright
72  * notice, this list of conditions and the following disclaimer in the
73  * documentation and/or other materials provided with the distribution.
74  *
75  * * Neither the name of the original author; nor the names of any contributors
76  * may be used to endorse or promote products derived from this software
77  * without specific prior written permission.
78  *
79  *
80  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
81  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
82  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
83  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
84  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
85  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
86  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
87  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
88  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
89  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91  */
92 
93 #ifndef LIBTELETONE_DETECT_H
94 #define LIBTELETONE_DETECT_H
95 
96 #ifdef __cplusplus
97 extern "C" {
98 #endif
99 #include <libteletone.h>
100 
101  /*! \file libteletone_detect.h
102  \brief Tone Detection Routines
103 
104  This module is responsible for tone detection specifics
105  */
106 
107 #ifndef FALSE
108 #define FALSE 0
109 #ifndef TRUE
110 #define TRUE (!FALSE)
111 #endif
112 #endif
113 
114  /* Basic DTMF specs:
115  *
116  * Minimum tone on = 40ms
117  * Minimum tone off = 50ms
118  * Maximum digit rate = 10 per second
119  * Normal twist <= 8dB accepted
120  * Reverse twist <= 4dB accepted
121  * S/N >= 15dB will detect OK
122  * Attenuation <= 26dB will detect OK
123  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
124  */
125 
126 #define DTMF_THRESHOLD 8.0e7
127 #define DTMF_NORMAL_TWIST 6.3 /* 8dB */
128 #define DTMF_REVERSE_TWIST 2.5 /* 4dB */
129 #define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
130 #define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
131 #define DTMF_2ND_HARMONIC_ROW 2.5 /* 4dB */
132 #define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
133 #define GRID_FACTOR 4
134 #define BLOCK_LEN 102
135 #define M_TWO_PI 2.0*M_PI
136 
137  typedef enum {
143 
144 
145  /*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
146  typedef struct {
147  float v2;
148  float v3;
149  double fac;
151 
152  /*! \brief A container for a DTMF detection state.*/
153  typedef struct {
154  int hit1;
155  int hit2;
156  int hit3;
157  int hit4;
158  int dur;
159  int zc;
160 
161 
166  float energy;
167  float lenergy;
168 
170  char digit;
174  int digit_hits[16];
176 
177  /*! \brief An abstraction to store the coefficient of a tone frequency */
178  typedef struct {
179  float fac;
181 
182  /*! \brief A container for a single multi-tone detection
183  TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present
184  in a multi-tone representation.
185  */
186  typedef struct {
188 
193 
194  float energy;
196 
199 
202  int hits;
203 
207 
209 
210 
211  /*!
212  \brief Initilize a multi-frequency tone detector
213  \param mt the multi-frequency tone descriptor
214  \param map a representation of the multi-frequency tone
215  */
217 
218  /*!
219  \brief Check a sample buffer for the presence of the mulit-frequency tone described by mt
220  \param mt the multi-frequency tone descriptor
221  \param sample_buffer an array aof 16 bit signed linear samples
222  \param samples the number of samples present in sample_buffer
223  \return true when the tone was detected or false when it is not
224  */
226  int16_t sample_buffer[],
227  int samples);
228 
229  /*!
230  \brief Initilize a DTMF detection state object
231  \param dtmf_detect_state the DTMF detection state to initilize
232  \param sample_rate the desired sample rate
233  */
234 TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate);
235 
236  /*!
237  \brief Check a sample buffer for the presence of DTMF digits
238  \param dtmf_detect_state the detection state object to check
239  \param sample_buffer an array aof 16 bit signed linear samples
240  \param samples the number of samples present in sample_buffer
241  \return true when DTMF was detected or false when it is not
242  */
244  int16_t sample_buffer[],
245  int samples);
246  /*!
247  \brief retrieve any collected digits into a string buffer
248  \param dtmf_detect_state the detection state object to check
249  \param buf the string buffer to write to
250  \param max the maximum length of buf
251  \return the number of characters written to buf
252  */
253 TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
254 
255  /*!
256  \brief Step through the Goertzel Algorithm for each sample in a buffer
257  \param goertzel_state the goertzel state to step the samples through
258  \param sample_buffer an array aof 16 bit signed linear samples
259  \param samples the number of samples present in sample_buffer
260  */
262  int16_t sample_buffer[],
263  int samples);
264 
265 
266 
267 #ifdef __cplusplus
268 }
269 #endif
270 
271 #endif
272 
273 /* For Emacs:
274  * Local Variables:
275  * mode:c
276  * indent-tabs-mode:t
277  * tab-width:4
278  * c-basic-offset:4
279  * End:
280  * For VIM:
281  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
282  */
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
A container for a single multi-tone detection TELETONE_MAX_TONES dictates the maximum simultaneous to...
void teletone_dtmf_detect_init(teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate)
Initilize a DTMF detection state object.
teletone_hit_type_t teletone_dtmf_detect(teletone_dtmf_detect_state_t *dtmf_detect_state, int16_t sample_buffer[], int samples)
Check a sample buffer for the presence of DTMF digits.
An abstraction to store a tone mapping.
Definition: libteletone.h:93
teletone_hit_type_t
#define GRID_FACTOR
A container for a DTMF detection state.
A continer for the elements of a Goertzel Algorithm (The names are from his formula) ...
#define TELETONE_API(type)
Definition: libteletone.h:133
switch_byte_t switch_byte_t * buf
int teletone_dtmf_get(teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
retrieve any collected digits into a string buffer
Top level include file.
void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
Initilize a multi-frequency tone detector.
void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state, int16_t sample_buffer[], int samples)
Step through the Goertzel Algorithm for each sample in a buffer.
An abstraction to store the coefficient of a tone frequency.
int teletone_multi_tone_detect(teletone_multi_tone_t *mt, int16_t sample_buffer[], int samples)
Check a sample buffer for the presence of the mulit-frequency tone described by mt.