wolffd@0: function y=MakeVowel(len, pitch, sampleRate, f1, f2, f3) wolffd@0: % MakeVowel(len, pitch [, sampleRate, f1, f2, f3]) - Make a vowel with wolffd@0: % "len" samples and the given pitch. The sample rate defaults to wolffd@0: % be 22254.545454 Hz (the native Mactinosh Sampling Rate). The wolffd@0: % formant frequencies are f1, f2 & f3. Some common vowels are wolffd@0: % Vowel f1 f2 f3 wolffd@0: % /a/ 730 1090 2440 wolffd@0: % /i/ 270 2290 3010 wolffd@0: % /u/ 300 870 2240 wolffd@0: % wolffd@0: % The pitch variable can either be a scalar indicating the actual wolffd@0: % pitch frequency, or an array of impulse locations. Using an wolffd@0: % array of impulses allows this routine to compute vowels with wolffd@0: % varying pitch. wolffd@0: % wolffd@0: % Alternatively, f1 can be replaced with one of the following strings wolffd@0: % 'a', 'i', 'u' and the appropriate formant frequencies are wolffd@0: % automatically selected. wolffd@0: % Modified by R. Duda, 3/13/94 wolffd@0: wolffd@0: % (c) 1998 Interval Research Corporation wolffd@0: wolffd@0: if nargin < 2, wolffd@0: fprintf('Format: y = MakeVowel(len, pitch [, sampleRate, f1, f2, f3])\n'); wolffd@0: return; wolffd@0: end; wolffd@0: wolffd@0: if nargin < 6; f3 = 0; end; wolffd@0: if nargin < 5; f2 = 0; end; wolffd@0: if nargin < 4, wolffd@0: f1 = 0; wolffd@0: else wolffd@0: if isstr(f1) wolffd@0: if f1 == 'a' | f1 == '/a/' wolffd@0: f1=730; f2=1090; f3=2440; wolffd@0: elseif f1 == 'i' | f1 == '/i/' wolffd@0: f1=270; f2=2290; f3=3010; wolffd@0: elseif f1 == 'u' | f1 == '/u/' wolffd@0: f1=300; f2=870; f3=2240; wolffd@0: end wolffd@0: end; wolffd@0: end; wolffd@0: wolffd@0: if nargin < 3, wolffd@0: sampleRate = 22254.545454; wolffd@0: elseif sampleRate < 1000, % Apparently for test purposes wolffd@0: sampleRate = 22254.545454; wolffd@0: end; wolffd@0: wolffd@0: % GlottalPulses(pitch, fs, len) - Generate a stream of wolffd@0: % glottal pulses with the given pitch (in Hz) and sampling wolffd@0: % frequency (sampleRate). A vector of the requested length is returned. wolffd@0: y=zeros(1,len); wolffd@0: if length(pitch) > 1, % If true, use to determine points wolffd@0: points=pitch; % Check for valid sequence of points wolffd@0: if any(points~=sort(points)), wolffd@0: error('Values in pitch array must be in ascending order.') wolffd@0: end; wolffd@0: if points(1) < 1, wolffd@0: error('Values in pitch array cannot be less than 1.'); wolffd@0: end; wolffd@0: kmax=sum(points <= len); wolffd@0: if kmax == 0, wolffd@0: error('All values in pitch array exceed "len"; none should.'); wolffd@0: elseif kmax < length(points), wolffd@0: fprintf('Some values in pitch array exceed "len"; truncating.\n'); wolffd@0: points=points(1:kmax); wolffd@0: end; wolffd@0: else wolffd@0: points=1:sampleRate/pitch:len; wolffd@0: end; wolffd@0: indices=floor(points); wolffd@0: wolffd@0: % Use a triangular approximation to an impulse function. The important wolffd@0: % part is to keep the total amplitude the same. wolffd@0: y(indices) = (indices+1)-points; wolffd@0: y(indices+1) = points-indices; wolffd@0: wolffd@0: % GlottalFilter(x,fs) - Filter an impulse train and simulate the glottal wolffd@0: % transfer function. The sampling interval (sampleRate) is given in Hz. wolffd@0: % The filtering performed by this function is two first-order filters wolffd@0: % at 250Hz. wolffd@0: a = exp(-250*2*pi/sampleRate); wolffd@0: %y=filter([1,0,-1],[1,-2*a,a*a],y); % Not as good as one below.... wolffd@0: y=filter([1],[1,0,-a*a],y); wolffd@0: wolffd@0: % FormantFilter(input, f, fs) - Filter an input sequence to model one wolffd@0: % formant in a speech signal. The formant frequency (in Hz) is given wolffd@0: % by f and the bandwidth of the formant is a constant 50Hz. The wolffd@0: % sampling frequency in Hz is given by fs. wolffd@0: if f1 > 0 wolffd@0: cft = f1/sampleRate; wolffd@0: bw = 50; wolffd@0: q = f1/bw; wolffd@0: rho = exp(-pi * cft / q); wolffd@0: theta = 2 * pi * cft * sqrt(1-1/(4 * q*q)); wolffd@0: a2 = -2*rho*cos(theta); wolffd@0: a3 = rho*rho; wolffd@0: y=filter([1+a2+a3],[1,a2,a3],y); wolffd@0: end; wolffd@0: wolffd@0: % FormantFilter(input, f, fs) - Filter an input sequence to model one wolffd@0: % formant in a speech signal. The formant frequency (in Hz) is given wolffd@0: % by f and the bandwidth of the formant is a constant 50Hz. The wolffd@0: % sampling frequency in Hz is given by fs. wolffd@0: if f2 > 0 wolffd@0: cft = f2/sampleRate; wolffd@0: bw = 50; wolffd@0: q = f2/bw; wolffd@0: rho = exp(-pi * cft / q); wolffd@0: theta = 2 * pi * cft * sqrt(1-1/(4 * q*q)); wolffd@0: a2 = -2*rho*cos(theta); wolffd@0: a3 = rho*rho; wolffd@0: y=filter([1+a2+a3],[1,a2,a3],y); wolffd@0: end; wolffd@0: wolffd@0: % FormantFilter(input, f, fs) - Filter an input sequence to model one wolffd@0: % formant in a speech signal. The formant frequency (in Hz) is given wolffd@0: % by f and the bandwidth of the formant is a constant 50Hz. The wolffd@0: % sampling frequency in Hz is given by fs. wolffd@0: if f3 > 0 wolffd@0: cft = f3/sampleRate; wolffd@0: bw = 50; wolffd@0: q = f3/bw; wolffd@0: rho = exp(-pi * cft / q); wolffd@0: theta = 2 * pi * cft * sqrt(1-1/(4 * q*q)); wolffd@0: a2 = -2*rho*cos(theta); wolffd@0: a3 = rho*rho; wolffd@0: y=filter([1+a2+a3],[1,a2,a3],y); wolffd@0: end;