Sunteți pe pagina 1din 11

1

MATLAB Lab 8
T. F. Wong

4.1 (a)

>> L=40;
>> hatw=0.4*pi;
>> h=2/L*cos(hatw*[0:L-1]);
>> w=-pi:pi/100:pi;
>> H=freqz(h,1,w);
>> subplot(2,1,1);
>> plot(w/pi,abs(H));
>> ylabel('Magnitude response');
>> subplot(2,1,2);
>> plot(w/pi,angle(H));
>> ylabel('Phase response');
>> xlabel('normalized radian freq (x\pi)');





4.1 (b) From the plot of the magnitude response, the passband width
(bandwidth or BW) is about 0.05! radians. More precisely, we can use
the following commands in MATLAB:



2
>> i=find(abs(H)>=0.5*max(abs(H)));
>> w(i)

ans =

Columns 1 through 9

-1.3509 -1.3195 -1.2881 -1.2566 -1.2252 -1.1938 1.1938

1.2252 1.2566

Columns 10 through 12

1.2881 1.3195 1.3509

Notice that the first 6 printed values correspond to the ve freq.
values over which the magnitude response is larger than one half of
its maximum value. The last 6 values correspond to the +ve freq.
values over which the magnitude response is larger than one half of
its maximum value. The BW of the filter is then 1.3509 - 1.1938 =
0.1571 = 0.05! radians. This result has an error of 0.01! radians.
Why? Do you know how to get a better resolution? Youll need that in
5.2 below.

4.1 (c) MATLAB codes are similar to the above.

BW = 0.11! 0.01! radians

3

BW = 0.02! 0.01! radians


Increasing L decreases the BW of the filter. Doubling the value of L
seems to roughly halving the BW.

4.2 (a)

>> hatw=0.25*pi;
>> L=41;
>> n=[0:L-1];
>> h=(0.54-0.46*cos(2*pi*n/(L-1))).*cos(hatw*(n-(L-1)/2));
>> H=freqz(h,1,w);
>> subplot(2,1,1);
>> title('L=21 w/ Hamming window');
>> plot(w/pi,abs(H));
>> ylabel('Magnitude response')
>> subplot(2,1,2);
>> plot(w/pi,angle(H));
>> ylabel('Phase response')
>> xlabel('normalized radian freq (x\pi)');
>> subplot(2,1,1);
>> title('L=41 w/ Hamming window');

4


The maximum height of the ripples in the stopband is about 0.1 You can
see that much clearly by plotting the magnitude response in dB. Using
the same method as in 4.1b), BW = 0.08! 0.01! radians.

>> w=[0 0.1 0.25 0.4 0.5 0.75]*pi;
>> H=freqz(h,1,w);
>> w

w =

0 0.3142 0.7854 1.2566 1.5708 2.3562
>> abs(H)

ans =

0.0800 0.0800 10.8800 0.0800 0.0800 0.0800

>> angle(H)

ans =

3.1416 -3.1416 3.1416 -3.1416 -3.1416 -3.1416





5
4.2 (b)

BW = 0.18! 0.01! radians


BW = 0.04! 0.01! radians
6

4.2 (c) y[n]=-0.08*2+0.08*2*cos(0.1!n+!/3-!)+10.88*cos(0.25!n-!/3+!)
=-0.16+0.16*cos(0.1!n-2!/3)+10.88*cos(0.25!n+2!/3)

The dc component and the sinusoidal component at freq. 0.1! are in the
stopband of the filter and hence significantly attenuated. The
sinusoidal component at freq. 0.25! is in the passband of the filter
and hence significantly magnified.

4.2 (d) Magnitude response peaks around freq. = 0.25! radians and is
very small for other freqs.


5.1) f
s
=8000Hz
Octave # 2 3 4 5 6
Key range 16-27 28-39 40-51 52-63 64-75
Lower freq. (Hz) 65 131 262 523 1047
Higher freq. (Hz) 123 247 494 988 1976
Passband width (Hz) 58 116 232 465 929
Center freq. (Hz) 94 189 378 756 1512
Lower norm. freq. 0.0081 0.0164 0.0328 0.0654 0.1309
Higher norm. freq. 0.0154 0.0309 0.0617 0.1235 0.2470
Passband width 0.0073 0.0145 0.0290 0.0581 0.1161
Center norm. freq. 0.0118 0.0236 0.0473 0.0945 0.1890

5.2) Let us first determine the value of L for the octave 6 filter. We
choose octave 6 because it has the widest passband, and hence gives
the smallest error from applying the above method to measure BW. The
passband of octave 6 is 0.1161*2! radians. As a result, we should
choose L < 21. After some trials, I settle for L=16 and BW=0.1175*2!
radians. For the other octave filters, we can then double the value of
L going down from octave #6. The results are summarized in the table
below:

Octave # 2 3 4 5 6
L 256 128 64 32 16
BW (Hz) 56 113 228 462 943
BW norm. freq. 0.0070 0.0141 0.0285 0.0578 0.1179
" 0.0145 0.0291 0.0586 0.1187 0.2438


