[asterisk-commits] russell: trunk r61782 - in /trunk: ./
include/asterisk/channel.h main/channel.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Apr 24 12:03:17 MST 2007
Author: russell
Date: Tue Apr 24 14:03:16 2007
New Revision: 61782
URL: http://svn.digium.com/view/asterisk?view=rev&rev=61782
Log:
Merged revisions 61781 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r61781 | russell | 2007-04-24 14:00:06 -0500 (Tue, 24 Apr 2007) | 6 lines
Improve DTMF handling in ast_read() even more in response to a discussion on
the asterisk-dev mailing list. I changed the enforced minimum length of a
digit from 100ms to 80ms. Furthermore, I made it now enforce a gap of 45ms in
between digits. These values are not configurable in a configuration file
right now, but they can be easily changed near the top of main/channel.c.
........
Modified:
trunk/ (props changed)
trunk/include/asterisk/channel.h
trunk/main/channel.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Modified: trunk/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=61782&r1=61781&r2=61782
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Tue Apr 24 14:03:16 2007
@@ -487,7 +487,7 @@
char emulate_dtmf_digit; /*!< Digit being emulated */
unsigned int emulate_dtmf_duration; /*!< Number of ms left to emulate DTMF for */
- struct timeval dtmf_begin_tv; /*!< The time that an in process digit began */
+ struct timeval dtmf_tv; /*!< The time that an in process digit began, or the last digit ended */
/*! \brief Data stores on the channel */
AST_LIST_HEAD_NOLOCK(datastores, ast_datastore) datastores;
Modified: trunk/main/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/main/channel.c?view=diff&rev=61782&r1=61781&r2=61782
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Tue Apr 24 14:03:16 2007
@@ -104,7 +104,16 @@
AST_THREADSTORAGE(state2str_threadbuf);
#define STATE2STR_BUFSIZE 32
-#define AST_DEFAULT_EMULATE_DTMF_DURATION 100 /*!< 100ms */
+/*! Default amount of time to use when emulating a digit as a begin and end
+ * 100ms */
+#define AST_DEFAULT_EMULATE_DTMF_DURATION 100
+
+/*! Minimum allowed digit length - 80ms */
+#define AST_MIN_DTMF_DURATION 80
+
+/*! Minimum amount of time between the end of the last digit and the beginning
+ * of a new one - 45ms */
+#define AST_MIN_DTMF_GAP 45
/*! \brief List of channel drivers */
struct chanlist {
@@ -2070,7 +2079,8 @@
prestate = chan->_state;
if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) &&
- !ast_strlen_zero(chan->dtmfq)) {
+ !ast_strlen_zero(chan->dtmfq) &&
+ (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
/* We have DTMF that has been deferred. Return it now */
chan->dtmff.subclass = chan->dtmfq[0];
/* Drop first digit from the buffer */
@@ -2083,8 +2093,8 @@
ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
chan->emulate_dtmf_digit = f->subclass;
chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
- chan->dtmf_begin_tv = ast_tvnow();
- }
+ }
+ chan->dtmf_tv = ast_tvnow();
goto done;
}
@@ -2222,35 +2232,51 @@
ast_frfree(f);
f = &ast_null_frame;
} else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
- f->frametype = AST_FRAME_DTMF_BEGIN;
- ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = f->subclass;
- chan->dtmf_begin_tv = ast_tvnow();
- if (f->len && f->len > AST_DEFAULT_EMULATE_DTMF_DURATION)
- chan->emulate_dtmf_duration = f->len;
- else
- chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
+ if (!ast_tvzero(chan->dtmf_tv) &&
+ ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
+ /* If it hasn't been long enough, defer this digit */
+ if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
+ chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
+ else
+ ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
+ ast_frfree(f);
+ f = &ast_null_frame;
+ } else {
+ /* There was no begin, turn this into a begin and send the end later */
+ f->frametype = AST_FRAME_DTMF_BEGIN;
+ ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
+ chan->emulate_dtmf_digit = f->subclass;
+ chan->dtmf_tv = ast_tvnow();
+ if (f->len && f->len > AST_MIN_DTMF_DURATION)
+ chan->emulate_dtmf_duration = f->len;
+ else
+ chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
+ }
} else {
+ struct timeval now = ast_tvnow();
ast_clear_flag(chan, AST_FLAG_IN_DTMF);
if (!f->len)
- f->len = ast_tvdiff_ms(ast_tvnow(), chan->dtmf_begin_tv);
- if (f->len < AST_DEFAULT_EMULATE_DTMF_DURATION) {
+ f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
+ if (f->len < AST_MIN_DTMF_DURATION) {
ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
chan->emulate_dtmf_digit = f->subclass;
- chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION - f->len;
+ chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
f = &ast_null_frame;
- }
+ } else
+ chan->dtmf_tv = now;
}
break;
case AST_FRAME_DTMF_BEGIN:
send_dtmf_event(chan, "Received", f->subclass, "Yes", "No");
ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
- if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY)) {
+ if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY) ||
+ (!ast_tvzero(chan->dtmf_tv) &&
+ ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
ast_frfree(f);
f = &ast_null_frame;
} else {
ast_set_flag(chan, AST_FLAG_IN_DTMF);
- chan->dtmf_begin_tv = ast_tvnow();
+ chan->dtmf_tv = ast_tvnow();
}
break;
case AST_FRAME_VOICE:
@@ -2268,10 +2294,12 @@
f = &ast_null_frame;
} else if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
if ((f->samples / 8) >= chan->emulate_dtmf_duration) { /* XXX 8kHz */
+ struct timeval now = ast_tvnow();
chan->emulate_dtmf_duration = 0;
f->frametype = AST_FRAME_DTMF_END;
f->subclass = chan->emulate_dtmf_digit;
- f->len = ast_tvdiff_ms(ast_tvnow(), chan->dtmf_begin_tv);
+ f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
+ chan->dtmf_tv = now;
} else {
chan->emulate_dtmf_duration -= f->samples / 8; /* XXX 8kHz */
ast_frfree(f);
More information about the asterisk-commits
mailing list