Skip to contentSkip to conversation

i4l dtmf errors

PATCH In review Roy Sigurd Karlsbakk 4 participants 8 messages Dec 12, 2002 – Jan 6, 2003

lore
Share & tools
lore
#0 lore raw

hi

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

see thread "[MGCP] Asterisk/D-Link phones generates ugly DTMF tones!!!" at
http://www.marko.net/asterisk/archives/ for more info.

roy

Signature · 6 lines
Roy Sigurd Karlsbakk, Datavaktmester
ProntoTV AS - http://www.pronto.tv/
Tel: +47 9801 3356

Computers are like air conditioners.
They stop working when you open Windows.
#1 lore raw

This is possibly more of [email protected] list thing,
than linux-kernel per se.

Quoted 8 lines · Roy Sigurd Karlsbakk

hi

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

see thread "[MGCP] Asterisk/D-Link phones generates ugly DTMF tones!!!" at
http://www.marko.net/asterisk/archives/ for more info.

Quick reading of drivers/isdn/isdn_audio.c(*) shows that it does use fixed-point Görtzel (Goertzel in english) algorithm for detecting tones, but it does _not_ do comparison of received overall signal power vs. detected DTMF tone powers.

When there is signal power outside the DTMF channels, signal should not be detected. Also, DTMF tone powers should be roughly equal, and exactly two tones should be present for valid detection.

http://www.numerix-dsp.com/goertzel.html

Adding those power tests should be fairly trivial, but I leave it to Somebody Else...

(*) kernel version I looked upon was 2.4.16-0.11custom -- some RH kernel

Quoted 5 lines

roy

Signature · 3 lines
Roy Sigurd Karlsbakk, Datavaktmester
ProntoTV AS - http://www.pronto.tv/
Tel: +47 9801 3356

/Matti Aarnio

#2 lore raw
Quoted 5 lines

Quick reading of drivers/isdn/isdn_audio.c(*) shows that it does use fixed-point Görtzel (Goertzel in english) algorithm for detecting tones, but it does _not_ do comparison of received overall signal power vs. detected DTMF tone powers.

Quoted 8 lines

When there is signal power outside the DTMF channels, signal should not be detected. Also, DTMF tone powers should be roughly equal, and exactly two tones should be present for valid detection.

http://www.numerix-dsp.com/goertzel.html

Adding those power tests should be fairly trivial, but I leave it to Somebody Else...

Is there a 'somebody else' (perhaps the isdn maintainer?) that have time to look at this?

thanks

roy

Signature · 6 lines
Roy Sigurd Karlsbakk, Datavaktmester
ProntoTV AS - http://www.pronto.tv/
Tel: +47 9801 3356

Computers are like air conditioners.
They stop working when you open Windows.
#3 lore raw
In reply to Roy Sigurd Karlsbakk
Quoted 5 lines · Roy Sigurd Karlsbakk

hi

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

The DTMF detection is broken since kernel 2.0.x. I have a patch for a 2.2 kernel which may manually be applied 2.4 kernels with some manual work. It fixes an overflow problem in the goertzel algorithm (which does the basic tone detection) and changes the algorithm to detect the DTMF pairs. If interested, I can try to recover that patch.

Wolfgang

Quoted 5 lines

see thread "[MGCP] Asterisk/D-Link phones generates ugly DTMF tones!!!" at http://www.marko.net/asterisk/archives/ for more info.

roy

#4 lore raw
Quoted 9 lines · Wolfgang Fritz
Quoted 3 lines

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

The DTMF detection is broken since kernel 2.0.x. I have a patch for a 2.2 kernel which may manually be applied 2.4 kernels with some manual work. It fixes an overflow problem in the goertzel algorithm (which does the basic tone detection) and changes the algorithm to detect the DTMF pairs. If interested, I can try to recover that patch.

If you dig out that patch and submit it (to me), I'm pretty sure there's a good chance of it going into the official kernel. ISTR there was talk about that earlier, but nothing ever happened.

--Kai

#5 lore raw

PATCH 1/1 (Was: i4l dtmf errors)

<veröffentlicht & per Mail versendet>

Quoted 12 lines · Kai Germaschewski
Quoted 9 lines · Wolfgang Fritz
Quoted 3 lines

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

