Basic MATLAB
Functions and Final
Program in MATLAB
Christian Ryan Santos
Sherdon Niņo Uy


back to CE150




The library of MATLAB offers many useful tools to manipulate audio data. Aside from making matrix treatment easy for the user, audio data would also be a breeze to deal with. The following are commands which may be used in MATLAB readily.

o Daqrecord
o Wavrecord
o Wavread
o Wavwrite
o Butter
o Wavplay
o Find

The Daqrecord records any audio signal picked up from the microphone of the computer. This recording is resident to MATLAB only and cannot be recognized in other application softwares. This is used for data acquisition and returning the audio data in matrix form.

The Wavrecord is similar to Daqrecord except that it uses Windows standard audio recorder to acquire data. This opens the Windows recorder and records the sound from the microphone. The recorded sound is recognized as a data bearing a .wav extension. Wavplay simply opens a .wav file specified by the user and plays it to the PC speakers.

For the function Wavread, MATLAB will open a specified .wav file and read its contents. The user may declare how much bytes in the file will be read. The bytes read will be transformed to a matrix format. The Wavwrite creates a .wav file in the current directory. With this function, the user may write a .wav file to the disk at the specified folder. The filename is to be provided by the user. This is used for saving wave files into the disk.

To create filters, the Butter is used to create filters which follow the Butterworth polynomials. This basically filters out noise in order to obtain the desired audio data. The Find function is for searching undesired values in the data matrix acquired and discarding them. Essentially, it would search a matrix for all non-zero values and create a new matrix where MATLAB will place the non-zero values.

The basic MATLAB functions were used to do the following programs that made communication with the parallel port possible. The main functions are the following:

· Wavchop
· Jfilt
· PC

Wavchop was used as the function which opens a wavfile, removes the noise of the recorded voice, and saves the filtered file to another. This process was necessary in order to obtain all the necessary data of the voiced without the unwanted ones. This takes out the white noise and silence from the voice sample taken. To place the voice sample to the bandwidth where human voice is located, the Jfilt function was used. This function uses a butterworth bandpass filter to get rid of unvoiced speech and to reject received signals beyond human voice. It is also in this part where fast-fourier transform is implemented to reproduce the signal in a format much easier to analyze as compared to its time domain.

The main program that runs all these functions, including the MEX-files, is the PC.m. This program implements the threshold triggering in order to decipher from "left", "right", "go", "back", and "stop". This program records a voice command from the user and saves the file to disk. It then commences to call the Wavchop and Jfilt functions to filter the voice sample. After that, it would proceed to compare which threshold is triggered by the sampled voice. When it has finished with the voice analysis, it would then call on the corresponding MEX-file which contains the command that determines which data port must be turned high. The table below lists the commands that the RC can do and the corresponding commands that the user must say.



The following is the source code for voice analysis.
Jfilt.m:

function [r1,r2,r3]=jfilt(wfile)
% jfilt.m
% Speech Recognition of YES / NO
%  Filter for raw .wav files
% Copyright 1997 Jonathan Cline
%
%       This program is free software; you can redistribute it and/or
%       modify it under the terms of the GNU General Public License
%       as published by the Free Software Foundation; either version 2
%       of the License, or (at your option) any later version.
%
%       This program is distributed in the hope that it will be useful,
%       but WITHOUT ANY WARRANTY; without even the implied warranty of
%       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%       GNU General Public License for more details.
%
%       To obtain a copy of the GNU General Public License
%       write to the Free Software
%       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
%       02111-1307, USA,
%       or download it at http://www.gnu.org/copyleft/gpl.html
%
% version 10:44AM  6/13/1997

% These thresholds were experimentally determined
%  mileage may vary with climate
NO_THRESHOLD=4.5e4;
YES_THRESHOLD=2.5e4;

GO_T = 300; %370
BACK_T = 700; %650
STOP_T = 80;
RIGHT_T = 145; %270
LEFT_T = 20;




[w,Fs]=wavread(wfile);
if max(w) > 0
	w = w./(max(w));
end
N=8192;

%w=w-mean(w);   % don't do this (remove 'DC'); tweaks poles/zeroes all up

W=fft(w,N);
wmag=abs(W);
%wmag=wmag/max(wmag);

[range]=0:2*pi/N:(N-1)/N*2*pi;

% Create filter - butterworth bandpass. get only between 0.3 and 0.8

wn = [0.3 0.8];
[zeros,poles,K] = butter(5,wn, 'bandpass');
[num,den] = zp2tf(zeros, poles, 1);



[H,F] = freqz(num, den, N, Fs);
Hm = abs(H);


% Convolve magnitude of sound with magnitude of filter
out = wmag .* Hm;
% return values for use when called
% r2 is the filename of the input wav file
% r1 is the magic value which differentiates the sounds
%       ie, the maximum value of the output
r2=wfile;
r1=max(out);

% r3 is the match assumed for the sound file

if (r1 > BACK_T)
   r3 = 'Back';
elseif(r1 > GO_T)
   r3 = 'Go';
elseif (r1 > RIGHT_T)
   r3= 'Right';
