mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	Fix an issue where dsp.c would interpret multiple dtmf events from a single key press.
When receiving calls from a mobile phone into a DISA system on a connection with significant interference, the reporter's Asterisk system would interpret DTMF incorrectly and replicate digits received. This patch resolves that by increasing the number of frames a mismatch has to be detected before assuming the DTMF is over by 1 frame and adjusts dtmf_detect function to reset hits and misses only when an edge is detected. (closes issue ASTERISK-17493) Reported by: Alec Davis Patches: bug18904-refactor.diff.txt uploaded by Alec Davis (license 5546) Review: https://reviewboard.asterisk.org/r/1130/ ........ Merged revisions 349728 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 349729 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@349730 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										63
									
								
								main/dsp.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								main/dsp.c
									
									
									
									
									
								
							@@ -201,9 +201,9 @@ enum gsamp_thresh {
 | 
			
		||||
#define DTMF_GSIZE		102
 | 
			
		||||
 | 
			
		||||
/* How many successive hits needed to consider begin of a digit */
 | 
			
		||||
#define DTMF_HITS_TO_BEGIN	2
 | 
			
		||||
#define DTMF_HITS_TO_BEGIN	4
 | 
			
		||||
/* How many successive misses needed to consider end of a digit */
 | 
			
		||||
#define DTMF_MISSES_TO_END	3
 | 
			
		||||
#define DTMF_MISSES_TO_END	4
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \brief The default silence threshold we will use if an alternate
 | 
			
		||||
@@ -721,42 +721,41 @@ static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (s->td.dtmf.current_hit) {
 | 
			
		||||
			/* We are in the middle of a digit already */
 | 
			
		||||
			if (hit != s->td.dtmf.current_hit) {
 | 
			
		||||
				s->td.dtmf.misses++;
 | 
			
		||||
				if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
 | 
			
		||||
					/* There were enough misses to consider digit ended */
 | 
			
		||||
					s->td.dtmf.current_hit = 0;
 | 
			
		||||
		if (hit == s->td.dtmf.lasthit) {
 | 
			
		||||
			if (s->td.dtmf.current_hit) {
 | 
			
		||||
				/* We are in the middle of a digit already */
 | 
			
		||||
				if (hit) {
 | 
			
		||||
					if (hit != s->td.dtmf.current_hit) {
 | 
			
		||||
						/* Look for a start of a new digit.
 | 
			
		||||
						   This is because hits_to_begin may be smaller than misses_to_end
 | 
			
		||||
						   and we may find the beginning of new digit before we consider last one ended. */
 | 
			
		||||
						s->td.dtmf.current_hit = 0;
 | 
			
		||||
					} else {
 | 
			
		||||
						/* Current hit was same as last, so increment digit duration (of last digit) */
 | 
			
		||||
						s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					/* No Digit */
 | 
			
		||||
					s->td.dtmf.misses++;
 | 
			
		||||
					if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
 | 
			
		||||
						/* There were enough misses to consider digit ended */
 | 
			
		||||
						s->td.dtmf.current_hit = 0;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				s->td.dtmf.misses = 0;
 | 
			
		||||
				/* Current hit was same as last, so increment digit duration (of last digit) */
 | 
			
		||||
				s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Look for a start of a new digit no matter if we are already in the middle of some
 | 
			
		||||
		   digit or not. This is because hits_to_begin may be smaller than misses_to_end
 | 
			
		||||
		   and we may find begin of new digit before we consider last one ended. */
 | 
			
		||||
		if (hit) {
 | 
			
		||||
			if (hit == s->td.dtmf.lasthit) {
 | 
			
		||||
			} else if (hit) {
 | 
			
		||||
				/* Detecting new digit */
 | 
			
		||||
				s->td.dtmf.hits++;
 | 
			
		||||
			} else {
 | 
			
		||||
				s->td.dtmf.hits = 1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin && hit != s->td.dtmf.current_hit) {
 | 
			
		||||
				store_digit(s, hit);
 | 
			
		||||
				s->td.dtmf.current_hit = hit;
 | 
			
		||||
				s->td.dtmf.misses = 0;
 | 
			
		||||
				if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin) {
 | 
			
		||||
					store_digit(s, hit);
 | 
			
		||||
					s->td.dtmf.current_hit = hit;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			s->td.dtmf.hits = 0;
 | 
			
		||||
			s->td.dtmf.hits = 1;
 | 
			
		||||
			s->td.dtmf.misses = 1;
 | 
			
		||||
			s->td.dtmf.lasthit = hit;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s->td.dtmf.lasthit = hit;
 | 
			
		||||
 | 
			
		||||
		/* If we had a hit in this block, include it into mute fragment */
 | 
			
		||||
		if (squelch && hit) {
 | 
			
		||||
			if (mute.end < sample - DTMF_GSIZE) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user