File: part13.html

package info (click to toggle)
nyquist 3.12%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 58,036 kB
  • sloc: ansic: 74,355; lisp: 20,485; java: 9,390; cpp: 6,695; sh: 207; xml: 58; makefile: 39
file content (162 lines) | stat: -rw-r--r-- 9,755 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<html><head><title>Linear Prediction Analysis and Synthesis</title>
<link rel="stylesheet" type="text/css" href="nyquiststyle.css">
</head>
<body bgcolor="ffffff">
<a href = "part12.html">Previous Section</a> | <a href = "part14.html">Next Section</a> | <a href = "title.html#toc">Table of Contents</a> | <a href = "indx.html">Index</a> | <a href = "title.html">Title Page</a>
<hr>
<a name = "147"><h2>Linear Prediction Analysis and Synthesis</h2></a>
<a name="index1068"></a><a name="index1069"></a>
Nyquist provides functions to perform Linear Prediction Coding (LPC) 
analysis and synthesis. In simple terms, LPC analysis assumes that a
sound is the result of an all-pole filter applied to a source with a 
flat spectrum. LPC is good for characterizing the general spectral 
shape of a signal, which may be time-varying as in speech sounds.
For synthesis, any source can be filtered, allowing the general 
spectral shape of one signal (used in analysis) to be applied to
any source (used in synthesis). A popular effect is to give vowel-like
spectra to musical tones, creating an artificial (or sometimes natural)
singing voice.
<p>
Examples of LPC analysis and synthesis can be found in the file 
<code>demos/lpc_tutorial.htm</code><a name="index1070"></a><a name="index1071"></a><a name="index1072"></a>,
which is part of the standard Nyquist release.
<p>
As with FFT processing, LPC analysis takes a sound as input and returns 
a stream of frames. Frames are returned from an object using the <code>:next</code>
selector just as with FFT frames. An LPC frame is a list consisting of:
<i>RMS1</i>, the energy of the input signal, <i>RMS2</i>, the energy of the
residual signal, <i>ERR</i>, the square root of <i>RMS1</i>/<i>RMS2</i>, and 
<i>FILTER-COEFS</i>, an array of filter coefficients. To make code more
readable and to avoid code dependence on the exact format of a frame, 
the functions <code>lpc-frame-rms1</code><a name="index1073"></a>, 
<code>lpc-frame-rms2</code><a name="index1074"></a>, 
<code>lpc-frame-err</code><a name="index1075"></a>, and
<code>lpc-frame-filter-coefs</code><a name="index1076"></a> can be
applied to a frame to obtain the respective fields.
<p>
The <i>z</i> transform
of the filter is <i>H</i>(<i>z</i>) = 1/<i>A</i>(<i>z</i>), where <i>A</i>(<i>z</i>) is a
polynomial of the form <i>A</i>(<i>z</i>) = 1 + <i>a<sub>1</sub></i><i>z</i> + 
<i>a<sub>2</sub></i><i>z</i> + ... + <i>a<sub>p</sub></i><i>z</i>. The <i>FILTER-COEFS</i> array has
the form <code>#(</code><i>a<sub>p</sub></i> <i>a<sub>p-1</sub></i> ... <i>a<sub>3</sub></i> 
<i>a<sub>2</sub></i> <i>a<sub>1</sub></i><code>)</code>.
<p>
The file <code>lpc.lsp</code> defines some useful classes and functions. The file
is <i>not</i> automatically loaded with Nyquist, so you must execute 
<code>(load "lpc")</code> before using them.
<p>
<a name = "148"><h3>LPC Classes and Functions</h3></a>
<dl>
<dt>
<code>make-lpanal-iterator(<a name="index1077"></a><i>sound</i>, <i>framedur</i>, <i>skiptime</i>, <i>npoles</i>)</code> [SAL]<br>

