Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

IN PYTHON: Build a DTMF decoder. Your code should accept a tonal sequence and ou

ID: 3596014 • Letter: I

Question

IN PYTHON:

Build a DTMF decoder. Your code should accept a tonal sequence and output a string of key presses.

Rules:

1. Use a sampling rate of 8000 samples per second.

2. Use a set of bandpass filters, not a FFT.

3. For full credit, use FIR filters of length 31 or less or second order (two pole) IIR filters. You get partial credit for working implementations that use larger filters.

4. You may assume the silence and tonal periods are both multiples of 400 samples. (This is a simplifying assumption.)

5. You may not assume the tones or the silence periods are the same length.

# GIVEN CODE

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rnd
from IPython.display import Audio
%matplotlib inline

# Code below encodes the dialed keypresses

Fs = 8000

#define the keypad and its frequencies
validkeys = '*#0123456789ABCD'
rowfreqs = [697, 770, 852, 941]
colfreqs = [1209, 1336, 1477, 1633]
buttons = {'1':(0,0), '2':(0,1), '3':(0,2), 'A':(0,3),
'4':(1,0), '5':(1,1), '6':(1,2), 'B':(1,3),
'7':(2,0), '8':(2,1), '9':(2,2), 'C':(2,3),
'*':(3,0), '0':(3,1), '#':(3,2), 'D':(3,3)}

def dtmf_encoder(phonenumber, dur = 0.5, silencedur=0.1, Fs=8000):
"""return the DTMF tones for a phone number"""
t = np.linspace(0,dur,int(dur*Fs),endpoint=False)
silence = np.zeros(int(silencedur*Fs))
  
sounds = []
for key in phonenumber:
if key.upper() in validkeys:
r,c = buttons[key]
fr, fc = rowfreqs[r], colfreqs[c]
#print key, fr, fc
sounds.append(np.sin(2*np.pi*fr*t)+np.sin(2*np.pi*fc*t))
sounds.append(silence)
return np.concatenate(sounds[:-1]) #drop last silence period

# TESTING CODE FOR ENCODER

test = '123A456B789C*0#D'
Audio(dtmf_encoder(test), rate=Fs)

# INSERT YOUR CODE FOR DECODING BELOW

def DTMF_decode(tones):
"PUT CODE HERE"
pass

# TESTING CODE FOR DECODER (SHOULD OUTPUT TRUE)

def test_dtmfdecoder(dtmfdecoder, dur=0.5, silencedur=0.1, Fs=8000):
works = False
sigma = 0.0
while sigma < 3.1:
number = ''.join([c for c in rnd.permutation(list(validkeys))])
#print number
tones = dtmf_encoder(number, dur=dur, silencedur=silencedur)
  
for i in range(5):
noisy_tones = tones + sigma*rnd.randn(len(tones))
decoded = dtmfdecoder(noisy_tones)
if decoded == number:
works = True
#print sigma, i
else:
return works, sigma
sigma += 0.1
return works, sigma
  

test_dtmfdecoder(DTMF_decode) #my solution

Explanation / Answer

