]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-3570 receive side, update libteletone to track duration so it is less likely to...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 16 Sep 2011 15:05:43 +0000 (10:05 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 16 Sep 2011 15:06:04 +0000 (10:06 -0500)
14 files changed:
libs/freetdm/src/detect_dtmf.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/include/private/libteletone.h
libs/freetdm/src/include/private/libteletone_detect.h
libs/freetdm/src/include/private/libteletone_generate.h
libs/freetdm/src/libteletone_detect.c
libs/freetdm/src/libteletone_generate.c
libs/libteletone/src/libteletone.h
libs/libteletone/src/libteletone_detect.c
libs/libteletone/src/libteletone_detect.h
libs/libteletone/src/libteletone_generate.c
libs/libteletone/src/libteletone_generate.h
src/mod/applications/mod_valet_parking/mod_valet_parking.c
src/switch_ivr_async.c

index e7d9648192e7dba20d9192c58b4aff05f8fda88d..62af298aefc71ff0d3c5a7de35c6565ee008d677 100644 (file)
@@ -6,7 +6,6 @@ int main(int argc, char *argv[])
        int fd, b;
        short sln[512] = {0};
        teletone_dtmf_detect_state_t dtmf_detect = {0};
-       char digit_str[128] = "";
 
        if (argc < 2) {
                fprintf(stderr, "Arg Error!\n");
@@ -21,10 +20,29 @@ int main(int argc, char *argv[])
        }
 
        while((b = read(fd, sln, 320)) > 0) {
+               char digit_char;
+               unsigned int dur;
+
                teletone_dtmf_detect(&dtmf_detect, sln, b / 2);
-               teletone_dtmf_get(&dtmf_detect, digit_str, sizeof(digit_str));
-               if (*digit_str) {
-                       printf("digit: %s\n", digit_str);
+               if ((hit = teletone_dtmf_get(&dtmf_detect, &digit_char, &dur))) {
+                       char *hs = NULL;
+                       
+
+                       switch(hit) {
+                       case TT_HIT_BEGIN:
+                               hs = "begin";
+                               break;
+
+                       case TT_HIT_MIDDLE:
+                               hs = "middle";
+                               break;
+
+                       case TT_HIT_END:
+                               hs = "end";
+                               break;
+                       }
+
+                       printf("%s digit: %s\n", hs, digit_str);
                }
        }
        close(fd);
index 0d0fdb655f254e99fe3cd5af45f77314dea3605b..a472ca1694a16a6a3de8feba965369a12d1fabe1 100644 (file)
@@ -3859,7 +3859,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
                uint8_t sln_buf[1024] = {0};
                int16_t *sln;
                ftdm_size_t slen = 0;
-               char digit_str[80] = "";
 
                if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
                        sln = data;
@@ -3960,13 +3959,18 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
                }
 
                if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT) && !ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
-                       teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen);
-                       teletone_dtmf_get(&ftdmchan->dtmf_detect, digit_str, sizeof(digit_str));
+                       teletone_hit_type_t hit;
+                       char digit_char;
+                       uint32_t dur;
 
