aboutsummaryrefslogtreecommitdiffstats
path: root/main/asterisk/ASTERISK-19610b.patch
blob: e31226cd9162b71a9d8a60ce6bb9aedf73e445b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
commit fd63c4b
Author: alecdavis <alecdavis@f38db490-d61c-443f-a65b-d21fe96a405b>
Date:   Wed Sep 5 07:37:42 2012 +0000

    dsp.c: Fix multiple issues when no-interdigit delay is present, and fast DTMF 50ms/50ms
    
    Revert DTMF hit/miss detector to original -r349249 method with some changes, remove unnecessary;
      1. reseting of hits=0, when no signal, only need to set it once.
      2. incrementing of hits, when the hit is the same as the current hit.
      3. setting of lasthit, when it's the same as before.
    
    Change HITS_TO_BEGIN to 2, MISSES_TO_END to 3
    
    & 3 spelling mistakes
    
    (closes issue ASTERISK-19610)
    alecdavis (license 585)
    Reported by: Jean-Philippe Lord
    Tested by: alecdavis
    
    Review: https://reviewboard.asterisk.org/r/2085/
    ........
    
    Merged revisions 372239 from http://svn.asterisk.org/svn/asterisk/branches/1.8
    
    
    git-svn-id: http://svn.digium.com/svn/asterisk/branches/10@372240 f38db490-d61c-443f-a65b-d21fe96a405b

diff --git a/main/dsp.c b/main/dsp.c
index 9ba4775..7541650 100644
--- a/main/dsp.c
+++ b/main/dsp.c
@@ -205,9 +205,9 @@ enum gsamp_thresh {
 #define DTMF_GSIZE		102
 
 /* How many successive hits needed to consider begin of a digit */
-#define DTMF_HITS_TO_BEGIN	4
+#define DTMF_HITS_TO_BEGIN	2
 /* How many successive misses needed to consider end of a digit */
-#define DTMF_MISSES_TO_END	4
+#define DTMF_MISSES_TO_END	3
 
 /*!
  * \brief The default silence threshold we will use if an alternate
@@ -353,7 +353,7 @@ typedef struct {
 } fragment_t;
 
 /* Note on tone suppression (squelching). Individual detectors (DTMF/MF/generic tone)
- * report fragmens of the frame in which detected tone resides and which needs
+ * report fragments of the frame in which detected tone resides and which needs
  * to be "muted" in order to suppress the tone. To mark fragment for muting,
  * detectors call mute_fragment passing fragment_t there. Multiple fragments
  * can be marked and ast_dsp_process later will mute all of them.
@@ -437,7 +437,7 @@ static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration,
 	s->block_size = periods_in_block * sample_rate / freq;
 
 	/* tone_detect is currently only used to detect fax tones and we
-	   do not need suqlching the fax tones */
+	   do not need squelching the fax tones */
 	s->squelch = 0;
 
 	/* Account for the first and the last block to be incomplete
@@ -549,7 +549,7 @@ static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp
 
 		for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
 			samp = *ptr;
-			/* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
+			/* signed 32 bit int should be enough to square any possible signed 16 bit value */
 			s->energy += (int32_t) samp * (int32_t) samp;
 
 			goertzel_sample(&s->tone, samp);
@@ -726,39 +726,90 @@ static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp
 			}
 		} 
 
-		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 if (hit) {
-				/* Detecting new digit */
-				s->td.dtmf.hits++;
-				if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin) {
-					store_digit(s, hit);
-					s->td.dtmf.current_hit = hit;
+/*
+ * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
+ * (40ms reference is tunable with hits_to_begin and misses_to_end)
+ * each hit/miss is 12.75ms with DTMF_GSIZE at 102
+ *
+ * Character recognition: When not DRC *(1) and then
+ *      Shall exist VSC > 40 ms (hits_to_begin)
+ *      May exist 20 ms <= VSC <= 40 ms
+ *      Shall not exist VSC < 20 ms
+ *
+ * Character recognition: When DRC and then
+ *      Shall cease Not VSC > 40 ms (misses_to_end)
+ *      May cease 20 ms >= Not VSC >= 40 ms
+ *      Shall not cease Not VSC < 20 ms
+ *
+ * *(1) or optionally a different digit recognition condition
+ *
+ * Legend: VSC The continuous existence of a valid signal condition.
+ *      Not VSC The continuous non-existence of valid signal condition.
+ *      DRC The existence of digit recognition condition.
+ *      Not DRC The non-existence of digit recognition condition.
+ */
+
+/*
+ * Example: hits_to_begin=2 misses_to_end=3
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2 current_hit=A misses=0       BEGIN A
+ * -----AA- misses=1 last_hit=' ' hits=0
+ * ----AA-- misses=2
+ * ---AA--- misses=3 current_hit=' '            END A
+ * --AA---B last_hit=B hits=0&1
+ * -AA---BC last_hit=C hits=0&1
+ * AA---BCC hits=2 current_hit=C misses=0       BEGIN C
+ * A---BCC- misses=1 last_hit=' ' hits=0
+ * ---BCC-C misses=0 last_hit=C hits=0&1
+ * --BCC-CC misses=0
+ *
+ * Example: hits_to_begin=3 misses_to_end=2
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2
+ * -----AAA hits=3 current_hit=A misses=0       BEGIN A
+ * ----AAAB misses=1 last_hit=B hits=0&1
+ * ---AAABB misses=2 current_hit=' ' hits=2     END A
+ * --AAABBB hits=3 current_hit=B misses=0       BEGIN B
+ * -AAABBBB misses=0
+ *
+ * Example: hits_to_begin=2 misses_to_end=2
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2 current_hit=A misses=0       BEGIN A
+ * -----AAB misses=1 hits=0&1
+ * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
+ * ---AABBB misses=0
+ */
+
+		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;
 				}
+			} 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;
 			}
-		} else {
-			s->td.dtmf.hits = 1;
-			s->td.dtmf.misses = 1;
+		}
+
+		/* 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 != s->td.dtmf.lasthit) {
 			s->td.dtmf.lasthit = hit;
+			s->td.dtmf.hits = 0;
+		}
+		if (hit && hit != s->td.dtmf.current_hit) {
+			s->td.dtmf.hits++;
+			if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin) {
+				store_digit(s, hit);
+				s->td.dtmf.current_hit = hit;
+				s->td.dtmf.misses = 0;
+			}
 		}
 
 		/* If we had a hit in this block, include it into mute fragment */