DSPRelated.com
Forums

Tone Detection

Started by Brian C. Lane August 20, 2003
I'm trying to implement a CTCSS tone detector in a C5402. I've tried to
implement a Goertzel Filter based on the DTMF decoder chapter in the
Analog Devices DSP Applications book. I'm not sure if this is the right
approach or not, and it doesn't seem to be working :<

Does anyone have any good references to tone detection articles for the
54x? I found a good article on Goertzel at
http://www.embedded.com/story/OEG20020819S0057

I've tried to implement a fixed point version in the 54x, but on noise
(its in a radio) I get occasional big spikes and on the ctcss tone it
doesn't return a very large mag^2 like it should.

Thanks,

Brian



Bonjour,

Try out the code of Schmer with SPRA096A.
Very good article about dual frequency detector is:
Felder et al. "Efficient Dual-Tone Multifrequency Detection Using
the Nonuniform DFT", july 1998, IEEE Signal Processing Letters. vol 5, no.7

What is CTCSS?

Bien vous,

Franis Caron, ing. M.Sc.
Concepteur DSP - Homologation
Les Services de SuritPublique Positron
Montrl, Quec, Canada
H4P 2R9
(514)-345-2270+2862
(514)-815-1618 (Cellulaire)

> -----Original Message-----
> From: Brian C. Lane [SMTP:]
> Sent: Wednesday, August 20, 2003 4:09 PM
> To:
> Subject: [c54x] Tone Detection
>
> I'm trying to implement a CTCSS tone detector in a C5402. I've tried to
> implement a Goertzel Filter based on the DTMF decoder chapter in the
> Analog Devices DSP Applications book. I'm not sure if this is the right
> approach or not, and it doesn't seem to be working :<
>
> Does anyone have any good references to tone detection articles for the
> 54x? I found a good article on Goertzel at
> http://www.embedded.com/story/OEG20020819S0057
>
> I've tried to implement a fixed point version in the 54x, but on noise
> (its in a radio) I get occasional big spikes and on the ctcss tone it
> doesn't return a very large mag^2 like it should.
>
> Thanks,
>
> Brian > _____________________________________
> Note: If you do a simple "reply" with your email client, only the author
> of this message will receive your answer. You need to do a "reply all" if
> you want your answer to be distributed to the entire group.
>
> _____________________________________
> About this discussion group:
>
> To Join: Send an email to
>
> To Post: Send an email to
>
> To Leave: Send an email to
>
> Archives: http://www.yahoogroups.com/group/c54x
>
> Other Groups: http://www.dsprelated.com > ">http://docs.yahoo.com/info/terms/
>




Caron, Francois wrote:

> Bonjour,
>
> Try out the code of Schmer with SPRA096A.
> Very good article about dual frequency detector is:
> Felder et al. "Efficient Dual-Tone Multifrequency Detection Using
> the Nonuniform DFT", july 1998, IEEE Signal Processing Letters. vol 5, no.7
>