The DTMF detection is broken since kernel 2.0.x. I have a patch for a 2.2 kernel which may manually be applied 2.4 kernels with some manual work. It fixes an overflow problem in the goertzel algorithm (which does the basic tone detection) and changes the algorithm to detect the DTMF pairs. If interested, I can try to recover that patch.

Quoted 6 lines

If you dig out that patch and submit it (to me), I'm pretty sure there's a good chance of it going into the official kernel. ISTR there was talk about that earlier, but nothing ever happened.

--Kai

Here is the patch against 2.4.20.

Wolfgang

Quoted 6 lines

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

drivers/isdn/isdn_audio.c +58 -36
diff -urN -X dontdiff linux-2.4.20/drivers/isdn/isdn_audio.c linux-2.4.20.mod/drivers/isdn/isdn_audio.c
@@ -169,39 +169,19 @@
 	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
 };
 
-#define NCOEFF           16     /* number of frequencies to be analyzed       */
-#define DTMF_TRESH    25000     /* above this is dtmf                         */
+#define NCOEFF            8     /* number of frequencies to be analyzed       */
+#define DTMF_TRESH     4000     /* above this is dtmf                         */
 #define SILENCE_TRESH   200     /* below this is silence                      */
-#define H2_TRESH      20000     /* 2nd harmonic                               */
 #define AMP_BITS          9     /* bits per sample, reduced to avoid overflow */
 #define LOGRP             0
 #define HIGRP             1
 
-typedef struct {
-	int grp;                /* low/high group     */
-	int k;                  /* k                  */
-	int k2;                 /* k fuer 2. harmonic */
-} dtmf_t;
-
 /* For DTMF recognition:
  * 2 * cos(2 * PI * k / N) precalculated for all k
  */
 static int cos2pik[NCOEFF] =
 {
-	55812, 29528, 53603, 24032, 51193, 14443, 48590, 6517,
-	38113, -21204, 33057, -32186, 25889, -45081, 18332, -55279
-};
-
-static dtmf_t dtmf_tones[8] =
-{
-	{LOGRP, 0, 1},          /*  697 Hz */
-	{LOGRP, 2, 3},          /*  770 Hz */
-	{LOGRP, 4, 5},          /*  852 Hz */
-	{LOGRP, 6, 7},          /*  941 Hz */
-	{HIGRP, 8, 9},          /* 1209 Hz */
-	{HIGRP, 10, 11},        /* 1336 Hz */
-	{HIGRP, 12, 13},        /* 1477 Hz */
-	{HIGRP, 14, 15}         /* 1633 Hz */
+	55813, 53604, 51193, 48591, 38114, 33057, 25889, 18332
 };
 
 static char dtmf_matrix[4][4] =
@@ -499,6 +479,18 @@
 			sk2 = sk1;
 			sk1 = sk;
 		}