-                       if(*digit_str) {
-                               if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (*digit_str == 'D' || *digit_str == 'A')) {
+                       teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen);
+                       
+                       if ((hit = teletone_dtmf_get(&ftdmchan->dtmf_detect, &digit_char, &dur)) == TT_HIT_BEGIN) {
+                               if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (digit_char == 'D' || digit_char == 'A')) {
                                        ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++;
                                } else {
+                                       char digit_str[2] = { digit_char, 0};
+                                       
                                        if (!ftdmchan->span->sig_dtmf || (ftdmchan->span->sig_dtmf(ftdmchan, (const char*)digit_str) != FTDM_BREAK)) {
                                                ftdm_channel_queue_dtmf(ftdmchan, digit_str);
                                        }
index dc98c8cb6c2bc42b9f106ec2353d69f312fe70c7..61078b49843b8527e462e30c071a2adef43c6ebb 100644 (file)
@@ -4,10 +4,10 @@
  *
  * Version: MPL 1.1
  *
- * The contents of this file are subject to the Mftilla Public License Version
+ * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
- * http://www.mftilla.org/MPL/
+ * http://www.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an "AS IS" basis,
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
@@ -33,8 +33,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the freetdm library.  Any use or distribution of this
- * source code outside the scope of the freetdm library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
@@ -136,8 +136,8 @@ typedef __int16 int16_t;
 #endif
 #endif
 
-#include "libteletone_generate.h"
-#include "libteletone_detect.h"
+#include <libteletone_generate.h>
+#include <libteletone_detect.h>
 
 #ifdef HAVE_STRING_H
 #include <string.h>
index 71bf067514e09f1dc2a02472427b14295b9a98da..4da368969ced34030da5d360f2739270759ddbb9 100644 (file)
@@ -2,13 +2,60 @@
  * libteletone
  * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
  *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
+ *
+ *
+ * The Initial Developer of the Original Code is
+ * Stephen Underwood <steveu@coppice.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * The the original interface designed by Steve Underwood was preserved to retain 
+ *the optimizations when considering DTMF tones though the names were changed in the interest 
+ * of namespace.
+ *
+ * Much less efficient expansion interface was added to allow for the detection of 
+ * a single arbitrary tone combination which may also exceed 2 simultaneous tones.
+ * (controlled by compile time constant TELETONE_MAX_TONES)
+ *
+ * Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
+ *
+ *
  * libteletone_detect.c Tone Detection Code
  *
+ *
+ ********************************************************************************* 
+ *
+ * Derived from tone_detect.h - General telephony tone detection, and specific
+ * detection of DTMF.
+ *
+ * Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
+ *
+ * Despite my general liking of the GPL, I place this code in the
+ * public domain for the benefit of all mankind - even the slimy
+ * ones who might try to proprietize my work and use it to my
+ * detriment.
+ *
+ *
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the freetdm library.     Any use or distribution of this
- * source code outside the scope of the freetdm library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************* 
- *
- * Derived from tone_detect.h - General telephony tone detection, and specific
- * detection of DTMF.
- *
- * Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
- *
- * Despite my general liking of the GPL, I place this code in the
- * public domain for the benefit of all mankind - even the slimy
- * ones who might try to proprietize my work and use it to my
- * detriment.
- *
- *
  */
 
 #ifndef LIBTELETONE_DETECT_H
@@ -63,7 +96,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-#include "libteletone.h"
+#include <libteletone.h>
 
        /*! \file libteletone_detect.h
          \brief Tone Detection Routines
@@ -101,6 +134,14 @@ extern "C" {
 #define BLOCK_LEN 102
 #define M_TWO_PI 2.0*M_PI
 
+       typedef enum {
+               TT_HIT_NONE = 0,
+               TT_HIT_BEGIN = 1,
+               TT_HIT_MIDDLE = 2,
+               TT_HIT_END = 3
+       } teletone_hit_type_t;
+
+
        /*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
        typedef struct {
                float v2;
@@ -114,16 +155,19 @@ extern "C" {
                int hit2;
                int hit3;
                int hit4;
-               int mhit;
+               int dur;
+               int zc;
+               
 
                teletone_goertzel_state_t row_out[GRID_FACTOR];
                teletone_goertzel_state_t col_out[GRID_FACTOR];
                teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
                teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
                float energy;
+               float lenergy;
        
                int current_sample;
-               char digits[TELETONE_MAX_DTMF_DIGITS + 1];
+               char digit;
                int current_digits;
                int detected_digits;
                int lost_digits;
@@ -196,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
          \param samples the number of samples present in sample_buffer
          \return true when DTMF was detected or false when it is not
        */
-TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
+TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                          int16_t sample_buffer[],
                                                          int samples);
        /*! 
@@ -206,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
          \param max the maximum length of buf
          \return the number of characters written to buf
        */
-TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-                                                  char *buf,
-                                                  int max);
+TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
 
        /*! 
          \brief Step through the Goertzel Algorithm for each sample in a buffer
index 6d716947616805a36f2b2f308fcfac36812ecbd1..0ff39e0dfaf41e1658ef8d7c5d35a3283865eff9 100644 (file)
@@ -2,6 +2,41 @@
  * libteletone
  * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
  *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libteletone
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthm@freeswitch.org>
+ *
+ *
+ * libteletone.h -- Tone Generator
+ *
+ *
+ *
+ * Exception:
+ * The author hereby grants the use of this source code under the 
+ * following license if and only if the source code is distributed
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
+ * following license and reinact the MPL 1.1 as stated above.
+ *
  * Copyright (c) 2007, Anthony Minessale II
  * All rights reserved.
  * 
@@ -81,7 +116,7 @@ extern float powf (float, float);
 #endif
 #include <assert.h>
 #include <stdarg.h>
-#include "libteletone.h"
+#include <libteletone.h>
 
 #define TELETONE_VOL_DB_MAX 0
 #define TELETONE_VOL_DB_MIN -63
index 0436c259532f6c4027526f4d0816aeb420d18fad..e995f98d0f68681525b7b9fa8f0dfecc812bf096 100644 (file)
@@ -2,14 +2,62 @@
  * libteletone
  * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
  *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
+ *
+ *
+ * The Initial Developer of the Original Code is
+ * Stephen Underwood <steveu@coppice.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * The the original interface designed by Steve Underwood was preserved to retain 
+ *the optimizations when considering DTMF tones though the names were changed in the interest 
+ * of namespace.
+ *
  * Much less efficient expansion interface was added to allow for the detection of 
  * a single arbitrary tone combination which may also exceed 2 simultaneous tones.
  * (controlled by compile time constant TELETONE_MAX_TONES)
  *
  * Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
  *
+ *
  * libteletone_detect.c Tone Detection Code
  *
+ *
+ ********************************************************************************* 
+ *
+ * Derived from tone_detect.c - General telephony tone detection, and specific
+ * detection of DTMF.
+ *
+ * Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
+ *
+ * Despite my general liking of the GPL, I place this code in the
+ * public domain for the benefit of all mankind - even the slimy
+ * ones who might try to proprietize my work and use it to my
+ * detriment.
+ *
+ *
+ * Exception:
+ * The author hereby grants the use of this source code under the 
+ * following license if and only if the source code is distributed
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
+ * following license and reinact the MPL 1.1 as stated above.
+ *
  * Copyright (c) 2007, Anthony Minessale II
  * All rights reserved.
  * 
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************* 
- *
- * Derived from tone_detect.c - General telephony tone detection, and specific
- * detection of DTMF.
- *
- * Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
- *
- * Despite my general liking of the GPL, I place this code in the
- * public domain for the benefit of all mankind - even the slimy
- * ones who might try to proprietize my work and use it to my
- * detriment.
- *
- *
- *
  */
 
 #include <libteletone_detect.h>
 #include <time.h>
 #include <fcntl.h>
 
-
+#define LOW_ENG 10000000
+#define ZC 2
 static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
 static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
 static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
@@ -132,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
        dtmf_detect_state->current_sample = 0;
        dtmf_detect_state->detected_digits = 0;
        dtmf_detect_state->lost_digits = 0;
-       dtmf_detect_state->digits[0] = '\0';
-       dtmf_detect_state->mhit = 0;
+       dtmf_detect_state->digit = 0;
+       dtmf_detect_state->dur = 0;
 }
 
 TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
@@ -266,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
 }
 
 
-TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
+TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                  int16_t sample_buffer[],
                                                  int samples)
 {
@@ -281,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
        int best_col;
        char hit;
        int limit;
+       teletone_hit_type_t r = 0;
 
        hit = 0;
        for (sample = 0;  sample < samples;      sample = limit) {
@@ -317,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
 
                }
 
+               if (dtmf_detect_state->zc > 0) {
+                       if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
+                               if (!--dtmf_detect_state->zc) {
+                                       /* Reinitialise the detector for the next block */
+                                       dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
+                                       for (i = 0;      i < GRID_FACTOR;  i++) {
+                                               goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
+                                               goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
+                                               goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
+                                               goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
+                                       }
+                                       dtmf_detect_state->dur -= samples;
+                                       return TT_HIT_END;
+                               }
+                       }
+                       
+                       dtmf_detect_state->dur += samples;
+                       dtmf_detect_state->lenergy = dtmf_detect_state->energy;
+                       dtmf_detect_state->energy = 0.0;
+                       dtmf_detect_state->current_sample = 0;
+                       return TT_HIT_MIDDLE;
+               } else if (dtmf_detect_state->digit) {
+                       return TT_HIT_END;
+               }
+               
+
                dtmf_detect_state->current_sample += (limit - sample);
                if (dtmf_detect_state->current_sample < BLOCK_LEN) {
                        continue;
@@ -361,58 +422,54 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
                                   back to back differing digits. More importantly, it
                                   can work with nasty phones that give a very wobbly start
                                   to a digit. */
-                               if (hit == dtmf_detect_state->hit3      &&      dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
-                                       dtmf_detect_state->mhit = hit;
+                               if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
                                        dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
                                        dtmf_detect_state->detected_digits++;
                                        if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
-                                               dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
-                                               dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
+                                               dtmf_detect_state->digit = hit;
+                                       } else {
+                                               dtmf_detect_state->lost_digits++;
                                        }
-                                       else
-                                               {
-                                                       dtmf_detect_state->lost_digits++;
-                                               }
+                                       
+                                       if (!dtmf_detect_state->zc) {
+                                               dtmf_detect_state->zc = ZC;
+                                               dtmf_detect_state->dur = 0;
+                                               r = TT_HIT_BEGIN;
+                                       }                                       
+
                                }
                        }
                }
+
                dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
                dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
                dtmf_detect_state->hit3 = hit;
-               /* Reinitialise the detector for the next block */
-               for (i = 0;      i < GRID_FACTOR;  i++) {
-                       goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
-                       goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
-                       goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
-                       goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
-               }
+
                dtmf_detect_state->energy = 0.0;
                dtmf_detect_state->current_sample = 0;
+               
        }
-       if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
-               dtmf_detect_state->mhit = 0;
-               return(0);
-       }
-       return (hit);
+
+       return r;
 }
 
 
-TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-                                          char *buf,
-                                          int max)
+TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
 {
-       teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
-
-       if (max > dtmf_detect_state->current_digits) {
-               max = dtmf_detect_state->current_digits;
+       if (!dtmf_detect_state->digit) {
+               return 0;
        }
-       if (max > 0) {
-               memcpy (buf, dtmf_detect_state->digits, max);
-               memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
-               dtmf_detect_state->current_digits -= max;
+
+       *buf = dtmf_detect_state->digit;
+
+       *dur = dtmf_detect_state->dur;
+
+       if (!dtmf_detect_state->zc) {
+               dtmf_detect_state->dur = 0;
+               dtmf_detect_state->digit = 0;
        }
-       buf[max] = '\0';
-       return  max;
+       
+       return 1;
 }
 
 /* For Emacs:
index c0d6a54349df0879eb56aa6e7c06a6feb22002b6..744850894450fb3c2c6e711eff31e8255e3f2952 100644 (file)
@@ -1,5 +1,41 @@
 /* 
- * libteletone_generate.c -- Tone Generator
+ * libteletone
+ * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libteletone
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthm@freeswitch.org>
+ *
+ *
+ * libteletone.c -- Tone Generator
+ *
+ *
+ *
+ * Exception:
+ * The author hereby grants the use of this source code under the 
+ * following license if and only if the source code is distributed
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
+ * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
  * All rights reserved.
@@ -34,7 +70,6 @@
  */
 
 #include <libteletone.h>
-#include "private/ftdm_core.h"
 
 #define SMAX 32767
 #define SMIN -32768
@@ -111,7 +146,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
        ts->decay_step = 0;
        ts->decay_factor = 1;
        if (buflen) {
-               if ((ts->buffer = ftdm_calloc(buflen, sizeof(teletone_audio_t))) == 0) {
+               if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
                        return -1;
                }
                ts->datalen = buflen;
@@ -142,7 +177,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
 TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts)
 {
        if (ts->buffer) {
-               ftdm_safe_free(ts->buffer);
+               free(ts->buffer);
                ts->buffer = NULL;
                ts->samples = 0;
        }
@@ -270,6 +305,19 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone
        return ts->samples / ts->channels;
 }
 
+/* don't ask */
+static char *my_strdup (const char *s)
+{
+       size_t len = strlen (s) + 1;
+       void *new = malloc (len);
+       
+       if (new == NULL) {
+               return NULL;
+       }
+
+       return (char *) memcpy (new, s, len);
+}
+
 TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
 {
        char *data = NULL, *cur = NULL, *end = NULL;
@@ -280,7 +328,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
        }
 
        do {
-               if (!(data = ftdm_strdup(cmd))) {
+               if (!(data = my_strdup(cmd))) {
                        return -1;
                }
 
@@ -363,6 +411,9 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
                                                                *e++ = '\0';
                                                        }
                                                        do {
+                                                               if (!p) {
+                                                                       break;
+                                                               }
                                                                if ((next = strchr(p, ',')) != 0) {
                                                                        *next++ = '\0';
                                                                }
@@ -427,7 +478,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
                        }
                }
        bottom:
-               ftdm_safe_free(data);
+               free(data);
                data = NULL;
                if (ts->LOOPS > 0) {
                        ts->LOOPS--;
index b54098c8ee7037c74a99b9115b6d581f54b1510d..61078b49843b8527e462e30c071a2adef43c6ebb 100644 (file)
@@ -33,8 +33,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the openzap library.  Any use or distribution of this
- * source code outside the scope of the openzap library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
index ae959535b513f5a96c611fe048b02f85e48de1a0..e995f98d0f68681525b7b9fa8f0dfecc812bf096 100644 (file)
@@ -54,8 +54,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the openzap library.     Any use or distribution of this
- * source code outside the scope of the openzap library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
 #include <time.h>
 #include <fcntl.h>
 
-
+#define LOW_ENG 10000000
+#define ZC 2
 static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
 static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
 static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
@@ -165,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
        dtmf_detect_state->current_sample = 0;
        dtmf_detect_state->detected_digits = 0;
        dtmf_detect_state->lost_digits = 0;
-       dtmf_detect_state->digits[0] = '\0';
-       dtmf_detect_state->mhit = 0;
+       dtmf_detect_state->digit = 0;
+       dtmf_detect_state->dur = 0;
 }
 
 TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
@@ -299,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
 }
 
 
-TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
+TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                  int16_t sample_buffer[],
                                                  int samples)
 {
@@ -314,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
        int best_col;
        char hit;
        int limit;
+       teletone_hit_type_t r = 0;
 
        hit = 0;
        for (sample = 0;  sample < samples;      sample = limit) {
@@ -350,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
 
                }
 
+               if (dtmf_detect_state->zc > 0) {
+                       if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
+                               if (!--dtmf_detect_state->zc) {
+                                       /* Reinitialise the detector for the next block */
+                                       dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
+                                       for (i = 0;      i < GRID_FACTOR;  i++) {
+                                               goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
+                                               goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
+                                               goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
+                                               goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
+                                       }
+                                       dtmf_detect_state->dur -= samples;
+                                       return TT_HIT_END;
+                               }
+                       }
+                       
+                       dtmf_detect_state->dur += samples;
+                       dtmf_detect_state->lenergy = dtmf_detect_state->energy;
+                       dtmf_detect_state->energy = 0.0;
+                       dtmf_detect_state->current_sample = 0;
+                       return TT_HIT_MIDDLE;
+               } else if (dtmf_detect_state->digit) {
+                       return TT_HIT_END;
+               }
+               
+
                dtmf_detect_state->current_sample += (limit - sample);
                if (dtmf_detect_state->current_sample < BLOCK_LEN) {
                        continue;
@@ -394,58 +422,54 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
                                   back to back differing digits. More importantly, it
                                   can work with nasty phones that give a very wobbly start
                                   to a digit. */
-                               if (hit == dtmf_detect_state->hit3      &&      dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
-                                       dtmf_detect_state->mhit = hit;
+                               if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
                                        dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
                                        dtmf_detect_state->detected_digits++;
                                        if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
-                                               dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
-                                               dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
+                                               dtmf_detect_state->digit = hit;
+                                       } else {
+                                               dtmf_detect_state->lost_digits++;
                                        }
-                                       else
-                                               {
-                                                       dtmf_detect_state->lost_digits++;
-                                               }
+                                       
+                                       if (!dtmf_detect_state->zc) {
+                                               dtmf_detect_state->zc = ZC;
+                                               dtmf_detect_state->dur = 0;
+                                               r = TT_HIT_BEGIN;
+                                       }                                       
+
                                }
                        }
                }
