annotate toolboxes/MIRtoolbox1.3.2/AuditoryToolbox/proclpc.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 [aCoeff,resid,pitch,G,parcor,stream] = proclpc(data,sr,L,fr,fs,preemp)
Daniel@0 2 % USAGE: [aCoeff,resid,pitch,G,parcor,stream] = proclpc(data,sr,L,fr,fs,preemp)
Daniel@0 3 %
Daniel@0 4 % This function computes the LPC (linear-predictive coding) coefficients that
Daniel@0 5 % describe a speech signal. The LPC coefficients are a short-time measure of
Daniel@0 6 % the speech signal which describe the signal as the output of an all-pole
Daniel@0 7 % filter. This all-pole filter provides a good description of the speech
Daniel@0 8 % articulators; thus LPC analysis is often used in speech recognition and
Daniel@0 9 % speech coding systems. The LPC parameters are recalculated, by default in
Daniel@0 10 % this implementation, every 20ms.
Daniel@0 11 %
Daniel@0 12 % The results of LPC analysis are a new representation of the signal
Daniel@0 13 % s(n) = G e(n) - sum from 1 to L a(i)s(n-i)
Daniel@0 14 % where s(n) is the original data. a(i) and e(n) are the outputs of the LPC
Daniel@0 15 % analysis with a(i) representing the LPC model. The e(n) term represents
Daniel@0 16 % either the speech source's excitation, or the residual: the details of the
Daniel@0 17 % signal that are not captured by the LPC coefficients. The G factor is a
Daniel@0 18 % gain term.
Daniel@0 19 %
Daniel@0 20 % LPC analysis is performed on a monaural sound vector (data) which has been
Daniel@0 21 % sampled at a sampling rate of "sr". The following optional parameters modify
Daniel@0 22 % the behaviour of this algorithm.
Daniel@0 23 % L - The order of the analysis. There are L+1 LPC coefficients in the output
Daniel@0 24 % array aCoeff for each frame of data. L defaults to 13.
Daniel@0 25 % fr - Frame time increment, in ms. The LPC analysis is done starting every
Daniel@0 26 % fr ms in time. Defaults to 20ms (50 LPC vectors a second)
Daniel@0 27 % fs - Frame size in ms. The LPC analysis is done by windowing the speech
Daniel@0 28 % data with a rectangular window that is fs ms long. Defaults to 30ms
Daniel@0 29 % preemp - This variable is the epsilon in a digital one-zero filter which
Daniel@0 30 % serves to preemphasize the speech signal and compensate for the 6dB
Daniel@0 31 % per octave rolloff in the radiation function. Defaults to .9378.
Daniel@0 32 %
Daniel@0 33 % The output variables from this function are
Daniel@0 34 % aCoeff - The LPC analysis results, a(i). One column of L numbers for each
Daniel@0 35 % frame of data
Daniel@0 36 % resid - The LPC residual, e(n). One column of sr*fs samples representing
Daniel@0 37 % the excitation or residual of the LPC filter.
Daniel@0 38 % pitch - A frame-by-frame estimate of the pitch of the signal, calculated
Daniel@0 39 % by finding the peak in the residual's autocorrelation for each frame.
Daniel@0 40 % G - The LPC gain for each frame.
Daniel@0 41 % parcor - The parcor coefficients. The parcor coefficients give the ratio
Daniel@0 42 % between adjacent sections in a tubular model of the speech
Daniel@0 43 % articulators. There are L parcor coefficients for each frame of
Daniel@0 44 % speech.
Daniel@0 45 % stream - The LPC analysis' residual or excitation signal as one long vector.
Daniel@0 46 % Overlapping frames of the resid output combined into a new one-
Daniel@0 47 % dimensional signal and post-filtered.
Daniel@0 48 %
Daniel@0 49 % The synlpc routine inverts this transform and returns the original speech
Daniel@0 50 % signal.
Daniel@0 51 %
Daniel@0 52 % This code was graciously provided by:
Daniel@0 53 % Delores Etter (University of Colorado, Boulder) and
Daniel@0 54 % Professor Geoffrey Orsak (Southern Methodist University)
Daniel@0 55 % It was first published in
Daniel@0 56 % Orsak, G.C. et al. "Collaborative SP education using the Internet and
Daniel@0 57 % MATLAB" IEEE SIGNAL PROCESSING MAGAZINE Nov. 1995. vol.12, no.6, pp.
Daniel@0 58 % 23-32.
Daniel@0 59 % Modified and debugging plots added by Kate Nguyen and Malcolm Slaney
Daniel@0 60
Daniel@0 61 % A more complete set of routines for LPC analysis can be found at
Daniel@0 62 % http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
Daniel@0 63
Daniel@0 64 % (c) 1998 Interval Research Corporation
Daniel@0 65
Daniel@0 66
Daniel@0 67 if (nargin<3), L = 13; end
Daniel@0 68 if (nargin<4), fr = 20; end
Daniel@0 69 if (nargin<5), fs = 30; end
Daniel@0 70 if (nargin<6), preemp = .9378; end
Daniel@0 71
Daniel@0 72 [row col] = size(data);
Daniel@0 73 if col==1 data=data'; end
Daniel@0 74
Daniel@0 75 nframe = 0;
Daniel@0 76 msfr = round(sr/1000*fr); % Convert ms to samples
Daniel@0 77 msfs = round(sr/1000*fs); % Convert ms to samples
Daniel@0 78 duration = length(data);
Daniel@0 79 speech = filter([1 -preemp], 1, data)'; % Preemphasize speech
Daniel@0 80 msoverlap = msfs - msfr;
Daniel@0 81 ramp = [0:1/(msoverlap-1):1]'; % Compute part of window
Daniel@0 82
Daniel@0 83
Daniel@0 84 for frameIndex=1:msfr:duration-msfs+1 % frame rate=20ms
Daniel@0 85 frameData = speech(frameIndex:(frameIndex+msfs-1)); % frame size=30ms
Daniel@0 86 nframe = nframe+1;
Daniel@0 87 autoCor = xcorr(frameData); % Compute the cross correlation
Daniel@0 88 autoCorVec = autoCor(msfs+[0:L]);
Daniel@0 89
Daniel@0 90 % Levinson's method
Daniel@0 91 err(1) = autoCorVec(1);
Daniel@0 92 k(1) = 0;
Daniel@0 93 A = [];
Daniel@0 94 for index=1:L
Daniel@0 95 numerator = [1 A.']*autoCorVec(index+1:-1:2);
Daniel@0 96 denominator = -1*err(index);
Daniel@0 97 k(index) = numerator/denominator; % PARCOR coeffs
Daniel@0 98 A = [A+k(index)*flipud(A); k(index)];
Daniel@0 99 err(index+1) = (1-k(index)^2)*err(index);
Daniel@0 100 end
Daniel@0 101
Daniel@0 102 aCoeff(:,nframe) = [1; A];
Daniel@0 103 parcor(:,nframe) = k';
Daniel@0 104
Daniel@0 105 % Calculate the filter
Daniel@0 106 % response
Daniel@0 107 % by evaluating the
Daniel@0 108 % z-transform
Daniel@0 109 if 0
Daniel@0 110 gain=0;
Daniel@0 111 cft=0:(1/255):1;
Daniel@0 112 for index=1:L
Daniel@0 113 gain = gain + aCoeff(index,nframe)*exp(-i*2*pi*cft).^index;
Daniel@0 114 end
Daniel@0 115 gain = abs(1./gain);
Daniel@0 116 spec(:,nframe) = 20*log10(gain(1:128))';
Daniel@0 117 plot(20*log10(gain));
Daniel@0 118 title(nframe);
Daniel@0 119 drawnow;
Daniel@0 120 end
Daniel@0 121
Daniel@0 122 % Calculate the filter response
Daniel@0 123 % from the filter's impulse
Daniel@0 124 % response (to check above).
Daniel@0 125 if 0
Daniel@0 126 impulseResponse = filter(1, aCoeff(:,nframe), [1 zeros(1,255)]);
Daniel@0 127 freqResp = 20*log10(abs(fft(impulseResponse)));
Daniel@0 128 plot(freqResp);
Daniel@0 129 end
Daniel@0 130
Daniel@0 131 errSig = filter([1 A'],1,frameData); % find excitation noise
Daniel@0 132
Daniel@0 133 G(nframe) = sqrt(err(L+1)); % gain
Daniel@0 134 autoCorErr = xcorr(errSig); % calculate pitch & voicing
Daniel@0 135 % information
Daniel@0 136 [B,I] = sort(autoCorErr);
Daniel@0 137 num = length(I);
Daniel@0 138 if B(num-1) > .3*B(num)
Daniel@0 139 pitch(nframe) = abs(I(num) - I(num-1));
Daniel@0 140 else
Daniel@0 141 pitch(nframe) = 0;
Daniel@0 142 end
Daniel@0 143
Daniel@0 144 resid(:,nframe) = errSig/G(nframe);
Daniel@0 145 if(frameIndex==1) % add residual frames using a
Daniel@0 146 stream = resid(1:msfr,nframe); % trapezoidal window
Daniel@0 147 else
Daniel@0 148 stream = [stream;
Daniel@0 149 overlap+resid(1:msoverlap,nframe).*ramp;
Daniel@0 150 resid(msoverlap+1:msfr,nframe)];
Daniel@0 151 end
Daniel@0 152 if(frameIndex+msfr+msfs-1 > duration)
Daniel@0 153 stream = [stream; resid(msfr+1:msfs,nframe)];
Daniel@0 154 else
Daniel@0 155 overlap = resid(msfr+1:msfs,nframe).*flipud(ramp);
Daniel@0 156 end
Daniel@0 157 end
Daniel@0 158 stream = filter(1, [1 -preemp], stream)';