annotate toolboxes/MIRtoolbox1.3.2/AuditoryToolbox/MakeVowel.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function y=MakeVowel(len, pitch, sampleRate, f1, f2, f3)
Daniel@0 2 % MakeVowel(len, pitch [, sampleRate, f1, f2, f3]) - Make a vowel with
Daniel@0 3 % "len" samples and the given pitch. The sample rate defaults to
Daniel@0 4 % be 22254.545454 Hz (the native Mactinosh Sampling Rate). The
Daniel@0 5 % formant frequencies are f1, f2 & f3. Some common vowels are
Daniel@0 6 % Vowel f1 f2 f3
Daniel@0 7 % /a/ 730 1090 2440
Daniel@0 8 % /i/ 270 2290 3010
Daniel@0 9 % /u/ 300 870 2240
Daniel@0 10 %
Daniel@0 11 % The pitch variable can either be a scalar indicating the actual
Daniel@0 12 % pitch frequency, or an array of impulse locations. Using an
Daniel@0 13 % array of impulses allows this routine to compute vowels with
Daniel@0 14 % varying pitch.
Daniel@0 15 %
Daniel@0 16 % Alternatively, f1 can be replaced with one of the following strings
Daniel@0 17 % 'a', 'i', 'u' and the appropriate formant frequencies are
Daniel@0 18 % automatically selected.
Daniel@0 19 % Modified by R. Duda, 3/13/94
Daniel@0 20
Daniel@0 21 % (c) 1998 Interval Research Corporation
Daniel@0 22
Daniel@0 23 if nargin < 2,
Daniel@0 24 fprintf('Format: y = MakeVowel(len, pitch [, sampleRate, f1, f2, f3])\n');
Daniel@0 25 return;
Daniel@0 26 end;
Daniel@0 27
Daniel@0 28 if nargin < 6; f3 = 0; end;
Daniel@0 29 if nargin < 5; f2 = 0; end;
Daniel@0 30 if nargin < 4,
Daniel@0 31 f1 = 0;
Daniel@0 32 else
Daniel@0 33 if isstr(f1)
Daniel@0 34 if f1 == 'a' | f1 == '/a/'
Daniel@0 35 f1=730; f2=1090; f3=2440;
Daniel@0 36 elseif f1 == 'i' | f1 == '/i/'
Daniel@0 37 f1=270; f2=2290; f3=3010;
Daniel@0 38 elseif f1 == 'u' | f1 == '/u/'
Daniel@0 39 f1=300; f2=870; f3=2240;
Daniel@0 40 end
Daniel@0 41 end;
Daniel@0 42 end;
Daniel@0 43
Daniel@0 44 if nargin < 3,
Daniel@0 45 sampleRate = 22254.545454;
Daniel@0 46 elseif sampleRate < 1000, % Apparently for test purposes
Daniel@0 47 sampleRate = 22254.545454;
Daniel@0 48 end;
Daniel@0 49
Daniel@0 50 % GlottalPulses(pitch, fs, len) - Generate a stream of
Daniel@0 51 % glottal pulses with the given pitch (in Hz) and sampling
Daniel@0 52 % frequency (sampleRate). A vector of the requested length is returned.
Daniel@0 53 y=zeros(1,len);
Daniel@0 54 if length(pitch) > 1, % If true, use to determine points
Daniel@0 55 points=pitch; % Check for valid sequence of points
Daniel@0 56 if any(points~=sort(points)),
Daniel@0 57 error('Values in pitch array must be in ascending order.')
Daniel@0 58 end;
Daniel@0 59 if points(1) < 1,
Daniel@0 60 error('Values in pitch array cannot be less than 1.');
Daniel@0 61 end;
Daniel@0 62 kmax=sum(points <= len);
Daniel@0 63 if kmax == 0,
Daniel@0 64 error('All values in pitch array exceed "len"; none should.');
Daniel@0 65 elseif kmax < length(points),
Daniel@0 66 fprintf('Some values in pitch array exceed "len"; truncating.\n');
Daniel@0 67 points=points(1:kmax);
Daniel@0 68 end;
Daniel@0 69 else
Daniel@0 70 points=1:sampleRate/pitch:len;
Daniel@0 71 end;
Daniel@0 72 indices=floor(points);
Daniel@0 73
Daniel@0 74 % Use a triangular approximation to an impulse function. The important
Daniel@0 75 % part is to keep the total amplitude the same.
Daniel@0 76 y(indices) = (indices+1)-points;
Daniel@0 77 y(indices+1) = points-indices;
Daniel@0 78
Daniel@0 79 % GlottalFilter(x,fs) - Filter an impulse train and simulate the glottal
Daniel@0 80 % transfer function. The sampling interval (sampleRate) is given in Hz.
Daniel@0 81 % The filtering performed by this function is two first-order filters
Daniel@0 82 % at 250Hz.
Daniel@0 83 a = exp(-250*2*pi/sampleRate);
Daniel@0 84 %y=filter([1,0,-1],[1,-2*a,a*a],y); % Not as good as one below....
Daniel@0 85 y=filter([1],[1,0,-a*a],y);
Daniel@0 86
Daniel@0 87 % FormantFilter(input, f, fs) - Filter an input sequence to model one
Daniel@0 88 % formant in a speech signal. The formant frequency (in Hz) is given
Daniel@0 89 % by f and the bandwidth of the formant is a constant 50Hz. The
Daniel@0 90 % sampling frequency in Hz is given by fs.
Daniel@0 91 if f1 > 0
Daniel@0 92 cft = f1/sampleRate;
Daniel@0 93 bw = 50;
Daniel@0 94 q = f1/bw;
Daniel@0 95 rho = exp(-pi * cft / q);
Daniel@0 96 theta = 2 * pi * cft * sqrt(1-1/(4 * q*q));
Daniel@0 97 a2 = -2*rho*cos(theta);
Daniel@0 98 a3 = rho*rho;
Daniel@0 99 y=filter([1+a2+a3],[1,a2,a3],y);
Daniel@0 100 end;
Daniel@0 101
Daniel@0 102 % FormantFilter(input, f, fs) - Filter an input sequence to model one
Daniel@0 103 % formant in a speech signal. The formant frequency (in Hz) is given
Daniel@0 104 % by f and the bandwidth of the formant is a constant 50Hz. The
Daniel@0 105 % sampling frequency in Hz is given by fs.
Daniel@0 106 if f2 > 0
Daniel@0 107 cft = f2/sampleRate;
Daniel@0 108 bw = 50;
Daniel@0 109 q = f2/bw;
Daniel@0 110 rho = exp(-pi * cft / q);
Daniel@0 111 theta = 2 * pi * cft * sqrt(1-1/(4 * q*q));
Daniel@0 112 a2 = -2*rho*cos(theta);
Daniel@0 113 a3 = rho*rho;
Daniel@0 114 y=filter([1+a2+a3],[1,a2,a3],y);
Daniel@0 115 end;
Daniel@0 116
Daniel@0 117 % FormantFilter(input, f, fs) - Filter an input sequence to model one
Daniel@0 118 % formant in a speech signal. The formant frequency (in Hz) is given
Daniel@0 119 % by f and the bandwidth of the formant is a constant 50Hz. The
Daniel@0 120 % sampling frequency in Hz is given by fs.
Daniel@0 121 if f3 > 0
Daniel@0 122 cft = f3/sampleRate;
Daniel@0 123 bw = 50;
Daniel@0 124 q = f3/bw;
Daniel@0 125 rho = exp(-pi * cft / q);
Daniel@0 126 theta = 2 * pi * cft * sqrt(1-1/(4 * q*q));
Daniel@0 127 a2 = -2*rho*cos(theta);
Daniel@0 128 a3 = rho*rho;
Daniel@0 129 y=filter([1+a2+a3],[1,a2,a3],y);
Daniel@0 130 end;