+		/* Avoid overflows */
+		sk >>= 1;
+		sk2 >>= 1;
+		/* compute |X(k)|**2 */
+		/* report overflows. This should not happen. */
+		/* Comment this out if desired */
+		if (sk < -32768 || sk > 32767)
+			printk(KERN_DEBUG
+			       "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
+		if (sk2 < -32768 || sk2 > 32767)
+			printk(KERN_DEBUG
+			       "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
 		result[k] =
 		    ((sk * sk) >> AMP_BITS) -
 		    ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
@@ -522,28 +514,58 @@
 	int grp[2];
 	char what;
 	char *p;
+	int thresh;
 
 	while ((skb = skb_dequeue(&info->dtmf_queue))) {
 		result = (int *) skb->data;
 		s = info->dtmf_state;
-		grp[LOGRP] = grp[HIGRP] = -2;
+		grp[LOGRP] = grp[HIGRP] = -1;
 		silence = 0;
-		for (i = 0; i < 8; i++) {
-			if ((result[dtmf_tones[i].k] > DTMF_TRESH) &&
-			    (result[dtmf_tones[i].k2] < H2_TRESH))
-				grp[dtmf_tones[i].grp] = (grp[dtmf_tones[i].grp] == -2) ? i : -1;
-			else if ((result[dtmf_tones[i].k] < SILENCE_TRESH) &&
-			      (result[dtmf_tones[i].k2] < SILENCE_TRESH))
+		thresh = 0;
+		for (i = 0; i < NCOEFF; i++) {
+			if (result[i] > DTMF_TRESH) {
+				if (result[i] > thresh)
+					thresh = result[i];
+			}
+			else if (result[i] < SILENCE_TRESH)
 				silence++;
 		}
-		if (silence == 8)
+		if (silence == NCOEFF)
 			what = ' ';
 		else {
-			if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
-				what = dtmf_matrix[grp[LOGRP]][grp[HIGRP] - 4];
-				if (s->last != ' ' && s->last != '.')
-					s->last = what;	/* min. 1 non-DTMF between DTMF */
-			} else
+			if (thresh > 0)	{
+				thresh = thresh >> 4;  /* touchtones must match within 12 dB */
+				for (i = 0; i < NCOEFF; i++) {
+					if (result[i] < thresh)
+						continue;  /* ignore */
+					/* good level found. This is allowed only one time per group */
+					if (i < NCOEFF / 2) {
+						/* lowgroup*/
+						if (grp[LOGRP] >= 0) {
+							// Bad. Another tone found. */
+							grp[LOGRP] = -1;
+							break;
+						}
+						else
+							grp[LOGRP] = i;
+					}
+					else { /* higroup */
+						if (grp[HIGRP] >= 0) { // Bad. Another tone found. */
+							grp[HIGRP] = -1;
+							break;
+						}
+						else
+							grp[HIGRP] = i - NCOEFF/2;
+					}
+				}
+				if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
+					what = dtmf_matrix[grp[LOGRP]][grp[HIGRP]];
+					if (s->last != ' ' && s->last != '.')
+						s->last = what;	/* min. 1 non-DTMF between DTMF */
+				} else
+					what = '.';
+			}
+			else
 				what = '.';
 		}
 		if ((what != s->last) && (what != ' ') && (what != '.')) {
drivers/isdn/isdn_audio.h +1 -0
diff -urN -X dontdiff linux-2.4.20/drivers/isdn/isdn_audio.h linux-2.4.20.mod/drivers/isdn/isdn_audio.h
@@ -20,6 +20,7 @@
 
 typedef struct dtmf_state {
 	char last;
+	char llast;
 	int idx;
 	int buf[DTMF_NPOINTS];
 } dtmf_state;
#6 lore raw

Re: [PATCH] (Was: i4l dtmf errors)

hi

thanks for the patch, but sorry - it really didn't help anything. still meep-meep's all over ...

roy

Quoted 29 lines · Wolfgang Fritz

<veröffentlicht & per Mail versendet>

Quoted 11 lines · Kai Germaschewski
Quoted 9 lines · Wolfgang Fritz
Quoted 3 lines

it seems isdn4linux detects DTMF tones from normal speach. This is rather annoying when using i4l for voice with Asterisk.org. This is tested on all recent kernels

The DTMF detection is broken since kernel 2.0.x. I have a patch for a 2.2 kernel which may manually be applied 2.4 kernels with some manual work. It fixes an overflow problem in the goertzel algorithm (which does the basic tone detection) and changes the algorithm to detect the DTMF pairs. If interested, I can try to recover that patch.

Quoted 5 lines

If you dig out that patch and submit it (to me), I'm pretty sure there's a good chance of it going into the official kernel. ISTR there was talk about that earlier, but nothing ever happened.

--Kai

Here is the patch against 2.4.20.

Wolfgang

Quoted 5 lines

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Signature · 6 lines
Roy Sigurd Karlsbakk, Datavaktmester
ProntoTV AS - http://www.pronto.tv/
Tel: +47 9801 3356

Computers are like air conditioners.
They stop working when you open Windows.
#7 lore raw
In reply to Wolfgang Fritz
Quoted 5 lines

The DTMF detection is broken since kernel 2.0.x. I have a patch for a 2.2 kernel which may manually be applied 2.4 kernels with some manual work. It fixes an overflow problem in the goertzel algorithm (which does the basic tone detection) and changes the algorithm to detect the DTMF pairs. If interested, I can try to recover that patch.

I'm very interested, as the alternative is to rewrite Asterisk (dot org) to use it's own. Today, I get beeps whenever I speak on the phone - espessialy with my girlfriend ;-P

roy

Signature · 6 lines
Roy Sigurd Karlsbakk, Datavaktmester
ProntoTV AS - http://www.pronto.tv/
Tel: +47 9801 3356

Computers are like air conditioners.
They stop working when you open Windows.