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