[asterisk-commits] russell: branch 1.4 r62942 -
/branches/1.4/main/channel.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu May 3 08:23:13 MST 2007
Author: russell
Date: Thu May 3 10:23:13 2007
New Revision: 62942
URL: http://svn.digium.com/view/asterisk?view=rev&rev=62942
Log:
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end. This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
back null frames, not voice frames. So, I have modified ast_read to check
the timing on emulated DTMF when it receives null frames, in addition to
where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits. If there was
no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
frames that pass through, just use time values. Now there is no code in this
section that assumes 8kHz audio.
Modified:
branches/1.4/main/channel.c
Modified: branches/1.4/main/channel.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/channel.c?view=diff&rev=62942&r1=62941&r2=62942
==============================================================================
--- branches/1.4/main/channel.c (original)
+++ branches/1.4/main/channel.c Thu May 3 10:23:13 2007
@@ -2293,10 +2293,13 @@
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;
+ if (f->len) {
+ if (f->len > AST_MIN_DTMF_DURATION)
+ chan->emulate_dtmf_duration = f->len;
+ else
+ chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
+ } else
+ chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
}
} else {
struct timeval now = ast_tvnow();
@@ -2324,9 +2327,23 @@
chan->dtmf_tv = ast_tvnow();
}
break;
+ case AST_FRAME_NULL:
+ if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
+ struct timeval now = ast_tvnow();
+ if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
+ chan->emulate_dtmf_duration = 0;
+ f->frametype = AST_FRAME_DTMF_END;
+ f->subclass = chan->emulate_dtmf_digit;
+ f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
+ chan->dtmf_tv = now;
+ ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
+ chan->emulate_dtmf_digit = 0;
+ }
+ }
+ break;
case AST_FRAME_VOICE:
- /* The EMULATE_DTMF flag must be cleared here as opposed to when the samples
- * first get to zero, because we want to make sure we pass at least one
+ /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
+ * is reached , because we want to make sure we pass at least one
* voice frame through before starting the next digit, to ensure a gap
* between DTMF digits. */
if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
@@ -2338,15 +2355,15 @@
ast_frfree(f);
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();
+ struct timeval now = ast_tvnow();
+ if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
chan->emulate_dtmf_duration = 0;
f->frametype = AST_FRAME_DTMF_END;
f->subclass = chan->emulate_dtmf_digit;
f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
chan->dtmf_tv = now;
} else {
- chan->emulate_dtmf_duration -= f->samples / 8; /* XXX 8kHz */
+ /* Drop voice frames while we're still in the middle of the digit */
ast_frfree(f);
f = &ast_null_frame;
}
More information about the asterisk-commits
mailing list