%record and play back as fast as possible
%with digital filtering

clear all;
clf;
delete(daqfind);

%sample rate and number of inputs per tirgger
numinput = 2000;
samrate = 8000;

%Configure the Filter
type='butter'; %Choose: butter|cheby|parks
filterlength=8;
%frequencies a a fraction of the nyquist freq
locut=.1;
hicut=.4;
if hicut<=locut
   hicut=locut+.01;
end

switch type
case 'butter' 
   if locut==0
      [b,a] = butter(filterlength,hicut);
   else
      [b,a] = butter(filterlength,[locut,hicut]);
   end   
case 'cheby'
   ripple=1;
   if locut==0
      [b,a] = cheby1(filterlength,ripple,hicut);
   else
      [b,a] = cheby1(filterlength,ripple,[locut,hicut]);
   end  
case 'parks'
   numSamples = 51;
   if locut==0
      freq = [0 hicut hicut+.1 1]; 
      amp = [1 1 0 0];
   else
      freq = [0 locut-.1 locut hicut hicut+.1 1]; 
      amp = [0 0 1 1 0 0];
   end
   b = remez(numSamples,freq,amp);
   a = [ 1 zeros(length(b)-1,1)'];   
end

[fresponse, ffreq] = freqz(b,a,1000);

figure(1)

%plot the filter freq response
subplot(3,1,2)
plot(ffreq/pi*samrate/2,abs(fresponse));
xlabel('frequency')
ylabel('filter response')
axis([0 samrate/2 0 2]);

%Set up the analog i/o
adaptor = 'winsound';
id = 0;
chan = 1;

% Input Object Configuration.
% Create an analog input object with one channel.
ai = analoginput(adaptor, id);
ch = addchannel(ai, chan);
set(ai, 'SampleRate', samrate);
set(ai, 'SamplesPerTrigger', numinput);
set(ai, 'TriggerRepeat', 1);
set(ai, 'TriggerType', 'Manual');

% Input Object Execution.
% Start the analog input object.
start(ai);
trigger(ai);
% Obtain the available time and data.
getdata(ai, ai.SamplesPerTrigger);

% Analog output object Configuration.
% Create an analog input object with one channel.
ao = analogoutput(adaptor, id);
ch = addchannel(ao, chan);
set(ao, 'SampleRate', samrate);

%need to initialize the first
music = zeros(numinput,1);

%window to minimize 'clicking' at sample ends
window = ...
   [0;.12;.25;.75;ones(numinput-8,1);.75;.25;.12;0];

%plot of spectrum of filtered signal
subplot(3,1,3)
[spect,freq]=periodogram(music,[],[],samrate);
fline=plot(freq,spect);
set(gca,'ylim',[0 .001]);
xlabel('frequency'); ylabel('filtered amp');

%plot of spectrum of raw signal
subplot(3,1,1)
[spect,freq]=periodogram(music,[],[],samrate);
iline=plot(freq,spect);
set(gca,'ylim',[0 .001]);
xlabel('frequency'); ylabel('music amp');

%one gui element to stop the music
stopit=0;
quitbutton=uicontrol('Style','pushbutton',...
      'Position',[0 0 45 25],...
      'String','Quit',...
      'callback', 'stopit=1;');
   
while (stopit==0)
   
   %play the previous sample
   putdata(ao, music);  
   %start output and trigger it
   start(ao);
   
   %get the next sample, compute the spectrum
   %and display it
   music = peekdata(ai, ai.SamplesPerTrigger);
   spect = periodogram(music,[],[],samrate);
   set(iline,'ydata',spect);

   %filter it , compute the spectrum and display
   music = filter(b,a,music) .* window;
   spect=periodogram(music,[],[],samrate);
   set(fline,'ydata',spect);
   
   drawnow
   
   %Wait until output is done
   run=1;
   while run==1
      %use try/catch to avoid errors
      try
         run=strcmp(ao.Running, 'On');
      catch
         stop(daqfind);
         delete(daqfind);
         error('bad analog output')
         run=0;
      end  
   end
   
end

%stop everything and delete it
stop(ao)
stop(ai)
delete(ao)
delete(ai)
