Chapter 6: Speech communications

There was a time when mobile phones (also known as handphones or cellphones, depending the region where you live) were precisely telephones that were mobile. It seems difficult to imagine a time when they did not have impressive graphics facilities or, indeed, any graphics facilities at all. However we probably have GSM to thank for our mobile phones (refer to book for more details). This European standard initiative allowed devices to operate globally and inexpensively, and did more to encourage mass adoption than anything else.

At its heart, GSM contained a speech compression algorithm, and most of those are based on a source filter model:


6.2.1.1 The LPC filter

Here are an example set of LPC coefficients that are useful for testing;

a=[1;-1.6187;2.3179;-2.9555;2.8862;-2.5331; 2.2299; -1.3271;0.9886; -0.6126;0.2354];

We can use this in varios ways;

subplot(3,1,1)
plot(abs(freqz(1,a)))
subplot(3,1,2)
plot(abs(freqz(a)))
subplot(3,1,3)
lpcsp(a, lpc_lsp(a))

Where lpcsp.m is a handy piece of MATLAB code that I've used to plot LSP lines overlaid on an LPC spectrum, as follows;

function lpcsp(a, lsp)
[HH, FF]=freqz(1, a, 100);
semilogy(abs(HH),'m-');
hold on 
V=axis;
axis([1,length(FF),V(3),V(4)]);
hold on;
lsc=100/pi;
for lp=1:length(lsp)
   line([1+lsp(lp)*lsc,1+lsp(lp)*lsc], [V(3),V(4)]);
end
hold off;

This plots the following;

Note that an enhanced version, that takes a frequency response argument, is available in the listings section.


6.2.1.4 Pre- and de-emphasis of the speech signal

As discussed in the book, these filters are created and applied as follows;

% Create emphasis/de-emphasis filter coeffs
h=[1, -0.9375];
% Apply the emphasis filter
es=filter(h, 1, s);
% Apply the de-emphasis filter
ds=filter(1, h, es);

6.2.4 Plotting tube models

The listing in Box 6.3 uses VT area data from the Storey paper, and makes use of some functions from the excellent VOICEBOX package.

Assuming that VOICEBOX has been downloaded and installed correctly in MATLAB's path (following instructions on their website), then we need to extract VT area data from Storey. To save typing everything in manually, here are some examples extracted from Brad Storey's results;

phoneme1=[0.3300; 0.3000; 0.3600; 0.3400; 0.6800; 0.5000; 2.4300; 3.1500; 2.6600; 
2.4900; 3.3900; 3.8000; 3.7800; 4.3500; 4.5000; 4.4300; 4.6800; 4.5200; 4.1500; 
4.0900; 3.5100; 2.9500; 2.0300; 1.6600; 1.3800; 1.0500; 0.6000; 0.3500; 0.3200; 
0.1200; 0.1000; 0.1600; 0.2500; 0.2400; 0.3800; 0.2800; 0.3600; 0.6500; 1.5800; 
2.0500; 2.0100; 1.5800];

phoneme2=[0.2000; 0.1700; 0.1800; 0.1800; 0.1000; 1.0800; 1.6600; 1.6400; 1.1900; 
0.9200; 1.1300; 2.4800; 2.7600; 2.9700; 3.4300; 3.3200; 3.4800; 3.9600; 3.7900; 
3.8800; 3.4700; 2.9800; 2.6200; 2.3700; 1.9900; 1.9000; 1.7000; 1.4400; 1.4500; 
1.0600; 0.8700; 0.7500; 1.0600; 1.2900; 1.7800; 1.8300; 1.7000; 1.9700; 1.9200; 
1.6200; 1.3600; 1.1800];

phoneme3=[0.2100; 0.1300; 0.1600; 0.1400; 0.0600; 0.7800; 1.2500; 1.2400; 0.9900; 
0.7200; 0.7300; 1.0600; 1.7700; 1.9700; 2.4600; 2.7000; 2.9200; 3.0300; 2.8400; 
2.8400; 2.8300; 2.3600; 2.1400; 2.0000; 1.7800; 1.8100; 1.7900; 1.5000; 1.3700; 
1.3600; 1.4300; 1.8300; 2.0800; 2.5900; 2.5400; 2.1100; 2.3400; 2.7400; 2.1900; 
1.6000];

We then quote the following code to plot one tube model and its corresponding spectral response;

%Select which phoneme to plot
ph=phoneme1';
L=length(ph);
Sect=0.396825; %in cm
A=[0,ph,100];
rf=lpcaa2rf(A);    %gives reflection 
lpcs=lpcrf2ar(rf); %gives LPC coeffs 
ph=ph/pi;          %convert from area to dia
subplot(2,1,1)     %plot tube shape 
oldyu=+1;
oldyl=-1;
for ll=1:L
    startx=(ll-1)*Sect;
    endx=(ll)*Sect;
    startyu=0.5*ph(ll);
    startyl=-0.5*ph(ll); 
    line([startx,startx],[oldyu,startyu],'linewidth',2) 
    line([startx,endx],[startyu,startyu],'linewidth',2) 
    line([startx,startx],[oldyl,startyl],'linewidth',2) 
    line([startx,endx],[startyl,startyl],'linewidth',2) 
    oldyu=startyu;
    oldyl=startyl; 
end
axis tight
%Plot the spectral response
subplot(2,1,2)
Fn=4000; 
xf=freqz(1,lpcs(1:9),100,Fn*2); 
plot([1:100]*Fn/100,log10(abs(xf)));