1 /* 2 * libteletone 3 * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org> 4 * 5 * libteletone_detect.c Tone Detection Code 6 * 7 * Exception: 8 * The author hereby grants the use of this source code under the 9 * following license if and only if the source code is distributed 10 * as part of the freetdm library. Any use or distribution of this 11 * source code outside the scope of the freetdm library will nullify the 12 * following license and reinact the MPL 1.1 as stated above. 13 * 14 * Copyright (c) 2007, Anthony Minessale II 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 21 * * Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 24 * * Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 28 * * Neither the name of the original author; nor the names of any contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * 33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 37 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 39 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 41 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 * 45 ********************************************************************************* 46 * 47 * Derived from tone_detect.h - General telephony tone detection, and specific 48 * detection of DTMF. 49 * 50 * Copyright (C) 2001 Steve Underwood <steveu@coppice.org> 51 * 52 * Despite my general liking of the GPL, I place this code in the 53 * public domain for the benefit of all mankind - even the slimy 54 * ones who might try to proprietize my work and use it to my 55 * detriment. 56 * 57 * 58 */ 59 60 #ifndef LIBTELETONE_DETECT_H 61 #define LIBTELETONE_DETECT_H 62 63 #ifdef __cplusplus 64 extern "C" { 65 #endif 66 #include "libteletone.h" 67 68 /*! \file libteletone_detect.h 69 \brief Tone Detection Routines 70 71 This module is responsible for tone detection specifics 72 */ 73 74 #ifndef FALSE 75 #define FALSE 0 76 #ifndef TRUE 77 #define TRUE (!FALSE) 78 #endif 79 #endif 80 81 /* Basic DTMF specs: 82 * 83 * Minimum tone on = 40ms 84 * Minimum tone off = 50ms 85 * Maximum digit rate = 10 per second 86 * Normal twist <= 8dB accepted 87 * Reverse twist <= 4dB accepted 88 * S/N >= 15dB will detect OK 89 * Attenuation <= 26dB will detect OK 90 * Frequency tolerance +- 1.5% will detect, +-3.5% will reject 91 */ 92 93 #define DTMF_THRESHOLD 8.0e7 94 #define DTMF_NORMAL_TWIST 6.3 /* 8dB */ 95 #define DTMF_REVERSE_TWIST 2.5 /* 4dB */ 96 #define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ 97 #define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ 98 #define DTMF_2ND_HARMONIC_ROW 2.5 /* 4dB */ 99 #define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ 100 #define GRID_FACTOR 4 101 #define BLOCK_LEN 102 102 #define M_TWO_PI 2.0*M_PI 103 104 /*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */ 105 typedef struct { 106 float v2; 107 float v3; 108 double fac; 109 } teletone_goertzel_state_t; 110 111 /*! \brief A container for a DTMF detection state.*/ 112 typedef struct { 113 int hit1; 114 int hit2; 115 int hit3; 116 int hit4; 117 int mhit; 118 119 teletone_goertzel_state_t row_out[GRID_FACTOR]; 120 teletone_goertzel_state_t col_out[GRID_FACTOR]; 121 teletone_goertzel_state_t row_out2nd[GRID_FACTOR]; 122 teletone_goertzel_state_t col_out2nd[GRID_FACTOR]; 123 float energy; 124 125 int current_sample; 126 char digits[TELETONE_MAX_DTMF_DIGITS + 1]; 127 int current_digits; 128 int detected_digits; 129 int lost_digits; 130 int digit_hits[16]; 131 } teletone_dtmf_detect_state_t; 132 133 /*! \brief An abstraction to store the coefficient of a tone frequency */ 134 typedef struct { 135 float fac; 136 } teletone_detection_descriptor_t; 137 138 /*! \brief A container for a single multi-tone detection 139 TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present 140 in a multi-tone representation. 141 */ 142 typedef struct { 143 int sample_rate; 144 145 teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES]; 146 teletone_goertzel_state_t gs[TELETONE_MAX_TONES]; 147 teletone_goertzel_state_t gs2[TELETONE_MAX_TONES]; 148 int tone_count; 149 150 float energy; 151 int current_sample; 152 153 int min_samples; 154 int total_samples; 155 156 int positives; 157 int negatives; 158 int hits; 159 160 int positive_factor; 161 int negative_factor; 162 int hit_factor; 163 164 } teletone_multi_tone_t; 165 166 167 /*! 168 \brief Initilize a multi-frequency tone detector 169 \param mt the multi-frequency tone descriptor 170 \param map a representation of the multi-frequency tone 171 */ 172 TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map); 173 174 /*! 175 \brief Check a sample buffer for the presence of the mulit-frequency tone described by mt 176 \param mt the multi-frequency tone descriptor 177 \param sample_buffer an array aof 16 bit signed linear samples 178 \param samples the number of samples present in sample_buffer 179 \return true when the tone was detected or false when it is not 180 */ 181 TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt, 182 int16_t sample_buffer[], 183 int samples); 184 185 /*! 186 \brief Initilize a DTMF detection state object 187 \param dtmf_detect_state the DTMF detection state to initilize 188 \param sample_rate the desired sample rate 189 */ 190 TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate); 191 192 /*! 193 \brief Check a sample buffer for the presence of DTMF digits 194 \param dtmf_detect_state the detection state object to check 195 \param sample_buffer an array aof 16 bit signed linear samples 196 \param samples the number of samples present in sample_buffer 197 \return true when DTMF was detected or false when it is not 198 */ 199 TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state, 200 int16_t sample_buffer[], 201 int samples); 202 /*! 203 \brief retrieve any collected digits into a string buffer 204 \param dtmf_detect_state the detection state object to check 205 \param buf the string buffer to write to 206 \param max the maximum length of buf 207 \return the number of characters written to buf 208 */ 209 TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, 210 char *buf, 211 int max); 212 213 /*! 214 \brief Step through the Goertzel Algorithm for each sample in a buffer 215 \param goertzel_state the goertzel state to step the samples through 216 \param sample_buffer an array aof 16 bit signed linear samples 217 \param samples the number of samples present in sample_buffer 218 */ 219 TELETONE_API(void) teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state, 220 int16_t sample_buffer[], 221 int samples); 222 223 224 225 #ifdef __cplusplus 226 } 227 #endif 228 229 #endif 230 231 /* For Emacs: 232 * Local Variables: 233 * mode:c 234 * indent-tabs-mode:t 235 * tab-width:4 236 * c-basic-offset:4 237 * End: 238 * For VIM: 239 * vim:set softtabstop=4 shiftwidth=4 tabstop=4: 240 */