Whenever you hit a number on a telephone touch pad, a unique tone is generated. Each tone is actually a sum of two sinusoids, and the resulting signal is called a dual-tone multifrequency (or DTMF) signal. Table 7.1 shows the frequencies generated for each button. For instance, if the “6” button is pressed, the telephone will generate a signal which is the sum of a 1336 Hz and a 770 Hz sinusoid. Frequencies 1209 Hz 1336 Hz 1477 Hz 697 Hz 1 2 3 770 Hz 4 5 6 852 Hz 7 8 9 941 Hz * 0 # Table 7.1: DTMF encoding table for touch tone dialing. When any key is pressed, the tones of the corresponding row and column are generated. We will call the set of all seven frequencies listed in this table the DTMF frequencies. These frequencies were chosen to minimize the effects of signal distortions. Notice that none of the DTMF frequencies is a multiple of another. We will see what happens when the signal is distorted and why this property is important. Looking at a DTMF signal in the time domain does not tell us very much, but there is a common signal processing tool that we can use to view a more useful picture of the DTMF signal. The spectrogram is a tool that allows us to see the frequency properties of a signal as they change over time. The spectrogram works by taking multiple DFTs over small, overlapping segments1 of a signal. The magnitudes of the resulting DFTs are then combined into a matrix and displayed as an image. Figure 7.1 shows the spectrogram of a DTMF signal. Time is shown along the x-axis and frequency along the y-axis. Note the bars, each of which represents a sinusoid of a particular frequency existing over some time period. At each time, there are two bars which indicate the presence of the two sinusoids that make up the DTMF tone. From this display, we can actually identify the number that has been dialed; you will be asked to do this in the lab assignment. 7.2.2 Decoding DTMF Signals There a number of steps to perform when decoding DTMF signals. The first two steps allow us to determine the strength of the signal at each of the DTMF frequencies. We first employ a bank of bandpass filters with center frequencies at each of the DTMF frequencies. Then, we process the output of each bandpass filter to give us an indication of the strength of each filter’s output. The third step is to “detect and decode.” From the filter output strengths, we detect whether or not a DTMF signal is present. If it is not, we refrain from decoding the signal until a tone is detected. Otherwise, we select the two filters with the largest output strengths and use this information to determine which key was pressed. A block diagram of the DTMF decoder can be seen in Figure 7.2. Step 1: Bandpass Filters From Lab 2, you may recall that correlating two signals provides us with a measure of how similar those two signals are. Since convolution is just “correlation with a time reversal,” we can use this same idea to design a filter that passes a given frequency. If our filter’s impulse response “looks like” the signal we want to pass, we should get a large amplitude signal out; similarly, signals that are different will produce smaller output signals. 1Note that each segment is some very small fraction of a second, and the segments usually overlap by 25-75%. 114 The University of Michigan, All rights reserved 7.2.2 Decoding DTMF Signals 0 10 20 30 40 50 60 Time (sec) Frequency (Hz) 0 0.5 1 1.5 2 2.5 3 3.5 4 0 500 1000 1500 2000 2500 3000 3500 4000 Figure 7.1: A spectrogram of a DTMF signal. Each horizontal bar indicates a sinusoid that exists over some time period. When performing DTMF decoding, we want filters that pass only one of the DTMF frequencies and reject all of the rest. We can make use of the correlation idea above to develop such a bandpass filter. We want our impulse response to be similar to a signal with the frequency that we wish to pass; this is the filter’s center frequency. This means that for a bandpass filter with center frequency f, we want our impulse response, h, to be equal to h[k] = sin(2fck/fs) 0 k M 0 else (7.1) From this equation, we have an FIR filter with order M. (Note that the support length of the impulse response is M + 1.) What should M be? M is a design parameter. You may remember from Lab 3 that correlating over a long time produces better estimates of similarity. Thus, we should get better differentiation between passed frequencies and rejected frequencies if M is large. There is a tradeoff, though. The longer M is, the more computation that is required to perform the convolution. Thus for efficiency reasons we would like M to be as small as possible. More computation also equates to more expensive devices, so we prefer smaller M for reasons of device economy as well. Since we have seven DTMF frequencies, we will also have seven bandpass filters in our system; in our decoder system, we will choose a different value of M for each bandpass filter. Because of the relatively small set of frequencies of concern in DTMF decoding, we will see that larger M do not necessarily produce better frequency differentiation. In order to judge how good a bandpass filter is at rejecting unwanted DTMF frequencies, we will define the gain-ratio, R. Given a filter with center frequency fc and frequency response H, the gain-ratio is R = |H(fc)| max |H( ˆf)| (7.2) where ˆf is in the set of DTMF frequencies and ˆf 6= fc. In words, we define R to be the ratio of the filter’s gain at its center frequency to the next-highest gain at one of the DTMF frequencies. Having a high gain-ratio is desirable, since it indicates that the filter is rejecting the other possible frequencies. Note that since we will be comparing the outputs of a variety of bandpass filters, we also need to normalize each filter by the center frequency gain. Thus, we will need to record not only the M that we select but also the center The University of Michigan, All rights reserved 115 Laboratory 7. Decoding DTMF: Filters in the Frequency Domain 697 Hz Bandpass Filter 770 Hz Bandpass Filter 1477 Hz Bandpass Filter DTMF Signal s(t) Rectify Rectify Rectify Lowpass Filter Lowpass Filter Detect and Decode Lowpass Filter Decoded Number Step 1 Step 2 Step 3 Figure 7.2: A block diagram of the DTMF decoder system. The input is a DTMF signal, and the output is a string of numbers corresponding to the original signal. frequency gain. You will be directed to record and include these gains in the lab assignment. Step 2: Determining filter output strengths In order to measure the strength of the filter’s output, we actually want to measure (or follow) the envelope of the filter outputs. To follow just the positive envelope of the signal, we first need to eliminate the negative portions of the signal. If we simply truncate all parts of the signal below zero, we have applied a half-wave rectifier. Alternately, we can simply take the absolute value of the signal, in which case we have applied a full-wave rectifier. It is possible to build rectifiers using diodes, and it turns out that half-wave rectifiers are easier to design. However, full-wave rectifiers are preferable, and they are no more difficult to implement in MATLAB. Thus, we will use full-wave rectifiers2. See Figure 7.3 to see the effects of these two types of rectifiers. If we now pass the rectified signal through a smoothing filter, the output will be a nearly constant signal whose value is a measure of the strength of the filter’s input at the center frequency of the filter. To accomplish this smoothing we will use a simple moving average filter with impulse response hLP = 1 MLP +1 0 k MLP 0 else (7.3) The order of this filter is MLP . The value MLP (and thus the corresponding strength of the smoothing filter) is a design parameter of the decoder system. When choosingMLP , there is a tradeoff between amount of smoothing and transient effects. If our filter’s impulse response is not long enough, the output signal will still have significant variations. If it is too long, transient effects will dominate the output of the filter. If it is too short, the system may “smooth over” short DTMF tones or periods of silence. Note that in our decoder system, we will apply the same smoothing filter to the output of each filter. Figure 7.3 shows the results of smoothing for half-wave and full-wave rectified signals. Step 3: “Detect and Decode” Once we have processed the outputs of the bandpass filters, we can now detect whether or not a DTMF tone is present and, if it is, determine which key was pressed to produce it. Ultimately, we want to convert our signal into a sequence of keys pressed to produce this sequence. The detect-and-decode step itself involves three steps. 2Note that the names “full-wave rectifier” and “half-wave rectifier” come from the circuit implementation of these systems