Standard LPC analysis separates a signal into a smoothed spectral representation - the resonances of a time-varying all-pole filter - and an approximately-white excitation which, when passed through the time-varying filter, reproduces the original signal. This decomposition is the basis of all kinds of compression and modification techniques.

One thing we can do is systematically shift the resonant frequencies of the LPC model by applying a warping transformation to the IIR filter (essentially, substituting an all-pole system for each delay element). The perceptual effect of this, for voice, is to change the 'color' of the speaker's voice, making it darker for a shift down, or brighter for a shift up. Pitch (which is represented in the excitation) does not change, and intelligibility and naturalness can be quite good.

The code and example on this page show a simple implementation of LPC spectral warping to effect a voice modification.

The routines provided here are:

- [B,A] = warppoles(a, alpha) warps the all-pole filter defined by numerator coefficients a using a first-order allpass substitution with parameter alpha to generate a new filter (with poles and zeros) defined by polynomials B and A. Negative alpha results in shifting poles up in frequency.
- [A,G,E] = lpcfit(D,P,H,W,O) fits P-th order LPC (all-pole, autoregressive) models to sound waveform D, using W-point windows advanced by H samples. Rows of A contain all-pole filter coefficiets [1 a1 a2 .. aP], with corresponding elements of G giving the frame gain (residual RMS). E is the actual excitation residual. Specifying OV as zero prevents overlap-add of the residual, for perfect reconstruction but a less useful E. (Same function as on the SWS page)
- D = lpcsynth(A,G,E,H,OV) resynthesizes from LPC parameters returned by lpcfit, or using noise excitation if E is omitted.

An example use is shown below:

>> % Load a speech waveform >> [d,sr] = wavread('sm1_cln.wav'); >> >> % Fit the original LPC model (high-order) >> [a,g,e] = lpcfit(d,20); >> >> % Warp the poles up a little >> % (warppoles modifies every frame - rows of a - at the same time) >> alpha = -0.2; >> [bhat, ahat] = warppoles(a, alpha); >> >> % Resynthesize with the new LPC >> % (fortunately, bhat is the same for all frames) >> dw = filter(bhat(1,:), 1, lpcsynth(ahat, g, e)); >> >> % Listen to the original... >> soundsc(d,sr); >> % ... and compare warped version >> soundsc(dw, sr);

Last updated: $Date: 2004/07/12 17:30:39 $

Dan Ellis <dpwe@ee.columbia.edu>