Forums

DTMF detection through Sound Card

Started by dkurman January 14, 2006
Hi. I have posted two messages, but I can�t get this working. I mean, I'm
getting the buffer from the sound card, and then I perform the goertzel
algorithm with this, but the data I get is wrong almost all times.

The steps are:

Data: Buffer Size: 4096 Kb, N=4096, Sample Rate = 22050, Format: 16 bits

1) When I get the buffer completely filled, I read the buffer (two bytes a
time) converting the bytes into float types and puting them in a float
array.
2) I perform goertzel in the low and high freq, puting the results in a
float array
3) Get the two highest values
4) Find if these two highest values belong one to low and the other to
high.
5) Check for minimum energy of these two goertzel values (Which could be
these minimum energy?). I put the values I found, I mean. If without DTMF,
the values are 1000 then, this is the minimum.
6) Check if is Normal twist or reverse
7) Check for 2nd Harmonics and compare, like: 

2nd Harmonic Goertzel Value < Highest High freq Value 
AND
(
Highest High freq Value / 2nd Harmonic Goertzel Value > 10 
OR 
2nd Harmonic Goertzel Value < Highest High freq Value * 0.25
)

8) Then I get the corresponding number values, I mean, if High=1209 and
Low=697 corresponds to 1 and show it

Almost all times I get wrong values. I&#2013266100;m performing this in C#

If someone have a sample source code in C#, Java or VB I will appreciate
if could send it to me. I'm have no more time to get this working, cause
my job is in danger.

Thanks a lot in advance
dkurman wrote:
> Hi. I have posted two messages, but I can&#2013266100;t get this working. I mean, I'm > getting the buffer from the sound card, and then I perform the goertzel > algorithm with this, but the data I get is wrong almost all times. > > The steps are: > > Data: Buffer Size: 4096 Kb, N=4096, Sample Rate = 22050, Format: 16 bits > > 1) When I get the buffer completely filled, I read the buffer (two bytes a > time) converting the bytes into float types and puting them in a float > array. > 2) I perform goertzel in the low and high freq, puting the results in a > float array > 3) Get the two highest values > 4) Find if these two highest values belong one to low and the other to > high. > 5) Check for minimum energy of these two goertzel values (Which could be > these minimum energy?). I put the values I found, I mean. If without DTMF, > the values are 1000 then, this is the minimum. > 6) Check if is Normal twist or reverse > 7) Check for 2nd Harmonics and compare, like: > > 2nd Harmonic Goertzel Value < Highest High freq Value > AND > ( > Highest High freq Value / 2nd Harmonic Goertzel Value > 10 > OR > 2nd Harmonic Goertzel Value < Highest High freq Value * 0.25 > ) > > 8) Then I get the corresponding number values, I mean, if High=1209 and > Low=697 corresponds to 1 and show it > > Almost all times I get wrong values. I&#2013266100;m performing this in C# > > If someone have a sample source code in C#, Java or VB I will appreciate > if could send it to me. I'm have no more time to get this working, cause > my job is in danger. > > Thanks a lot in advance
Try testing the pieces. Get an audio signal generator and verify that you can detect the individual tones with your Goertzel algorithms. Once you've verified that, instrument your code so you can see all the statistics you're generating -- look for some pattern to what may be causing problems. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com

dkurman wrote:

> Hi. I have posted two messages, but I can=B4t get this working. I mean,=
I'm
> getting the buffer from the sound card, and then I perform the goertzel=
> algorithm with this, but the data I get is wrong almost all times.
The DTMF detection is the simplest thing in the world. You don't need=20 Goertzel to do that. Some idiot posted Goertzel on the application notes = while ago and everybody else mimics this stuff since then. The magic=20 manipulations with the second harmonics is nothing but an attempt to=20 simulate the operation of the analog DTMF receivers of old times. This=20 is not the most efficient and best performance algorithm. This is how you should do DTMF: 1. Multiply the input by sin and cos for all eight frequencies. 2. Accumulate the I and Q products with the exponential averager T ~ 50ms= =2E 3. Calculate amplitudes I^2 + Q^2 every ~ 20ms 4. Find two biggest amplitudes and check for valid DTMF symbol. 5. Compare the two biggest amplitudes against the third to biggest=20 amplitude for validity. 6. Compare the smallest of two to the treshold for validity. 7. Enjoy. Hints: 1. Sin and Cos are unnecessary. The square wave will work just as good. 2. sqrt(x^2 + y^2) ~ max(|x|,|y|) + 0.25*min(|x|,|y|) 3. You don't need any multiplications at all. 4. If you don't have the ADC, you may use comparator. Just one bit=20 quantization will work if the signal is good enough. 4. All of that can be done with just about any microcontroller of 1 MIPS.=
>=20 > The steps are: >=20 > Data: Buffer Size: 4096 Kb, N=3D4096, Sample Rate =3D 22050, Format: 16=
bits
>=20 > 1) When I get the buffer completely filled, I read the buffer (two byte=
s a
> time) converting the bytes into float types and puting them in a float > array. > 2) I perform goertzel in the low and high freq, puting the results in a=
> float array > 3) Get the two highest values > 4) Find if these two highest values belong one to low and the other to > high. > 5) Check for minimum energy of these two goertzel values (Which could b=
e
> these minimum energy?). I put the values I found, I mean. If without DT=
MF,
> the values are 1000 then, this is the minimum. > 6) Check if is Normal twist or reverse > 7) Check for 2nd Harmonics and compare, like:=20 >=20 > 2nd Harmonic Goertzel Value < Highest High freq Value=20 > AND > ( > Highest High freq Value / 2nd Harmonic Goertzel Value > 10=20 > OR=20 > 2nd Harmonic Goertzel Value < Highest High freq Value * 0.25 > ) >=20 > 8) Then I get the corresponding number values, I mean, if High=3D1209 a=
nd
> Low=3D697 corresponds to 1 and show it >=20 > Almost all times I get wrong values. I=B4m performing this in C#
The unnecessary knowledge only harms. Using the things that you have a=20 litte understanding of is not going to work.
> If someone have a sample source code in C#, Java or VB I will appreciat=
e
> if could send it to me. I'm have no more time to get this working, caus=
e
> my job is in danger.
No problem. $1000. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
Tim: I already tried this. I have a tone generator by soft and the goertzel
did work. But when I change to detect through sound it doesn&#2013266100;t work any
more. I think the problem is about the sampling and buffering or maybe
when I convert from byte to float.

Vladimir: I will try what you said

