summaryrefslogtreecommitdiff
path: root/main/dsp.c
diff options
context:
space:
mode:
authorAlec L Davis <sivad.a@paradise.net.nz>2012-09-05 07:43:32 +0000
committerAlec L Davis <sivad.a@paradise.net.nz>2012-09-05 07:43:32 +0000
commit7af245a4033afcea69736999bbf31a7c55fdc1a9 (patch)
tree0c648b60a976e2ba941d16b195eba0402ed3d714 /main/dsp.c
parent2f9f9ecffbe2b74b2e02229ece4df8b11fe75e2b (diff)
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 ........ Merged revisions 372240 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 372241 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@372242 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/dsp.c')
-rw-r--r--main/dsp.c121
1 files changed, 86 insertions, 35 deletions
diff --git a/main/dsp.c b/main/dsp.c
index 884f610e7..6ba9abdaa 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.
@@ -438,7 +438,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
@@ -550,7 +550,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);
@@ -727,39 +727,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 */