|This is the approach that Analog Devices takes in their DSP-based DTMF
|decoder. (Actually they decode the 'fundamentals' and the '2nd
|Harmonics'.) However, this approach isn't entirely succesful (from what
|I've read in other literature). But even if you do implement this
|filtering strategy, you're still going to be plagued by the 'broad band'
|nature of some conversations. In other words, normal conversation can
|overlap the DTMF frequencies. (The 'autocorrelation' trick helps,
One trick I've found handy (when doing tone detect on a
TI DSP) is to measure the strength of each frequency when
viewed with a fairly wide passband filter and subtract that
from the strength when viewed with a narrow one. The graph
of frequency sensitivity goes negative near each target freq-
uency, but has a very tall and narrow spike at the target.
Since voice is likely to have a frequencies that are near the
DTMF tones in addition to those that match DTMF tones perfect-
ly, this allows for excellent rejection of talk-off and accur-
ate reception of DTMF.
|On Tue, 17 Nov 1998, John Payson wrote:
This is precisely (one of) the technique(s) I suggested to Andy Kunz in
private e-mail. In Andy's case, the incoming frequency is not know. In the
DTMF case, it is known to be in 8 discrete locations. The decoding logic
is similar though:
I'm not sure if you'll be able to use a pic, but here's one brute-force
solution that might work for you:
1) Hardware low-pass filter your signal. A 4th order chebychev filter can
be implemented with two op-amps. The phase response is terrible, but
you're not interested in phase. (You may can design a 4'th order elliptic
filter instead, however the cut-off is not that much steeper and the
component sensitivites tend to be higher [unless of course you throw in
more opamps, in which you would probably inclined to implement a 6th or
8th order chebychev...]).
2) Sample the signal at roughly 12kHz (4 * 3k)
3) Compute the total energy in the signal. There are esoteric ways of
doing this, but the simplest is an autocorrelation-type approach: find the
sum of the squares of each sample:
for(i=0; i<NUM_SAMPLES; i++)
sum_of_squares += sample[i]*sample[i];
4) Now the tough part. I'm not sure how much processing power you're going
to have, but you'll probably want to do some sort of frequency
decomposition. There are several ways to approach this. First of all, you
could implement a good old fashioned FFT (since you care less about phase,
an FHT or fast Hartley transform would probably be more appropriate). A
more efficient technique what be to implement a digital filter banks and
use multirate filters (e.g. decimation and interpolation filters). The
multirate filters are good also because they filter the data as it is
acquired, where as the FFT and FHT require the entire data block before
the decomposition can begin.
However you do the frequency binning, you'll now have to decode the
signal by comparing the energy per bin to the overall energy in the
signal. The bin with the largest energy (above a threshold that's defined
by the total signal energy) contains the frequency of interest.
Whew! But you still may not be done! I'm not sure how much resolution you
need. You may want to process the signal with another frequency-binning
filter that is centered over the bin determined above.
I realize that this sounds complex, but it can be done efficiently (at
least on a dsp). For example, you could have 8 coarse bins to determine
where most of the signal energy is located followed by 8 fine bins to
narrow in more accurately. In effect, you can have 256 (arbitrarily)
spaced frequency bins.
Another solution that's less brute forced, but probably not as accurate:
1) Same as (1) above
2) Feed the signal into a comparator and create a square wave.
3) Now the hard part.
I think you could easily (okay maybe not easily but) create 8 DFT type
square wave filters with self adjusting center frequencies. In other
words, create 8 phase locked loops. The time between edges in the square
wave can be used to control the center frequency. The basic idea is that
the frequency of the reference signal (like the sine/cosine in a DFT)
varies as a function of the incoming signal. Each of the 8 filters are
limited though over the range in which their frequency can be adjusted.
This would help prevent spurious frequency burst from totally screwing up
the filtering process. The frequency can be adjusted by varying phase
accumulators. Relatively simple low pass filters can vary the phase
The phase accumulators can be inspected to ascertain the center
frequency to which the filter phase locks.
I know this may not make any sense, but maybe it can get you going.
Scott, outstanding. To followup, John may want to take a look at
"Digital Signal Processing" by Alan V. Oppenheim and Ronald W. Schafer.
Prentice-Hall. I've had this book for a couple of decades and I still find
it to be an excellent reference. You might want to consider a book on
applying the theory to PIC code. If so, I'll buy the first book ;-)
At 01:37 PM 11/17/98 -0800, Scott Dattalo wrote:
|Another solution that's less brute forced, but probably not as accurate:
|1) Same as (1) above
|2) Feed the signal into a comparator and create a square wave.
|3) Now the hard part.
| I think you could easily (okay maybe not easily but) create 8 DFT type
|square wave filters with self adjusting center frequencies. In other
|words, create 8 phase locked loops. The time between edges in the square
|wave can be used to control the center frequency.
This is pretty close to what I did; the one notable difference is that
I used three integrating square waves, 120 degrees apart, and after I
accumulated all the signals, I looked for the largest difference bet-
ween two of the square waves. The net effect is that the input "wave"
is integrated with a signal that looks like this:
---- ---- ----
-- -- -- -- -- -- --
---- ---- ----
[those really are discrete steps, and the positive/negative parts
are twice as wide as the zero parts]. Note that this waveform is
completely devoid of the 2nd, 3rd, and 4th harmonics; a little bit
of analog filtering (using just R's and C's] will clean the upper
harmonics out of the signal reasonably well.
Anyway, I have done DTMF detection on a PIC and I can say that even
with dirtball hardware it works well. CPU loading is pretty signif-
icant, but on a 20MHz PIC there's still time to do other stuff.
FWIW(PNM) the DTMF project is the only one with a 14-bit PIC where
I actually ran out of stack space, and with a little tweaking I got
things well under control (worst-case depth=6). If you need to be
able to detect a wide variety of things of which DTMF is just one
flavor, the PIC-based approach has a lot to recommend it; if all
you need is DTMF, though, a dedicated chip may be a better approach
(if you don't mind running your PIC off 3,579,545Hz you can even
share the crystal!)
|On Thu, 31 Dec 1998, John Payson wrote:
BTW, This harmonic cancellation technique is the one that's used to
generate those infamous 'Magic Sinewaves'. In addition to the 2nd, 3rd,
and 4th, it also is devoid of the integer multiples of these harmonics
(e.g. 6th, 8th, 9th, ...)
The last time we had this discussion, John and I carried the thread
privately to a level slightly beyond what's revealed here. Since it's
public now... let's talk about some details.
I looked at this technique you describe John, and I've got a couple of
1) If the phase relationship isn't correct, it's possible that a valid
frequency integrates to zero. For example, if the digitized DTMF tone is
90 degrees out of phase with your synthesized 'sine' wave the integral (or
more properly the sum) evaluates to zero. How do you reconcile that? The
technique I used involves generating two synthesized 'sine' waves (my sine
waves are only square waves - devoid of only even harmonics) that are 90
degrees apart. This is somewhat analogous to a discrete Fourier Transform
where the integrating basis function is the complex exponential
(exp(j*wt)) and implicitly includes the sine and cosine waves.
I imagine you could attempt to phase lock to the incoming DTMF signal,
however if you're decoding all eight tones simultaneously you'll still
have the problem.
2) What kind of normalization do you use? I used a simple "one's norm" as
opposed to the more common "two's norm". [given the two integrated signals
discussed above, the two's norm = sqrt of the sum of the squares, one's
norm = sum of the abs value of each signal]
3) One problem I had is that if there is any twist in the DTMF signal (one
of the tones has a larger amplitude than the other) that the decoding is
adversely affected. Without analog signal processing it was nearly
impossible to detect the weaker tone at the maximum twist. In other words,
the worst case scenario was pretty bad. How did you deal with that? Also,
a weak DTMF signal in the presence of other noise (voices) made detection
More... (looser matching)
- Last day of these posts
- In 1998
, 1999 only
- New search...