+
                dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
                dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
                dtmf_detect_state->hit3 = hit;
-               /* Reinitialise the detector for the next block */
-               for (i = 0;      i < GRID_FACTOR;  i++) {
-                       goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
-                       goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
-                       goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
-                       goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
-               }
+
                dtmf_detect_state->energy = 0.0;
                dtmf_detect_state->current_sample = 0;
+               
        }
-       if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
-               dtmf_detect_state->mhit = 0;
-               return(0);
-       }
-       return (hit);
+
+       return r;
 }
 
 
-TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-                                          char *buf,
-                                          int max)
+TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
 {
-       teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
-
-       if (max > dtmf_detect_state->current_digits) {
-               max = dtmf_detect_state->current_digits;
+       if (!dtmf_detect_state->digit) {
+               return 0;
        }
-       if (max > 0) {
-               memcpy (buf, dtmf_detect_state->digits, max);
-               memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
-               dtmf_detect_state->current_digits -= max;
+
+       *buf = dtmf_detect_state->digit;
+
+       *dur = dtmf_detect_state->dur;
+
+       if (!dtmf_detect_state->zc) {
+               dtmf_detect_state->dur = 0;
+               dtmf_detect_state->digit = 0;
        }
-       buf[max] = '\0';
-       return  max;
+       
+       return 1;
 }
 
 /* For Emacs:
index e2a8c20b33f2f198f0c205aaf934d400e2961118..4da368969ced34030da5d360f2739270759ddbb9 100644 (file)
@@ -54,8 +54,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the openzap library.     Any use or distribution of this
- * source code outside the scope of the openzap library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
@@ -134,6 +134,14 @@ extern "C" {
 #define BLOCK_LEN 102
 #define M_TWO_PI 2.0*M_PI
 
+       typedef enum {
+               TT_HIT_NONE = 0,
+               TT_HIT_BEGIN = 1,
+               TT_HIT_MIDDLE = 2,
+               TT_HIT_END = 3
+       } teletone_hit_type_t;
+
+
        /*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
        typedef struct {
                float v2;
@@ -147,16 +155,19 @@ extern "C" {
                int hit2;
                int hit3;
                int hit4;
-               int mhit;
+               int dur;
+               int zc;
+               
 
                teletone_goertzel_state_t row_out[GRID_FACTOR];
                teletone_goertzel_state_t col_out[GRID_FACTOR];
                teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
                teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
                float energy;
+               float lenergy;
        
                int current_sample;
-               char digits[TELETONE_MAX_DTMF_DIGITS + 1];
+               char digit;
                int current_digits;
                int detected_digits;
                int lost_digits;
@@ -229,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
          \param samples the number of samples present in sample_buffer
          \return true when DTMF was detected or false when it is not
        */
-TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
+TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                          int16_t sample_buffer[],
                                                          int samples);
        /*! 
@@ -239,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
          \param max the maximum length of buf
          \return the number of characters written to buf
        */
-TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-                                                  char *buf,
-                                                  int max);
+TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
 
        /*! 
          \brief Step through the Goertzel Algorithm for each sample in a buffer
index a5cefac98d43fd4faa96d74437e1114dfe04e3df..744850894450fb3c2c6e711eff31e8255e3f2952 100644 (file)
@@ -33,8 +33,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the openzap library.     Any use or distribution of this
- * source code outside the scope of the openzap library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
index 5e6444b0c4cd63e91543bb49adda5fdeb73443fa..0ff39e0dfaf41e1658ef8d7c5d35a3283865eff9 100644 (file)
@@ -33,8 +33,8 @@
  * Exception:
  * The author hereby grants the use of this source code under the 
  * following license if and only if the source code is distributed
- * as part of the openzap library.     Any use or distribution of this
- * source code outside the scope of the openzap library will nullify the
+ * as part of the OpenZAP or FreeTDM library.  Any use or distribution of this
+ * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
  * following license and reinact the MPL 1.1 as stated above.
  *
  * Copyright (c) 2007, Anthony Minessale II
index 0b25a47e94f83c73076b19c3bf352e701e4b4bd6..3ac27b15338d8cb8ba4ddf97ceff83ddc274eda9 100644 (file)
@@ -92,40 +92,49 @@ static void check_timeouts(void)
        void *val;
        time_t now;
        valet_lot_t *lot;
+       switch_console_callback_match_t *matches = NULL;
+       switch_console_callback_match_node_t *m;
+       switch_hash_index_t *i_hi;
+       const void *i_var;
+       void *i_val;
+       char *i_ext;
+       valet_token_t *token;
 
        now = switch_epoch_time_now(NULL);
 
        switch_mutex_lock(globals.mutex);
-
-
        for (hi = switch_hash_first(NULL, globals.hash); hi; hi = switch_hash_next(hi)) {
-               switch_hash_index_t *i_hi;
-               const void *i_var;
-               void *i_val;
-               char *i_ext;
-               valet_token_t *token;
-
                switch_hash_this(hi, &var, NULL, &val);
-               lot = (valet_lot_t *) val;
+               switch_console_push_match(&matches, (const char *) var);
+       }
+       switch_mutex_unlock(globals.mutex);
 
-               switch_mutex_lock(lot->mutex);
 
-       top:
+       if (matches) {
+               for (m = matches->head; m; m = m->next) {
+
+                       lot = valet_find_lot(m->val);
+                       switch_mutex_lock(lot->mutex);
+
+               top:
                
-               for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
-                       switch_hash_this(i_hi, &i_var, NULL, &i_val);
-                       i_ext = (char *) i_var;
-                       token = (valet_token_t *) i_val;
-                       if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) {
-                               switch_core_hash_delete(lot->hash, i_ext);
-                               switch_safe_free(token);
-                               goto top;
+                       for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
+                               switch_hash_this(i_hi, &i_var, NULL, &i_val);
+                               i_ext = (char *) i_var;
+                               token = (valet_token_t *) i_val;
+                               if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) {
+                                       switch_core_hash_delete(lot->hash, i_ext);
+                                       switch_safe_free(token);
+                                       goto top;
+                               }
                        }
+
+                       switch_mutex_unlock(lot->mutex);
                }
 
-               switch_mutex_unlock(lot->mutex);
+               switch_console_free_matches(&matches);
        }
-       switch_mutex_unlock(globals.mutex);
+
 }
 
 static int next_id(valet_lot_t *lot, int min, int max, int in)
index 6fe6048173601e19735fe411d7733edada34c84b..99449082bb321ebc5556956b95884283f5a24461 100644 (file)
@@ -2139,8 +2139,8 @@ static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_da
 {
        switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
        switch_frame_t *frame = NULL;
-       char digit_str[80];
        switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
+       teletone_hit_type_t hit;
 
        switch (type) {
        case SWITCH_ABC_TYPE_INIT:
@@ -2149,20 +2149,14 @@ static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_da
                break;
        case SWITCH_ABC_TYPE_READ_REPLACE:
                if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
-                       teletone_dtmf_detect(&pvt->dtmf_detect, frame->data, frame->samples);
-                       teletone_dtmf_get(&pvt->dtmf_detect, digit_str, sizeof(digit_str));
-                       if (digit_str[0]) {
-                               char *p = digit_str;
-                               while (p && *p) {
-                                       switch_dtmf_t dtmf = {0};
-                                       dtmf.digit = *p;
-                                       dtmf.duration = switch_core_default_dtmf_duration(0);
-                                       dtmf.source = SWITCH_DTMF_INBAND_AUDIO;
-                                       switch_channel_queue_dtmf(channel, &dtmf);
-                                       p++;
-                               }
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "DTMF DETECTED: [%s]\n",
-                                                                 digit_str);
+                       if ((hit = teletone_dtmf_detect(&pvt->dtmf_detect, frame->data, frame->samples)) == TT_HIT_END) {
+                               switch_dtmf_t dtmf = {0};
+
+                               teletone_dtmf_get(&pvt->dtmf_detect, &dtmf.digit, &dtmf.duration);
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "DTMF DETECTED: [%c][%d]\n",
+                                                                 dtmf.digit, dtmf.duration);
+                               dtmf.source = SWITCH_DTMF_INBAND_AUDIO;
+                               switch_channel_queue_dtmf(channel, &dtmf);
                        }
                        switch_core_media_bug_set_read_replace_frame(bug, frame);
                }