% First let's filter an artificial signal. We'll add two sinewaves together:
% one with a frequency of 5 kHz and the other at 500 Hz. We've done this before,
% so no problem!
freq1 = 5000;
Fs = 20000;
freq2 = 500;
intvl = 1/Fs;
secs = 2;
tim = intvl : intvl : secs;
amp1 = 1;
amp2 = 1;
wave1 = sin(tim*2*pi*freq1) * amp1;
wave2 = sin(tim*2*pi*freq2) * amp2;
addwav = wave1 + wave2;
% frequencies for the high- and low-pass parts, but to start we'll use
% the same frequency, 2500Hz.
lowcut = 2500;
highcut = 2500;
% the one we are using is called a "Butterworth" filter. The only
% thing to change here is the 'order' - which is the slope of the
% filter. Lower numbers have a broader slope, whereas higher
% numbers have a steeper slope.
order = 5;
lowcut = lowcut*2/Fs;
[b,a] = butter(order,lowcut,'low');
highcut = highcut*2/Fs;
[d,c] = butter(order,highcut,'high');
% filter that we made above, and applies it to the signal, in this case
% addwav.
lowfilt = filtfilt(b,a,addwav);
highfilt = filtfilt(d,c,addwav);
% pass filtered, bottom is low-pass filtered.
subplot(3,1,1); specgram(addwav, 512, Fs);
subplot(3,1,2); specgram(highfilt, 512, Fs);
subplot(3,1,3); specgram(lowfilt, 512, Fs);
% The first step is to make a noisy signal.
% Set the length, in seconds
len = 1;
Fs = 20000;
tim = 1/Fs:1/Fs:len;
% dimensions… we want a 1 dimensional noisy sequence, hence the
% second dimension is '1'.
noisy=randn(length(tim),1);
figure(1);
subplot(3,1,1); specgram(noisy,512,Fs);
order = 5;
lowcut = lowcut*2/Fs;
[b,a] = butter(order,lowcut,'low');
lowcut = 1500;
highcut = 5700;
highcut = highcut*2/Fs;
[d,c] = butter(order,highcut,'high');
% filter that we made above, and applies it to the signal, in this case
% addwav.
lowfilt = filtfilt(b,a,noisy);
subplot(3,1,2); specgram(highfilt, 512, Fs);
highfilt = filtfilt(d,c,noisy);
subplot(3,1,3); specgram(lowfilt, 512, Fs);
%% Now vary the 'order' of the filter between 1 and 9. What happens?
%% Can you make a bandpass signal, where you filter out signal
%% below 1000 Hz and above 7700 Hz??
% First, we need a signal - let's use the zebra finch song
[ zfData zfFs ] = wavread('zfinch.wav');
% is the first value in our variable "zfData". The "-1" in the middle is the
% step size. It defaults to "1" - but we can give it whatever value you want, and
% "-1" means that the steps will go 1 at a time from the end to the first value.
zfRev = zfData(end:-1:1);
% We can halve the sample rate for both reverse and forward songs...
zfHalfRev = zfData(end:-2:1);
zfHalfData = zfData(1:2:end);
figure(1);
subplot(2,1,1);
plot(zfHalfData);
subplot(2,1,2);
plot(zfHalfRev);
% The find command is a powerful tool to extract portions of a signal.
% First let's get a signal and plot it:
[ zfData zfFs ] = wavread('zfinch.wav');
plot(tim,zfData);
tim = 1/zfFs:1/zfFs:length(zfData)/zfFs;
% We can use the "xlim" command to only plot the end.
% In this case we'll plot this syllable that starts at roughly
% 1.3 seconds and ends by 1.7 seconds.
xlim( [ 1.3 1.7 ] );
ylim([-0.75 0.75]);
pp = find ( tim > 1.45 & tim < 1.63);
% tim is larger than 1.45 and smaller than 1.63.
% pp is just sequence of integers.
figure(2);
plot(pp);
plot( tim(pp), zfData(pp) );
figure(1);
plot( tim, zfData,'b');
hold on;
plot( tim(pp) , zfData(pp) ,'r');
% OK - now another idea. Let's get only the values above a threshold
% Our threshold will be 0.1.
thresh = 0.1;
tt = find ( zfData > thresh );
% The "hold on" command allows you to plot on the same plot again
% (the default is to erase the old plot and do the new plot).
% You can turn this off using "hold off".
figure(3);
plot(tim, zfData,'b');
hold on;
plot( tim(tt), zfData(tt) ,'r' );
hold off;