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");
}
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);
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;
}
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);
}
*
* 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
* 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
#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>
* 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
#ifdef __cplusplus
extern "C" {
#endif
-#include "libteletone.h"
+#include <libteletone.h>
/*! \file libteletone_detect.h
\brief Tone Detection Routines
#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;
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;
\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);
/*!
\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
* 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.
*
#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
* 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];
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)
}
-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)
{
int best_col;
char hit;
int limit;
+ teletone_hit_type_t r = 0;
hit = 0;
for (sample = 0; sample < samples; sample = limit) {
}
+ 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;
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:
/*
- * 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.
*/
#include <libteletone.h>
-#include "private/ftdm_core.h"
#define SMAX 32767
#define SMIN -32768
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;
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;
}
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;
}
do {
- if (!(data = ftdm_strdup(cmd))) {
+ if (!(data = my_strdup(cmd))) {
return -1;
}
*e++ = '\0';
}
do {
+ if (!p) {
+ break;
+ }
if ((next = strchr(p, ',')) != 0) {
*next++ = '\0';
}
}
}
bottom:
- ftdm_safe_free(data);
+ free(data);
data = NULL;
if (ts->LOOPS > 0) {
ts->LOOPS--;
* 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
* 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];
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)
}
-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)
{
int best_col;
char hit;
int limit;
+ teletone_hit_type_t r = 0;
hit = 0;
for (sample = 0; sample < samples; sample = limit) {
}
+ 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;
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:
* 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
#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;
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;
\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);
/*!
\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
* 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
* 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
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)
{
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:
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);
}