Signals and Systems
Ziaullah Shakeel
Rizwan kareem
Lab 11
Task 1
ftable = [1;2;3;4;5]*[80,110]
ftable = 5×2
80 110
160 220
240 330
320 440
400 550
fs = 8000; xx = [ ];
keys = rem(3:12,10) + 1
keys = 1×10
4 5 6 7 8 9 10 1 2 3
for ii = 1:length(keys)
kk = keys(ii);
xx = [xx,zeros(1,400)];
krow = ceil(kk/2);
kcol = rem(kk-1,2) + 1;
dur=0.15;
t=0:1/fs:dur;
xx = [xx, cos(2*pi*ftable(krow,kcol)*t)];
end
soundsc(xx,fs);
1. We multiply the by [80, 110] and then the row's and column's values are added with a delay .
2. the table size is 5 by 2. The playing order is 4, 5, 6, 7, 8, 9, 10, 1, 2, 3
3. The duration for the total signal is 2 seconds. This is because we know that the sound at each frequency
plays for 0.15 seconds, and then we add a delay of 0.05 seconds to it which gives a total duration of 0.2
seconds. But since the loop runs 10 times we get a duration of 0.2 * 10 which gives 2 seconds. The total
samples are therefore 16000 because it will just be fs*time. The total signal length is 16010.
Task 2
xx = dtmfdial(['1' '2' '3' '4' '5' '6' '7' '8' '9'], 8000);
soundsc(xx, 8000)
1
Task 3
B = maxbeta(51, 852, 8000)
B = 0.0396
L = 51;
n = 0:L-1;
ww = 0:pi/L:pi;
x = B .* cos((2*pi*852.*n)./8000);
c = freqz(x, 1, ww);
plot(ww, abs(c))
ylabel("Frequency Response"); xlabel("X-Axis")
xlim([0 2]);
Task 4
When L = 40
L= 40;
fb=[697,770,852,941,1209,1336,1477,1633];
[hh, freq] = dtmfdesign(fb, L, 8000);
ww = 0:pi/L:pi;
plot(ww, abs(freq(:,1)),'DisplayName',[num2str(fb(1)), 'Hz']);
title("Frequency response when L = 40"); xlabel("normalized radian
frequency"); ylabel("magnitude"); hold on;
for i=2:8
2
plot(ww, abs(freq(:,i)), 'DisplayName',[num2str(fb(i)), 'Hz']);
end
hold off
legend('Location', 'northeast');
xlim([0 2])
When L = 80
L= 80;
fb=[697,770,852,941,1209,1336,1477,1633];
[hh, freq] = dtmfdesign(fb, L, 8000);
ww = 0:pi/L:pi;
plot(ww, abs(freq(:,1)),'DisplayName',[num2str(fb(1)), 'Hz']);
title("Frequency response when L = 80"); xlabel("normalized radian
frequency"); ylabel("magnitude"); hold on;
for i=2:8
plot(ww, abs(freq(:,i)), 'DisplayName',[num2str(fb(i)), 'Hz']);
end
hold off
legend('Location', 'northeast');
xlim([0 2])
3
The passbands at both frequencies has almost the same length when we look at the graphs' normalized
frequency. One difference is that when L = 80, the passband has shrunk a little bit, which means that it has
come even more closer to the bounds - 1.5 and 0.5 - as compared to the graph when L = 40.
Bandpass filters only allow a specific range of frequencies to pass through while blocking other frequencies.
This is determined by the filter's frequency response, which has a narrow peak at the center frequency it's
designed to pass.
When L=80, the signals with frequencies around 1 to 1.5 rad/s we see that there isn't a huge overlap, therefore
the passband is narrow enough, but between 0.5 and 1, there is a significant overlap between the signals and
therefore it's not narrow enough for each signal. Hence, the filter is more selective for the ones between 1-1.5.
L = 200;
fb=[697,770,852,941,1209,1336,1477,1633];
[hh, freq] = dtmfdesign(fb, L, 8000);
ww = 0:pi/L:pi;
plot(ww, abs(freq(:,1)),'DisplayName',[num2str(fb(1)), 'Hz']);
4
title("Frequency response when L = 200"); xlabel("normalized radian
frequency"); ylabel("magnitude"); hold on;
for i=2:8
plot(ww, abs(freq(:,i)), 'DisplayName',[num2str(fb(i)), 'Hz']);
end
hold off
legend('Location', 'northeast');
xlim([0 2])
Part II
Task 5
The DTMF Score Function:
function sc = dtmfscore(xx, hh)
% DTMFSCORE
% usage: sc = dtmfscore(xx, hh)
% returns a score based on the max amplitude of the filtered output
% xx = input DTMF tone
% hh = impulse response of ONE bandpass filter
%
xx = xx*(2/max(abs(xx))); %--Scale the input x[n] to the range [-2,+2]
y_n = conv(xx, hh); % convolve the two vectors
sc = max(abs(y_n)) >= 0.59; % returns 1 when y[n] >= 0.59
end
5
The maximum value of the magnitude for must be equal to 1 so that the signal passes as it is - it's
magnitude does not amplify. A frequency response of 1 for a band-pass filter means that the frequencies within
the 'band' will be allowed to pass through without attenuating or amplifying. In this case, we have set a threshold
of 0.59 - all signals with a magnitude more than this will be allowed to pass and the others will be discarded.
Task 6
The DTMF Run Function:
function keys = dtmfrun(xx,L,fs)
%DTMFRUN keys = dtmfrun(xx,L,fs)
% returns the list of key names found in xx.
% keys = array of characters, i.e., the decoded key names
% xx = DTMF waveform
% L = filter length
% fs = sampling freq
dtmf.keys = ...
['1','2','3','A';
'4','5','6','B';
'7','8','9','C';
'*','0','#','D'];
dtmf.colTones = ones(4,1)*[1209,1336,1477,1633];
dtmf.rowTones = [697;770;852;941]*ones(1,4);
% defines 1X8 vector of frequencies
center_freqs = [697,770,852,941,1209,1336,1477,1633];
hh = dtmfdesign( center_freqs,L,fs );
% hh = L by 8 MATRIX of all the filters. Each column contains the
% impulse response of one BPF (bandpass filter)
%
[nstart,nstop] = dtmfcut(xx,fs); %¡--Find the beginning and end of tone bursts
keys = []; %initialize keys
for kk=1:length(nstart) %for eah tone
x_seg = xx(nstart(kk):nstop(kk)); %¡--Extract one DTMF tone
sc = [];
for ii=1:8
score = dtmfscore(x_seg, hh(:, ii));
sc = [sc, score];
end
r = find(sc(1:4) == 1); c = find(sc(5:8) == 1);
keys = [keys, dtmf.keys(r, c)];
end
keys = char(keys);
Code:
1. When tk = [1, 2, 3, 4]
fs = 8000; %¡--use this sampling rate in all functions
tk = ['1','2','3','4'];
xx = dtmfdial( tk, fs );
soundsc(xx, fs)
L = 200; %¡--use your value of L
dtmfrun(xx, L, fs)
6
ans =
'1234'
2. When tk = [A, C, B, D]
fs = 8000; %¡--use this sampling rate in all functions
tk = ['A','C','B','D'];
xx = dtmfdial( tk, fs );
soundsc(xx, fs)
L = 200; %¡--use your value of L
dtmfrun(xx, L, fs)
ans =
'ACBD'
3. When tk = [1, 2, 3, 4, 5, *, #, 0, 1, 2, 3, 4, 5 , 6, 7, 8, 9]
fs = 8000; %¡--use this sampling rate in all functions
tk = ['1','2','3','4','5','*','#','0','1','2','3','4','5','6','7','8','9'];
xx = dtmfdial( tk, fs );
soundsc(xx, fs)
L = 200; %¡--use your value of L
dtmfrun(xx, L, fs)
ans =
'12345*#0123456789'
4. When tk = [A,B,C,D,*,#,0,1,2,3,4,5,6,7,8,9]
fs = 8000; %¡--use this sampling rate in all functions
tk = ['A','B','C','D','*','#','0','1','2','3','4','5','6','7','8','9'];
xx = dtmfdial( tk, fs );
soundsc(xx, fs)
L = 200; %¡--use your value of L
dtmfrun(xx, L, fs)
ans =
'ABCD*#0123456789'
Task 7
Code For Testing
Phone number used: 407*89132BADC
fs = 8000; %¡--use this sampling rate in all functions
tk = ['4', '0', '7', '*', '8', '9', '1', '3', '2', 'B', 'A', 'D', 'C'];
xx = dtmfdial( tk, fs );
soundsc(xx, fs)
L = 200; %¡--use your value of L
dtmfrun(xx, L, fs)
ans =
'407*89132BADC'
7
Functions Used
DTMF Design
function [hh, freq] = dtmfdesign(fb, L, fs)
hh = []; freq = [];
i = 1;
while i <= length(fb)
n = 0:(L-1);
func = maxbeta(L,fb(i),fs);
hn = func*cos((2*pi.*fb(i)*n)/fs);
ww = 0:pi/L:pi;
f_resp = freqz(hn, 1, ww);
hh = [hh; hn];
freq = [freq; f_resp];
i = i + 1;
end
hh = transpose(hh);
freq = transpose(freq);
end
DTMF Dial
function xx = dtmfdial(keyNames,fs)
dtmf.keys = ...
['1','2','3','A';
'4','5','6','B';
'7','8','9','C';
'*','0','#','D'];
dtmf.colTones = ones(4,1)*[1209,1336,1477,1633];
dtmf.rowTones = [697;770;852;941]*ones(1,4);
t = 0:1/fs:0.2;
xx = [];
for i = 1:length(keyNames)
kk = keyNames(i);
xx = [xx, zeros(1, 400)];
[ii, jj] = find(kk==dtmf.keys);
r1 = cos(2*pi*dtmf.colTones(ii, jj)*t);
r2 = cos(2*pi*dtmf.rowTones(ii, jj)*t);
xx = [xx, r1+r2];
end
end
Maxbeta
function B = maxbeta(L, fb, fs)
n = 0:pi/L:L;
w = 2*pi/fs;
ww = 0:1:L-1;
h_n = cos(w.*ww.*fb);
c = freqz(h_n, 1, n);
B = max(abs(c));
B = 1/B;
end
8
DTMF Cut
function [nstart,nstop] = dtmfcut(xx,fs)
%DTMFCUT find the DTMF tones within x[n]
% usage:
% [nstart,nstop] = dtmfcut(xx,fs)
%
% length of nstart = M = number of tones found
% nstart is the set of STARTING indices
% nstop is the set of ENDING indices
% xx = input signal vector
% fs = sampling frequency
%
% Looks for silence regions which must at least 10 millisecs long.
% Also the tones must be longer than 100 msec
xx = xx(:)'/max(abs(xx)); %-- normalize xx
Lx = length(xx);
Lz = round(0.01*fs);
setpoint = 0.02; %-- make everything below 2% zero
xx = filter( ones(1,Lz)/Lz, 1, abs(xx) );
xx = diff(xx>setpoint);
jkl = find(xx~=0)';
%%%xx(jkl);
if xx(jkl(1))<0, jkl = [1;jkl]; end
if xx(jkl(end))>0, jkl = [jkl;Lx]; end
%%%jkl';
indx = [];
while length(jkl)>1
if jkl(2)>(jkl(1)+10*Lz)
indx = [indx, jkl(1:2)];
end
jkl(1:2) = [];
end
nstart = indx(1,:);
nstop = indx(2,:);