The required " is simply the reciprocal of the maximum value of the
magnitude response of the filter given by (3). The values of " for the
five octave filters are given in the table above.

The magnitude responses of the octave filters are plotted below. The
passband of each octave is shown between the broken vertical lines of
color associated with the octave. The center freq. of the octave is
shown in the dash-dot vertical line of the corresponding color.
7

5.3)
>> fs=8000;
>> t=0:1/fs:0.85;
>> xx=zeros(1,length(t));
>> temp=one_cos(220,1,0,fs,0.25,0);
>> xx(1:length(temp))=temp;
>> temp=one_cos(880,1,0,fs,0.25,0.3);
>> start=find(t==0.3);
>> xx(start:start+length(temp)-1)=temp;
>> temp=one_cos(440,1,0,fs,0.25,0.6)+one_cos(1760,1,0,fs,0.25,0.6);
>> start=find(t==0.6);
>> xx(start:start+length(temp)-1)=temp;

>> x2=conv(xx,h2);
>> x3=conv(xx,h3);
>> x4=conv(xx,h4);
>> x5=conv(xx,h5);
>> x6=conv(xx,h6);

>> subplot(6,1,1)
>> plot(t,xx);
>> axis([0 max(t) -2 2])
8

>> ylabel('xx')
>> subplot(6,1,2)
>> plot(t,x2(1:length(t)));
>> axis([0 max(t) -1 1])
>> ylabel('x2')
>> subplot(6,1,3)
>> plot(t,x3(1:length(t)));
>> axis([0 max(t) -1 1])
>> ylabel('x3')
>> subplot(6,1,4)
>> plot(t,x4(1:length(t)));
>> axis([0 max(t) -1 1])
>> ylabel('x4')
>> subplot(6,1,5)
>> plot(t,x5(1:length(t)));
>> axis([0 max(t) -1 1])
>> ylabel('x5')
>> subplot(6,1,6)
>> plot(t,x6(1:length(t)));
>> axis([0 max(t) -1 1])
>> ylabel('x6')
>> xlabel('time (s)');


9
From time 0s to 0.25s, the signal xx has a component in octave #3.
From time 0.3s to 0.55s, xx has a component in octave #5. From time
0.6s to 0.85s, xx has a component in octave #4 and a component in
octave #6.

We can see from the waveform plot above that the octave components in
the signal xx at different time can be correctly detected by comparing
the maximum magnitude of the output of each filter to a suitable
threshold (say 0.5).

The transient should last as long as the length of the FIR filter
used. For example, the length of the octave #6 filter is L=16, and
hence the transient should last for 16/fs=0.002s. The length of the
octave #2 filter is L=256, and hence the transient should last for
256/fs=0.032s. These calculations can be verified by examining the
waveform plot above.

5.4)
function sc=octavescore(xx,hh,fs)

% xx = input signal containing musical notes
% hh = impulse response of BPF with max magnitude response=1,
% assuming FIR filter in (4) Hamming-windowed FIR filter
% fs = sample rate

L=length(hh); % length of filter
delay=round((L-1)/2); % assuming filter's impulse response peaks at center
SS=round(50e-3*fs); % # of samples in 50ms


yy=abs(conv(hh,xx)); % magnitude of filter output

% Calculate the # of 50ms segments in yy after removing the delay
ny=length(yy);
ns=floor((ny-delay)/SS); % # of segments

% Find max. magnitude in each segment
sc=max(reshape(yy(delay+1:delay+SS*ns),SS,ns));


Below is a function to generate and plot the detection matrix:

function dm=octavedetect(xx,fs)

% dm = detection matrix; 1st row octave #2, last row octave #6, each
% element is either 0 or 1. '1' means presence of notes in the 50ms segment
% at that octave.

% Generate the impulse response of the octave filters
w=-pi:pi/1000:pi;
L=[256 128 64 32 16]; % filter lengths
hatw=[0.0118 0.0236 0.0473 0.0945 0.1890]*2*pi; % center freqs
SS=round(50e-3*fs); % # of samples in 50ms
10
ns=floor(length(xx)/SS); % # of 50ms segments in xx
dm=zeros(5,ns);

for i=1:5
% Generate filter for current octave
n=[0:L(i)-1];
hh=(0.54-0.46*cos(2*pi*n/(L(i)-1))).*cos(hatw(i)*(n-(L(i)-1)/2));
H=freqz(hh,1,w);
hh=hh/max(abs(H));

% calculate scores and thresholding
thr=octavescore(xx,hh,fs) >= 0.5;
dm(i,:)=thr(1:ns);
subplot(5,1,i);
bar([0:ns-1]*50e-3,dm(i,:),1,'r');
ylabel(sprintf('Octave #%1d',i+1));
axis([-25e-3 4 0 1]);
end
xlabel('time (s)');

Here is the result applied on the signal xx in labtest.mat:

>> notes

notes =

66 53 55 53 41 22 21 66 34 31 0 72 59 62 39
0 0 46 71 0 0 0 0 37 27 63 0 0 0 63

11
It is hard to compare to the true note trajectory since timing info
is not provided in the array notes. But it appears that the detector
gives pretty good detection with occasional errors.

S-ar putea să vă placă și