<code>(make-lpanal-iterator <i>sound</i> <i>framedur</i> <i>skiptime</i> <i>npoles</i>)</code> [LISP]<dd>Makes an iterator
object, an instance of <code>lpanal-class</code>, 
that returns LPC frames from successive frames of samples in
<i>sound</i>. The duration (in seconds)
of each frame is given by <i>framedur</i>, a 
<code>FLONUM</code>. The skip size (in seconds) between successive frames
is given by <i>skiptime</i>, a <code>FLONUM</code>. Typical values for
<i>framedur</i> and <i>skiptime</i> are 0.08 and 0.04, giving 25 frames
per second and a 50% frame overlap. The number of poles is given
by <i>npoles</i>, a <code>FIXNUM</code>. The result is an object that
responds to the <code>:next</code> selector by returning a frame as 
described above. <code>NIL</code> is returned when <i>sound</i> terminates.
(Note that one or more of the last analysis windows may be 
padded with zeros. <code>NIL</code> is only returned when the corresponding
window would begin after the termination time of the sound.)<br><br>
<dt><code>make-lpc-file-iterator(<a name="index1078"></a><i>filename</i>)</code> [SAL]<br>

<code>(make-lpc-file-iterator <i>filename</i>)</code> [LISP]<dd>Another way to get LPC frames is to read them from a
 file. This function opens an ASCII file containing LPC frames and
 creates an iterator object, an instance of class <code>lpc-file-class</code>
 to access them. Create a file using <code>save-lpc-file</code> (see below).<br><br>
<dt><code>save-lpc-file(<a name="index1079"></a><i>lpc-iterator</i>, <i>filename</i>)</code> [SAL]<br>

<code>(save-lpc-file <i>lpc-iterator</i> <i>filename</i>)</code> [LISP]<dd>Create a file containing LPC frames.
This file can be read by <code>make-lpc-file-iterator</code> (see above).<br><br>
<dt><code>show-lpc-data(<a name="index1080"></a><i>lpc-iterator</i>,
<i>iniframe</i>, <i>endframe</i> [, <i>poles?</i>])</code> [SAL]<br>

<code>(show-lpc-data <i>lpc-iterator</i> <i>iniframe</i> <i>endframe</i>
 [<i>poles?</i>])</code> [LISP]<dd>Print values of LPC
frames from an LPC iterator object. The object is <i>lpc-iterator</i>,
which is typically an instance of <code>lpanal-class</code> or 
<code>lpc-file-class</code>. Frames are numbered from zero, and only
files starting at <i>iniframe</i> (a <code>FIXNUM</code>) and ending before
<i>endframe</i> (also a <code>FIXNUM</code>) are printed. By default, only
the values for <i>RMS1</i>, <i>RMS2</i>, and <i>ERR</i> are printed, but
if optional parameter <i>poles?</i> is non-<code>NIL</code>, then
the LPC coefficients are also printed.<br><br>
<dt><code>allpoles-from-lpc(<a name="index1081"></a><i>snd</i>, <i>lpc-frame</i>)</code> [SAL]<br>

<code>(allpoles-from-lpc <i>snd</i> <i>lpc-frame</i>)</code> [LISP]<dd>A single LPC frame defines a filter.
Use <code>allpoles-from-lpc</code> to apply this filter to <i>snd</i>,
a <code>SOUND</code>. To obtain <i>lpc-frame</i>, a <code>LIST</code>
 containing an LPC frame, either send <code>:next</code> to an
 LPC iterator, or use <code>nth-frame</code> (see below). The result
 is a <code>SOUND</code> whose duration is the same as that of <i>snd</i>.<br><br>
<dt><code>lpreson(<a name="index1082"></a><i>snd</i>, <i>lpc-iterator</i>, 
<i>skiptime</i>)</code> [SAL]<br>