I've read 096a, but it doesn't have any code included, just a bunch of
math (which looks like what I'm trying to implement I think). Thanks for
the DTMF paper, here's a URL for it:

http://www.ece.utexas.edu/~bevans/papers/1998/dtmf/

> What is CTCSS?

Continuous Tone Coded Suelch System. Its a low freq. tone (192.8Hz in
this case) that is added to voice transmissions. The receiver won't open
its squelch unless the tone is present. Its used in system in congested
areas where a normal noise operated squelch would false on nearby
signals. Its also used by ham radio repeaters so that the repeater isn't
accidently keyed up.

Brian


Brian C. Lane wrote:
> I'm trying to implement a CTCSS tone detector in a C5402. I've tried to
> implement a Goertzel Filter based on the DTMF decoder chapter in the
> Analog Devices DSP Applications book. I'm not sure if this is the right
> approach or not, and it doesn't seem to be working :<
>
> Does anyone have any good references to tone detection articles for the
> 54x? I found a good article on Goertzel at
> http://www.embedded.com/story/OEG20020819S0057
>
> I've tried to implement a fixed point version in the 54x, but on noise
> (its in a radio) I get occasional big spikes and on the ctcss tone it
> doesn't return a very large mag^2 like it should.

I've fixed the spikes (overflow problem), and tried it both with my code
and with the TI implementation and I now get the same results with
either. But it doesn't work right.

On noise I see variations in mag2 up to about 500. When I receive the
tone I see it level out at about 84. I'm thinking that my coefficient
calculation must be off, but I don't see how.

Fs is 10669 Hz and the desired tone is 192.8Hz
N = 221

coeff = 2 * math.cos( 2 * PI * 192.8 / 10669.0 )
coeff = 1.9871216646192891

Which is too big for 1.15 format so I divide it by 2 and scale it back
up by x2 in the calculations.

So my coeff ends up being:
coeff = (1.9871216646192891 / 2) * 2**15
coeff = 32557.001353122432

So I use 32557.

I scale my input samples down to 8 bits to prevent overflow with N"1,
and I have a diagnostic graph of the mag2 results that I can look at.

I've tried a lower N, 107, but the mag2 was reduced to 22 with the tone
present.

I've even tried a lower coeff (16278, half of 32557) just to see what
would happen and when the tone is present the mag2 goes to 0.

Any ideas would be appreciated,

Thanks!

Brian



Have u tested your code on pc with floating point
format, to avoid any overflow problem?

regards
hemya
--- "Brian C. Lane" <> wrote:
> Brian C. Lane wrote:
> > I'm trying to implement a CTCSS tone detector in a
> C5402. I've tried to
> > implement a Goertzel Filter based on the DTMF
> decoder chapter in the
> > Analog Devices DSP Applications book. I'm not sure
> if this is the right
> > approach or not, and it doesn't seem to be working
> :<
> >
> > Does anyone have any good references to tone
> detection articles for the
> > 54x? I found a good article on Goertzel at
> > http://www.embedded.com/story/OEG20020819S0057
> >
> > I've tried to implement a fixed point version in
> the 54x, but on noise
> > (its in a radio) I get occasional big spikes and
> on the ctcss tone it
> > doesn't return a very large mag^2 like it should.
>
> I've fixed the spikes (overflow problem), and tried
> it both with my code
> and with the TI implementation and I now get the
> same results with
> either. But it doesn't work right.
>
> On noise I see variations in mag2 up to about 500.
> When I receive the
> tone I see it level out at about 84. I'm thinking
> that my coefficient
> calculation must be off, but I don't see how.
>
> Fs is 10669 Hz and the desired tone is 192.8Hz
> N = 221
>
> coeff = 2 * math.cos( 2 * PI * 192.8 / 10669.0 )
> coeff = 1.9871216646192891
>
> Which is too big for 1.15 format so I divide it by 2
> and scale it back
> up by x2 in the calculations.
>
> So my coeff ends up being:
> coeff = (1.9871216646192891 / 2) * 2**15
> coeff = 32557.001353122432
>
> So I use 32557.
>
> I scale my input samples down to 8 bits to prevent
> overflow with N"1,
> and I have a diagnostic graph of the mag2 results
> that I can look at.
>
> I've tried a lower N, 107, but the mag2 was reduced
> to 22 with the tone
> present.
>
> I've even tried a lower coeff (16278, half of 32557)
> just to see what
> would happen and when the tone is present the mag2
> goes to 0.
>
> Any ideas would be appreciated,
>
> Thanks!
>
> Brian >
> _____________________________________
> Note: If you do a simple "reply" with your email
> client, only the author of this message will receive
> your answer. You need to do a "reply all" if you
> want your answer to be distributed to the entire
> group.
>
> _____________________________________
> About this discussion group:
>
> To Join: Send an email to > To Post: Send an email to
>
> To Leave: Send an email to > Archives: http://www.yahoogroups.com/group/c54x
>
> Other Groups: http://www.dsprelated.com > ">http://docs.yahoo.com/info/terms/


__________________________________


Brian C. Lane wrote:

> Brian C. Lane wrote:
>
>>I'm trying to implement a CTCSS tone detector in a C5402. I've tried to
>>implement a Goertzel Filter based on the DTMF decoder chapter in the
>>Analog Devices DSP Applications book. I'm not sure if this is the right
>>approach or not, and it doesn't seem to be working :<
>>
>>Does anyone have any good references to tone detection articles for the
>>54x? I found a good article on Goertzel at
>>http://www.embedded.com/story/OEG20020819S0057
>>
>>I've tried to implement a fixed point version in the 54x, but on noise
>>(its in a radio) I get occasional big spikes and on the ctcss tone it
>>doesn't return a very large mag^2 like it should. > I've fixed the spikes (overflow problem), and tried it both with my code
> and with the TI implementation and I now get the same results with
> either. But it doesn't work right.
>
> On noise I see variations in mag2 up to about 500. When I receive the
> tone I see it level out at about 84. I'm thinking that my coefficient
> calculation must be off, but I don't see how.
>
> Fs is 10669 Hz and the desired tone is 192.8Hz
> N = 221
>
> coeff = 2 * math.cos( 2 * PI * 192.8 / 10669.0 )
> coeff = 1.9871216646192891
>
> Which is too big for 1.15 format so I divide it by 2 and scale it back
> up by x2 in the calculations.
>
> So my coeff ends up being:
> coeff = (1.9871216646192891 / 2) * 2**15
> coeff = 32557.001353122432
>
> So I use 32557.
>
> I scale my input samples down to 8 bits to prevent overflow with N"1,
> and I have a diagnostic graph of the mag2 results that I can look at.
>
> I've tried a lower N, 107, but the mag2 was reduced to 22 with the tone
> present.
>
> I've even tried a lower coeff (16278, half of 32557) just to see what
> would happen and when the tone is present the mag2 goes to 0.
>


Ok, here's my code. This is converted from the TI code Mnemonic format
to algebraic:

; Goertzel Filter for 192.8Hz
; Q0 = (2 * coeff * Q1) - Q2 + sample
; Q2 = Q1
; Q1 = Q0
;
; Every N (221) samples calculate mag*mag
; mag*mag = Q1*Q1 + Q2*Q2 - Q1*Q2*coeff

AR3 = #ctcss_coeff ; Point to coefficient
AR2 = #ctcss_Q2 ; Point to Q2
A = B << #8 ; Get the last sample (top 8 bits)
B = A - *AR2- << #16 ; -Q2 + signal (shifted into high 16 bits)
B = B + *AR2 * *AR3 ; coeff*Q1 - Q2+signal
B = B + *AR2 * *AR3 ; coeff*Q1 + coeff*Q1 - Q2+signal
delay(*AR2) ; Q2 = Q1
*AR2 = B << #-16 ; Save the high 16 bits in Q1

; Count the number of samples
*(ctcss_ctr) -= #1
TC = (*(ctcss_ctr) == #0)
if(NTC) goto no_lvl_change

; Calculate the mag*mag value
; mag*mag = Q1*Q1 + Q2*Q2 - Q1*Q2*coeff
AR2 = #ctcss_Q2
AR3 = #ctcss_coeff
A = *AR2 << #16 ; Load Q2
B = *AR2- * hi(A), T = *AR2- ; Q2*Q2, T=Q2
A = T * *AR2 ; Q1*Q2
T = *AR3 ; T = coeff
A = T * hi(A) ; coeff*Q1*Q2
B = B - A << #1 ; Q2*Q2 - 2*coeff*Q1*Q2
T = *AR2 ; T = Q1
B = B + *AR2 * T

*(ctcss_lvl) = B << #-16 ; Convert back to 16 bits
*(ctcss_ctr) = #CTCSS_N ; Reset the counter

; Reset the Goertzel variables
*(ctcss_Q1) = #0
*(ctcss_Q2) = #0 Can anyone see anything wrong with this?

I've tried to run the output of a 192.8Hz NCO through it, and it results
in a 0 in ctcss_lvl, so I've obviously got something wrong here.

Thanks,

Brian



Brian-

> Ok, here's my code. This is converted from the TI code Mnemonic format
> to algebraic:

Is the FRACT bit set to 1? Your code appears to expect that.

Also, do you have all pipeline warnings turned on? There a few places below
that I
would be wondering about pipeline conflicts and results not being ready in time.

-Jeff

> ; Goertzel Filter for 192.8Hz
> ; Q0 = (2 * coeff * Q1) - Q2 + sample
> ; Q2 = Q1
> ; Q1 = Q0
> ;
> ; Every N (221) samples calculate mag*mag
> ; mag*mag = Q1*Q1 + Q2*Q2 - Q1*Q2*coeff
>
> AR3 = #ctcss_coeff ; Point to coefficient
> AR2 = #ctcss_Q2 ; Point to Q2
> A = B << #8 ; Get the last sample (top 8 bits)
> B = A - *AR2- << #16 ; -Q2 + signal (shifted into high 16 bits)
> B = B + *AR2 * *AR3 ; coeff*Q1 - Q2+signal
> B = B + *AR2 * *AR3 ; coeff*Q1 + coeff*Q1 - Q2+signal
> delay(*AR2) ; Q2 = Q1
> *AR2 = B << #-16 ; Save the high 16 bits in Q1
>
> ; Count the number of samples
> *(ctcss_ctr) -= #1
> TC = (*(ctcss_ctr) == #0)
> if(NTC) goto no_lvl_change
>
> ; Calculate the mag*mag value
> ; mag*mag = Q1*Q1 + Q2*Q2 - Q1*Q2*coeff
> AR2 = #ctcss_Q2
> AR3 = #ctcss_coeff
> A = *AR2 << #16 ; Load Q2
> B = *AR2- * hi(A), T = *AR2- ; Q2*Q2, T=Q2
> A = T * *AR2 ; Q1*Q2
> T = *AR3 ; T = coeff
> A = T * hi(A) ; coeff*Q1*Q2
> B = B - A << #1 ; Q2*Q2 - 2*coeff*Q1*Q2
> T = *AR2 ; T = Q1
> B = B + *AR2 * T
>
> *(ctcss_lvl) = B << #-16 ; Convert back to 16 bits
> *(ctcss_ctr) = #CTCSS_N ; Reset the counter
>
> ; Reset the Goertzel variables
> *(ctcss_Q1) = #0
> *(ctcss_Q2) = #0
>
> Can anyone see anything wrong with this?
>
> I've tried to run the output of a 192.8Hz NCO through it, and it results
> in a 0 in ctcss_lvl, so I've obviously got something wrong here.
>
> Thanks,
>
> Brian



Do you know what the frequency response of your A/D converter is below
300Hz? It might be attenuating outside the speech bandpass.

Just a thought...

-- Larry, K1LJ
Brian C. Lane <> wrote:

.
.
.
>I've fixed the spikes (overflow problem), and tried it both with my code
>and with the TI implementation and I now get the same results with
>either. But it doesn't work right.

>On noise I see variations in mag2 up to about 500. When I receive the
>tone I see it level out at about 84. I'm thinking that my coefficient
>calculation must be off, but I don't see how.

>Fs is 10669 Hz and the desired tone is 192.8Hz
.
.
.