wolffd@0
|
1 function [output,aCoeff] = WhiteVowel(data,sr,L,pos)
|
wolffd@0
|
2 % function [output,aCoeff] = WhiteVowel(data,sr,L,pos)
|
wolffd@0
|
3 %
|
wolffd@0
|
4 % Speech is often described as having spectral peaks or formants which
|
wolffd@0
|
5 % identify the phonetic signal. An interesting experiment, first proposed by
|
wolffd@0
|
6 % XXX, filters a speech signal to remove all the formant information at one
|
wolffd@0
|
7 % time during the speech. If there are no formant peaks, how can the speech
|
wolffd@0
|
8 % be understood? It turns out that processing, much like RASTA, means that
|
wolffd@0
|
9 % relative changes in spectrum are the most important, thus the speech signal
|
wolffd@0
|
10 % is understood because the formant transitions carry the information. This
|
wolffd@0
|
11 % gives speech an important transparency due
|
wolffd@0
|
12 %
|
wolffd@0
|
13 % This function takes a speech signal (data) with a given sampling rate (sr).
|
wolffd@0
|
14 % It then finds the L-order LPC filter that describes the speech at the given
|
wolffd@0
|
15 % position (pos ms). The entire speech signal is then filtered with the
|
wolffd@0
|
16 % inverse of the LPC filter, effectively turning the speech spectrum at the
|
wolffd@0
|
17 % given time white (flat).
|
wolffd@0
|
18
|
wolffd@0
|
19 % Chris Pal, Interval, May 1997
|
wolffd@0
|
20 % (c) 1998 Interval Research Corporation
|
wolffd@0
|
21
|
wolffd@0
|
22 fr = 20; fs = 30; preemp = .9378; % LPC defaults
|
wolffd@0
|
23
|
wolffd@0
|
24 [row col] = size(data);
|
wolffd@0
|
25 if col==1 data=data'; end
|
wolffd@0
|
26
|
wolffd@0
|
27 nframe = 0;
|
wolffd@0
|
28 msfr = round(sr/1000*fr);
|
wolffd@0
|
29 msfs = round(sr/1000*fs);
|
wolffd@0
|
30 duration = length(data);
|
wolffd@0
|
31 msoverlap = msfs - msfr;
|
wolffd@0
|
32 frameNumber = floor(pos/1000*sr/msfr);
|
wolffd@0
|
33
|
wolffd@0
|
34 frameStart = round(pos/1000*sr - msfs/2);
|
wolffd@0
|
35 frameData = data(frameStart:(frameStart+msfs-1));
|
wolffd@0
|
36 aCoeff = proclpc(frameData, sr, L, fr, fs, preemp);
|
wolffd@0
|
37 % Calculate the filter response
|
wolffd@0
|
38 % by evaluating the z-transform
|
wolffd@0
|
39 spec=lpc_spec(aCoeff);
|
wolffd@0
|
40 subplot(2,3,1);
|
wolffd@0
|
41 plot(spec);
|
wolffd@0
|
42 title('LPC Spectral Slice');
|
wolffd@0
|
43 ylabel('Original')
|
wolffd@0
|
44
|
wolffd@0
|
45 % Now do the actual whitening filter
|
wolffd@0
|
46 output = filter(aCoeff,1,data)';
|
wolffd@0
|
47
|
wolffd@0
|
48 frameData = output(frameStart:(frameStart+msfs-1));
|
wolffd@0
|
49 bCoeff = proclpc(frameData, sr, L, fr, fs, preemp);
|
wolffd@0
|
50 spec=lpc_spec(bCoeff);
|
wolffd@0
|
51 subplot(2,3,4);
|
wolffd@0
|
52 plot(spec);
|
wolffd@0
|
53 ylabel('Whitened'); xlabel('FFT Bin');
|
wolffd@0
|
54
|
wolffd@0
|
55 % 256-DFT
|
wolffd@0
|
56 origSpec = 20*log10(abs(specgram(data,512,sr,msfs,msoverlap)));
|
wolffd@0
|
57 subplot(2,3,2),imagesc(origSpec); axis xy; colormap(1-gray);
|
wolffd@0
|
58 title('Spectrogram');
|
wolffd@0
|
59
|
wolffd@0
|
60 synSpec = 20*log10(abs(specgram(output,512,sr,msfs,msoverlap)));
|
wolffd@0
|
61 subplot(2,3,5),imagesc(synSpec); axis xy; colormap(1-gray);
|
wolffd@0
|
62 xlabel('Frame #');
|
wolffd@0
|
63
|
wolffd@0
|
64 origloc = origSpec(:,frameNumber); origloc=origloc-max(origloc);origmin=min(origloc);
|
wolffd@0
|
65 subplot(2,3,3),plot(origloc),title('Spectrogram'),
|
wolffd@0
|
66 axis([1 length(origloc) origmin 0]);
|
wolffd@0
|
67
|
wolffd@0
|
68 filloc = synSpec(:,frameNumber); filloc=filloc-max(filloc);
|
wolffd@0
|
69 subplot(2,3,6),plot(filloc);ylabel('db');
|
wolffd@0
|
70 axis([1 length(origloc) origmin 0]);
|
wolffd@0
|
71 xlabel('FFT Bin');
|
wolffd@0
|
72
|
wolffd@0
|
73 function spec=lpc_spec(aCoeff)
|
wolffd@0
|
74 gain=0;
|
wolffd@0
|
75 cft=0:(1/255):1;
|
wolffd@0
|
76 for index=1:size(aCoeff,1)
|
wolffd@0
|
77 gain = gain + aCoeff(index)*exp(-i*2*pi*cft).^index;
|
wolffd@0
|
78 end
|
wolffd@0
|
79 gain = abs(1./gain);
|
wolffd@0
|
80 spec = 20*log10(gain(1:128))';
|