annotate toolboxes/MIRtoolbox1.3.2/AuditoryToolbox/synlpc.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function synWave = synlpc(aCoeff,source,sr,G,fr,fs,preemp)
wolffd@0 2 % USAGE: synWave = synlpc(aCoeff,source,sr,G,fr,fs,preemp);
wolffd@0 3 %
wolffd@0 4 % This function synthesizes a (speech) signal based on a LPC (linear-
wolffd@0 5 % predictive coding) model of the signal. The LPC coefficients are a
wolffd@0 6 % short-time measure of the speech signal which describe the signal as the
wolffd@0 7 % output of an all-pole filter. This all-pole filter provides a good
wolffd@0 8 % description of the speech articulators; thus LPC analysis is often used in
wolffd@0 9 % speech recognition and speech coding systems. The LPC analysis is done
wolffd@0 10 % using the proclpc routine. This routine can be used to verify that the
wolffd@0 11 % LPC analysis produces the correct answer, or as a synthesis stage after
wolffd@0 12 % first modifying the LPC model.
wolffd@0 13 %
wolffd@0 14 % The results of LPC analysis are a new representation of the signal
wolffd@0 15 % s(n) = G e(n) - sum from 1 to L a(i)s(n-i)
wolffd@0 16 % where s(n) is the original data. a(i) and e(n) are the outputs of the LPC
wolffd@0 17 % analysis with a(i) representing the LPC model. The e(n) term represents
wolffd@0 18 % either the speech source's excitation, or the residual: the details of the
wolffd@0 19 % signal that are not captured by the LPC coefficients. The G factor is a
wolffd@0 20 % gain term.
wolffd@0 21 %
wolffd@0 22 % LPC synthesis produces a monaural sound vector (synWave) which is
wolffd@0 23 % sampled at a sampling rate of "sr". The following parameters are mandatory
wolffd@0 24 % aCoeff - The LPC analysis results, a(i). One column of L+1 numbers for each
wolffd@0 25 % frame of data. The number of rows of aCoeff determines L.
wolffd@0 26 % source - The LPC residual, e(n). One column of sr*fs samples representing
wolffd@0 27 % the excitation or residual of the LPC filter.
wolffd@0 28 % G - The LPC gain for each frame.
wolffd@0 29 %
wolffd@0 30 % The following parameters are optional and default to the indicated values.
wolffd@0 31 % fr - Frame time increment, in ms. The LPC analysis is done starting every
wolffd@0 32 % fr ms in time. Defaults to 20ms (50 LPC vectors a second)
wolffd@0 33 % fs - Frame size in ms. The LPC analysis is done by windowing the speech
wolffd@0 34 % data with a rectangular window that is fs ms long. Defaults to 30ms
wolffd@0 35 % preemp - This variable is the epsilon in a digital one-zero filter which
wolffd@0 36 % serves to preemphasize the speech signal and compensate for the 6dB
wolffd@0 37 % per octave rolloff in the radiation function. Defaults to .9378.
wolffd@0 38 %
wolffd@0 39 % This code was graciously provided by:
wolffd@0 40 % Delores Etter (University of Colorado, Boulder) and
wolffd@0 41 % Professor Geoffrey Orsak (Southern Methodist University)
wolffd@0 42 % It was first published in
wolffd@0 43 % Orsak, G.C. et al. "Collaborative SP education using the Internet and
wolffd@0 44 % MATLAB" IEEE SIGNAL PROCESSING MAGAZINE Nov. 1995. vol.12, no.6, pp.
wolffd@0 45 % 23-32.
wolffd@0 46 % Modified and debugging plots added by Kate Nguyen and Malcolm Slaney
wolffd@0 47
wolffd@0 48 % (c) 1998 Interval Research Corporation
wolffd@0 49 % A more complete set of routines for LPC analysis can be found at
wolffd@0 50 % http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
wolffd@0 51
wolffd@0 52
wolffd@0 53
wolffd@0 54 if (nargin < 5), fr = 20; end;
wolffd@0 55 if (nargin < 6), fs = 30; end;
wolffd@0 56 if (nargin < 7), preemp = .9378; end;
wolffd@0 57
wolffd@0 58 msfs = round(sr*fs/1000);
wolffd@0 59 msfr = round(sr*fr/1000);
wolffd@0 60 msoverlap = msfs - msfr;
wolffd@0 61 ramp = [0:1/(msoverlap-1):1]';
wolffd@0 62 [L1 nframe] = size(aCoeff); % L1 = 1+number of LPC coeffs
wolffd@0 63
wolffd@0 64 [row col] = size(source);
wolffd@0 65 if(row==1 | col==1) % continous stream; must be
wolffd@0 66 % windowed
wolffd@0 67 postFilter = 0; duration = length(source); frameIndex = 1;
wolffd@0 68 for sampleIndex=1:msfr:duration-msfs+1
wolffd@0 69 resid(:,frameIndex) = source(sampleIndex:(sampleIndex+msfs-1))';
wolffd@0 70 frameIndex = frameIndex+1;
wolffd@0 71 end
wolffd@0 72 else
wolffd@0 73 postFilter = 1; resid = source;
wolffd@0 74 end
wolffd@0 75
wolffd@0 76 [row col] = size(resid);
wolffd@0 77 %if ~(col==nframe)
wolffd@0 78 % error('synLPC: numbers of LPC frames and source frames do not match');
wolffd@0 79 if col<nframe
wolffd@0 80 nframe=col;
wolffd@0 81 end
wolffd@0 82
wolffd@0 83 for frameIndex=1:nframe
wolffd@0 84 % Calculate the filter response
wolffd@0 85 % by evaluating the z-transform
wolffd@0 86 % if 1
wolffd@0 87 % gain=0;
wolffd@0 88 % cft=0:(1/255):1;
wolffd@0 89 % for index=1:L1-1
wolffd@0 90 % gain = gain + aCoeff(index,frameIndex)*exp(-i*2*pi*cft).^index;
wolffd@0 91 % end
wolffd@0 92 % gain = abs(1./gain);
wolffd@0 93 % spec(:,frameIndex) = 20*log10(gain(1:128))';
wolffd@0 94 % plot(20*log10(gain));
wolffd@0 95 % title(frameIndex);
wolffd@0 96 % drawnow;
wolffd@0 97 % end
wolffd@0 98
wolffd@0 99 % Calculate the filter response
wolffd@0 100 % from the filter's impulse
wolffd@0 101 % response (to check above).
wolffd@0 102 % if 0
wolffd@0 103 % impulseResponse = filter(1, aCoeff(:,frameIndex), [1 zeros(1,255)]);
wolffd@0 104 % freqResp = 20*log10(abs(fft(impulseResponse)));
wolffd@0 105 % plot(freqResp);
wolffd@0 106 % end
wolffd@0 107
wolffd@0 108
wolffd@0 109 A = aCoeff(:,frameIndex);
wolffd@0 110 residFrame = resid(:,frameIndex)*G(frameIndex);
wolffd@0 111 synFrame = filter(1, A', residFrame); % synthesize speech from LPC
wolffd@0 112 % coeffs
wolffd@0 113 if(frameIndex==1) % add synthesize frames using a
wolffd@0 114 synWave = synFrame(1:msfr); % trapezoidal window
wolffd@0 115 else
wolffd@0 116 synWave = [synWave; overlap+synFrame(1:msoverlap).*ramp; ...
wolffd@0 117 synFrame(msoverlap+1:msfr)];
wolffd@0 118 end
wolffd@0 119 if(frameIndex==nframe)
wolffd@0 120 synWave = [synWave; synFrame(msfr+1:msfs)];
wolffd@0 121 else
wolffd@0 122 overlap = synFrame(msfr+1:msfs).*flipud(ramp);
wolffd@0 123 end
wolffd@0 124 %length(synWave)
wolffd@0 125 end;
wolffd@0 126
wolffd@0 127 if(postFilter)
wolffd@0 128 synWave = filter(1, [1 -preemp], synWave);
wolffd@0 129 end
wolffd@0 130