<code>(lpreson <i>snd</i> <i>lpc-iterator</i> <i>skiptime</i>)</code> [LISP]<dd>Implements a time-varying all-pole filter 
controlled by a sequence of LPC frames from an iterator. The
<code>SOUND</code> to be filtered is <i>snd</i>, and the source of
LPC frames is <i>lpc-iterator</i>, typically an instance of 
<code>lpanal-class</code> or <code>lpc-file-class</code>. The frame 
period (in seconds) is given by <i>skiptime</i> (a <code>FLONUM</code>).
This number does not have to agree with the <i>skiptime</i> used
to analyze the frames. (Greater values will cause the filter
evolution slow down, and smaller values will cause it to
speed up.) The result is a <code>SOUND</code>. The duration of the
result is the minimum of the duration of <i>snd</i> and that of
the sequence of frames. <br><br>
<dt><code>lpc-frame-rms1(<a name="index1083"></a><i>frame</i>)</code> [SAL]<br>

<code>(lpc-frame-rms1 <i>frame</i>)</code> [LISP]<dd>Get the energy of the input signal from a frame.<br><br>
<dt><code>lpc-frame-rms2(<a name="index1084"></a><i>frame</i>)</code> [SAL]<br>

<code>(lpc-frame-rms2 <i>frame</i>)</code> [LISP]<dd>Get the energy of the residual from a frame.<br><br>
<dt><code>lpc-frame-err(<a name="index1085"></a><i>frame</i>)</code> [SAL]<br>

<code>(lpc-frame-err <i>frame</i>)</code> [LISP]<dd>Get the square root of <i>RMS1</i>/<i>RMS2</i> from a frame.<br><br>
<dt><code>lpc-frame-filter-coefs(<a name="index1086"></a><i>frame</i>)</code> [SAL]<br>

<code>(lpc-frame-filter-coefs <i>frame</i>)</code> [LISP]<dd>Get the filter coefficients from a frame.
</dl>
<p>

<a name = "149"><h3>Low-level LPC Functions</h3></a>
The lowest-level Nyquist functions for LPC are 
<ul>
<li>
<code>snd-lpanal</code> for analysis,
<li><code>snd-allpoles</code>, an all-pole filter with fixed coefficients, and
<li><code>snd-lpreson</code>, an all-pole filter that takes frames from an LPC iterator.
</ul>
<p>
<dl>
<dt>
<code>snd-lpanal(<a name="index1087"></a><i>samps</i>, <i>npoles</i>)</code> [SAL]<br>

<code>(snd-lpanal <i>samps</i> <i>npoles</i>)</code> [LISP]<dd>Compute
an LPC frame with <i>npoles</i> (a <code>FIXNUM</code>) poles from an 
<code>ARRAY</code> of samples (<code>FLONUMS</code>). Note that <code>snd-fetch-array</code>
can be used to fetch a sequence of frames from a sound. Ordinarily, you
should not use this function. Use <code>make-lpanal-iterator</code> instead.<br><br>
<dt><code>snd-allpoles(<a name="index1088"></a><i>snd</i>, <i>lpc-coefs</i>, <i>gain</i>)</code> [SAL]<br>

<code>(snd-allpoles <i>snd</i> <i>lpc-coefs</i> <i>gain</i>)</code> [LISP]<dd>A fixed all-pole filter. The input is
<i>snd</i>, a <code>SOUND</code>. The filter coefficients are given by <i>lpc-coefs</i>
(an <code>ARRAY</code>), and the filter gain is given by <i>gain</i>, a <code>FLONUM</code>.
The result is a <code>SOUND</code> whose duration matches that of <i>snd</i>. 
Ordinarily, you should use <code>allpoles-from-lpc</code> instead (see above).<br><br>
<dt><code>snd-lpreson(<a name="index1089"></a><i>snd</i>, <i>lpc-iterator</i>, 
<i>skiptime</i>)</code> [SAL]<br>

<code>(snd-lpreson <i>snd</i> <i>lpc-iterator</i> <i>skiptime</i>)</code> [LISP]<dd>This function is identical to <code>lpreson</code> (see above).
</dl>
<p>
<hr>
<a href = "part12.html">Previous Section</a> | <a href = "part14.html">Next Section</a> | <a href = "title.html#toc">Table of Contents</a> | <a href = "indx.html">Index</a> | <a href = "title.html">Title Page</a>
</body></html>