elseif (r1 > STOP_T)
   r3 = 'Stop';
elseif (r1 > LEFT_T)
   r3 = 'Left';
else r3 = 'Indistinguishable';
end
         
% end matlab source

Wavchop.m:

function wavchop(wname,wnewname)
% Extract meaningful part of wav-file recorded via microphone
%   ie, chops off 'audio space' from beginning & end
% Copyright 1997 Jonathan Cline
%
%       This program is free software; you can redistribute it and/or
%       modify it under the terms of the GNU General Public License
%       as published by the Free Software Foundation; either version 2
%       of the License, or (at your option) any later version.
%
%       This program is distributed in the hope that it will be useful,
%       but WITHOUT ANY WARRANTY; without even the implied warranty of
%       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%       GNU General Public License for more details.
%
%       To obtain a copy of the GNU General Public License
%       write to the Free Software
%       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
%       02111-1307, USA,
%       or download it at http://www.gnu.org/copyleft/gpl.html.
%
% Example usage:  wavchop('myfile', 'newfile')
% version 2:00PM  6/3/1997

if nargin~=2
        error('WAVCHOP takes two arguments, ');
	error('which are the names of the .WAV files');
end

if isempty(findstr(wname,'.')) %==[]
        wname=[wname,'.wav'];
end

if isempty(findstr(wnewname,'.')) %==[]
        wnewname=[wnewname,'.wav'];
end

[wsave,Fs,fmt]=wavread(wname);

w=wsave;

% Normalize
wmean=mean(w);
%w=w-wmean; Don't do this
wmax=max(abs(w));
%w=w/wmax;  Or this either

% Extract signal, ie, remove near-0 parts at beginning & end
% actually trims parts @ beg & end less than 15% of absolute max value
wstart=0;
for k=1:size(w)
   if abs(w(k))>wmean+15*wmax/100 & wstart==0
   	wstart=k;
   end;
end
wstop=size(w);
for k=size(w):-1:1
        if abs(w(k))>wmean+15*wmax/100 & wstop==size(w)
                wstop=k;
        end
end;

wnew=w(wstart:wstop);

wavwrite(wnew,Fs,wnewname);

% end matlab source

PC.m:

%PC - Matlab program for controlling a remote controlled car using voice commands
function pc()

%Threshold values for specific commands
GO_T = 300; 		%370
BACK_T = 700; 		%850; %650
STOP_T = 80; 
RIGHT_T = 145; 	%270
LEFT_T = 20;

%some constants
GO = 1;
BACK = -1;
STOP = 0;
RIGHT = 2;
LEFT = -2;
STRAIGHT = 0;
currentFB = 0;
currentRL = 0;
Fs = 11025;		%sampling rate
r = 100;				%counter
punta0;				%stop as initial condition
for  s = 1:r
   pause;			%wait for user
	stream = wavrecord(1*Fs,Fs,'double');	%get command from user
   
   wavwrite(stream,Fs,'stream.wav');		%write it to file
   wavchop('stream.wav', 'stream.wav');	%get rid of unwanted data 
                                 (delete parts 15% below the average data)
   [a,b,c]=jfilt('stream.wav');			%make sense out of the data
   fprintf('%d\t%s\t%s\n',a,b,c);		%print result
   
         if (a > BACK_T)				%control the pc
            if (currentRL == LEFT & currentFB == STOP)
               punta6;
               currentRL = LEFT;
               currentFB = BACK;
            elseif (currentRL == RIGHT & currentFB == STOP)
               punta10;
               currentRL = RIGHT;
               currentFB = BACK;
            else 
               punta2;
               currentRL = STRAIGHT;
               currentFB = BACK;
            end               
         elseif(a > GO_T)
            if (currentRL == LEFT & currentFB == STOP)
               punta5;
               currentRL = LEFT;
               currentFB = GO;
            elseif (currentRL == RIGHT & currentFB == STOP)
               punta9;
               currentRL = RIGHT;
               currentFB = GO;
            else 
               punta1;
               currentRL = STRAIGHT;
               currentFB = GO;
            end   
			elseif (a > RIGHT_T)
            if (currentFB == GO)
               punta9;
               currentFB = GO;
               currentRL = RIGHT;
            elseif (currentFB == BACK)               
               punta10;
               currentFB = BACK;
               currentRL = RIGHT;
            else
               punta8;
               currentFB = STOP;
               currentRL = RIGHT;
            end
                    
			elseif (a > STOP_T)
            if (currentFB == GO)
               punta2;
            elseif (currentFB == BACK)
               punta1;
            end
            pause(1);
            punta0;
            currentRL = STRAIGHT;
            currentFB = STOP;
         elseif (a > LEFT_T)
            if (currentFB == GO)
               punta5;
               currentFB = GO;
               currentRL = LEFT;
            elseif (currentFB == BACK)               
               punta6;
               currentFB = BACK;
               currentRL = LEFT;
            else
               punta4;
               currentFB = STOP;
               currentRL = LEFT;
            end	   
         else 
            punta0;
            currentFB = STOP;
            currentRL = STRAIGHT;
         end
   s = s + 1;
end





back to CE150