[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