You wrote: 
>5. Compare the two biggest amplitudes against the third to biggest=20 >amplitude for validity.
What do you mean with compare?. What are the values for valid DTMF. I mean is something like with 2nd Harmonics?, like: Highest High freq Value / 2nd Harmonic Goertzel Value > 10?
>6. Compare the smallest of two to the treshold for validity.
This is another black hole. I saw the threshold is between 6 and 8 in commercial software, but I can&#2013266100;t compare with these thresholds cause the values are bigger than 6 or 8, I&#2013266100;m talking about values between 1000 and 5000 without tones. How do you compare with this? Thanks in advance. Daniel
> > >dkurman wrote: > >> Hi. I have posted two messages, but I can=B4t get this working. I
mean,=
> I'm >> getting the buffer from the sound card, and then I perform the
goertzel=
> >> algorithm with this, but the data I get is wrong almost all times. > > >The DTMF detection is the simplest thing in the world. You don't need=20 >Goertzel to do that. Some idiot posted Goertzel on the application notes
=
> >while ago and everybody else mimics this stuff since then. The magic=20 >manipulations with the second harmonics is nothing but an attempt to=20 >simulate the operation of the analog DTMF receivers of old times.
This=20
>is not the most efficient and best performance algorithm. > >This is how you should do DTMF: > >1. Multiply the input by sin and cos for all eight frequencies. >2. Accumulate the I and Q products with the exponential averager T ~
50ms=
>=2E >3. Calculate amplitudes I^2 + Q^2 every ~ 20ms >4. Find two biggest amplitudes and check for valid DTMF symbol. >5. Compare the two biggest amplitudes against the third to biggest=20 >amplitude for validity. >6. Compare the smallest of two to the treshold for validity. >7. Enjoy. > >Hints: > >1. Sin and Cos are unnecessary. The square wave will work just as good. >2. sqrt(x^2 + y^2) ~ max(|x|,|y|) + 0.25*min(|x|,|y|) >3. You don't need any multiplications at all. >4. If you don't have the ADC, you may use comparator. Just one bit=20 >quantization will work if the signal is good enough. >4. All of that can be done with just about any microcontroller of 1
MIPS.=
> > > >>=20 >> The steps are: >>=20 >> Data: Buffer Size: 4096 Kb, N=3D4096, Sample Rate =3D 22050, Format:
16=
> bits >>=20 >> 1) When I get the buffer completely filled, I read the buffer (two
byte=
>s a >> time) converting the bytes into float types and puting them in a float >> array. >> 2) I perform goertzel in the low and high freq, puting the results in
a=
> >> float array >> 3) Get the two highest values >> 4) Find if these two highest values belong one to low and the other to >> high. >> 5) Check for minimum energy of these two goertzel values (Which could
b=
>e >> these minimum energy?). I put the values I found, I mean. If without
DT=
>MF, >> the values are 1000 then, this is the minimum. >> 6) Check if is Normal twist or reverse >> 7) Check for 2nd Harmonics and compare, like:=20 >>=20 >> 2nd Harmonic Goertzel Value < Highest High freq Value=20 >> AND >> ( >> Highest High freq Value / 2nd Harmonic Goertzel Value > 10=20 >> OR=20 >> 2nd Harmonic Goertzel Value < Highest High freq Value * 0.25 >> ) >>=20 >> 8) Then I get the corresponding number values, I mean, if High=3D1209
a=
>nd >> Low=3D697 corresponds to 1 and show it >>=20 >> Almost all times I get wrong values. I=B4m performing this in C# > >The unnecessary knowledge only harms. Using the things that you have
a=20
>litte understanding of is not going to work. > >> If someone have a sample source code in C#, Java or VB I will
appreciat=
>e >> if could send it to me. I'm have no more time to get this working,
caus=
>e >> my job is in danger. > >No problem. $1000. > >Vladimir Vassilevsky > >DSP and Mixed Signal Design Consultant > >http://www.abvolt.com > > >
dkurman wrote:
> Tim: I already tried this. I have a tone generator by soft and the goertzel > did work. But when I change to detect through sound it doesn&#2013266100;t work any > more. I think the problem is about the sampling and buffering or maybe > when I convert from byte to float.
Then you've verified your algorithm -- now you should verify the rest. Get a _real_ tone generator, one that puts a wiggly voltage into your sound card. At the very least play tones out of one sound card and into another. If you suspect that the sampling, buffering, or byte to float conversion isn't working, why don't you take the numbers you're getting and graph them, to see if they look right? If that's screwed up you'll never get any sensible results from later stages.
> > Vladimir: I will try what you said > > You wrote: > >>5. Compare the two biggest amplitudes against the third to biggest=20 >>amplitude for validity. > > > What do you mean with compare?. What are the values for valid DTMF. I mean > is something like with 2nd Harmonics?, like: Highest High freq Value / 2nd > Harmonic Goertzel Value > 10?
There are specs out there that will tell you. In their absence you'll have to go by measured values -- which will be meaningless if you're not acquiring your data right.
> > >>6. Compare the smallest of two to the treshold for validity. > > > This is another black hole. I saw the threshold is between 6 and 8 in > commercial software, but I can&#2013266100;t compare with these thresholds cause the > values are bigger than 6 or 8, I&#2013266100;m talking about values between 1000 and > 5000 without tones. How do you compare with this?
Thresholds of '6' or '6000' mean nothing unless you have some scaling information. The scaling will be determined by how you treat your numbers coming in, and the gain of your particular implementation of the filters (by the way I suspect that Vladimir is right with his suggestion to use FIR filters rather than IIR -- but if your Goertzel algorithm itself isn't the problem then you probably want to stick with it for now).
> > Thanks in advance. > > Daniel > >> >>dkurman wrote: >> >> >>>Hi. I have posted two messages, but I can=B4t get this working. I > > mean,= > >>I'm >> >>>getting the buffer from the sound card, and then I perform the > > goertzel= > >>>algorithm with this, but the data I get is wrong almost all times. >> >> >>The DTMF detection is the simplest thing in the world. You don't need=20 >>Goertzel to do that. Some idiot posted Goertzel on the application notes > > = > >>while ago and everybody else mimics this stuff since then. The magic=20 >>manipulations with the second harmonics is nothing but an attempt to=20 >>simulate the operation of the analog DTMF receivers of old times. > > This=20 > >>is not the most efficient and best performance algorithm. >> >>This is how you should do DTMF: >> >>1. Multiply the input by sin and cos for all eight frequencies. >>2. Accumulate the I and Q products with the exponential averager T ~ > > 50ms= > >>=2E >>3. Calculate amplitudes I^2 + Q^2 every ~ 20ms >>4. Find two biggest amplitudes and check for valid DTMF symbol. >>5. Compare the two biggest amplitudes against the third to biggest=20 >>amplitude for validity. >>6. Compare the smallest of two to the treshold for validity. >>7. Enjoy. >> >>Hints: >> >>1. Sin and Cos are unnecessary. The square wave will work just as good. >>2. sqrt(x^2 + y^2) ~ max(|x|,|y|) + 0.25*min(|x|,|y|) >>3. You don't need any multiplications at all. >>4. If you don't have the ADC, you may use comparator. Just one bit=20 >>quantization will work if the signal is good enough. >>4. All of that can be done with just about any microcontroller of 1 > > MIPS.= > >> >> >>>=20 >>>The steps are: >>>=20 >>>Data: Buffer Size: 4096 Kb, N=3D4096, Sample Rate =3D 22050, Format: > > 16= > >>bits >> >>>=20 >>>1) When I get the buffer completely filled, I read the buffer (two > > byte= > >>s a >> >>>time) converting the bytes into float types and puting them in a float >>>array. >>>2) I perform goertzel in the low and high freq, puting the results in > > a= > >>>float array >>>3) Get the two highest values >>>4) Find if these two highest values belong one to low and the other to >>>high. >>>5) Check for minimum energy of these two goertzel values (Which could > > b= > >>e >> >>>these minimum energy?). I put the values I found, I mean. If without > > DT= > >>MF, >> >>>the values are 1000 then, this is the minimum. >>>6) Check if is Normal twist or reverse >>>7) Check for 2nd Harmonics and compare, like:=20 >>>=20 >>>2nd Harmonic Goertzel Value < Highest High freq Value=20 >>>AND >>>( >>>Highest High freq Value / 2nd Harmonic Goertzel Value > 10=20 >>>OR=20 >>>2nd Harmonic Goertzel Value < Highest High freq Value * 0.25 >>>) >>>=20 >>>8) Then I get the corresponding number values, I mean, if High=3D1209 > > a= > >>nd >> >>>Low=3D697 corresponds to 1 and show it >>>=20 >>>Almost all times I get wrong values. I=B4m performing this in C# >> >>The unnecessary knowledge only harms. Using the things that you have > > a=20 > >>litte understanding of is not going to work. >> >> >>>If someone have a sample source code in C#, Java or VB I will > > appreciat= > >>e >> >>>if could send it to me. I'm have no more time to get this working, > > caus= > >>e >> >>>my job is in danger. >> >>No problem. $1000. >> >>Vladimir Vassilevsky >> >>DSP and Mixed Signal Design Consultant >> >>http://www.abvolt.com >> >> >> > > >
-- Tim Wescott Wescott Design Services http://www.wescottdesign.com