wolffd@0: function [output,aCoeff] = WhiteVowel(data,sr,L,pos) wolffd@0: % function [output,aCoeff] = WhiteVowel(data,sr,L,pos) wolffd@0: % wolffd@0: % Speech is often described as having spectral peaks or formants which wolffd@0: % identify the phonetic signal. An interesting experiment, first proposed by wolffd@0: % XXX, filters a speech signal to remove all the formant information at one wolffd@0: % time during the speech. If there are no formant peaks, how can the speech wolffd@0: % be understood? It turns out that processing, much like RASTA, means that wolffd@0: % relative changes in spectrum are the most important, thus the speech signal wolffd@0: % is understood because the formant transitions carry the information. This wolffd@0: % gives speech an important transparency due wolffd@0: % wolffd@0: % This function takes a speech signal (data) with a given sampling rate (sr). wolffd@0: % It then finds the L-order LPC filter that describes the speech at the given wolffd@0: % position (pos ms). The entire speech signal is then filtered with the wolffd@0: % inverse of the LPC filter, effectively turning the speech spectrum at the wolffd@0: % given time white (flat). wolffd@0: wolffd@0: % Chris Pal, Interval, May 1997 wolffd@0: % (c) 1998 Interval Research Corporation wolffd@0: wolffd@0: fr = 20; fs = 30; preemp = .9378; % LPC defaults wolffd@0: wolffd@0: [row col] = size(data); wolffd@0: if col==1 data=data'; end wolffd@0: wolffd@0: nframe = 0; wolffd@0: msfr = round(sr/1000*fr); wolffd@0: msfs = round(sr/1000*fs); wolffd@0: duration = length(data); wolffd@0: msoverlap = msfs - msfr; wolffd@0: frameNumber = floor(pos/1000*sr/msfr); wolffd@0: wolffd@0: frameStart = round(pos/1000*sr - msfs/2); wolffd@0: frameData = data(frameStart:(frameStart+msfs-1)); wolffd@0: aCoeff = proclpc(frameData, sr, L, fr, fs, preemp); wolffd@0: % Calculate the filter response wolffd@0: % by evaluating the z-transform wolffd@0: spec=lpc_spec(aCoeff); wolffd@0: subplot(2,3,1); wolffd@0: plot(spec); wolffd@0: title('LPC Spectral Slice'); wolffd@0: ylabel('Original') wolffd@0: wolffd@0: % Now do the actual whitening filter wolffd@0: output = filter(aCoeff,1,data)'; wolffd@0: wolffd@0: frameData = output(frameStart:(frameStart+msfs-1)); wolffd@0: bCoeff = proclpc(frameData, sr, L, fr, fs, preemp); wolffd@0: spec=lpc_spec(bCoeff); wolffd@0: subplot(2,3,4); wolffd@0: plot(spec); wolffd@0: ylabel('Whitened'); xlabel('FFT Bin'); wolffd@0: wolffd@0: % 256-DFT wolffd@0: origSpec = 20*log10(abs(specgram(data,512,sr,msfs,msoverlap))); wolffd@0: subplot(2,3,2),imagesc(origSpec); axis xy; colormap(1-gray); wolffd@0: title('Spectrogram'); wolffd@0: wolffd@0: synSpec = 20*log10(abs(specgram(output,512,sr,msfs,msoverlap))); wolffd@0: subplot(2,3,5),imagesc(synSpec); axis xy; colormap(1-gray); wolffd@0: xlabel('Frame #'); wolffd@0: wolffd@0: origloc = origSpec(:,frameNumber); origloc=origloc-max(origloc);origmin=min(origloc); wolffd@0: subplot(2,3,3),plot(origloc),title('Spectrogram'), wolffd@0: axis([1 length(origloc) origmin 0]); wolffd@0: wolffd@0: filloc = synSpec(:,frameNumber); filloc=filloc-max(filloc); wolffd@0: subplot(2,3,6),plot(filloc);ylabel('db'); wolffd@0: axis([1 length(origloc) origmin 0]); wolffd@0: xlabel('FFT Bin'); wolffd@0: wolffd@0: function spec=lpc_spec(aCoeff) wolffd@0: gain=0; wolffd@0: cft=0:(1/255):1; wolffd@0: for index=1:size(aCoeff,1) wolffd@0: gain = gain + aCoeff(index)*exp(-i*2*pi*cft).^index; wolffd@0: end wolffd@0: gain = abs(1./gain); wolffd@0: spec = 20*log10(gain(1:128))';