miller-book/node26.html

421 lines
14 KiB
HTML

<!DOCTYPE html>
<!--Converted with LaTeX2HTML 2002-2-1 (1.71)
original version by: Nikos Drakos, CBLU, University of Leeds
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<TITLE>Wavetables and samplers</TITLE>
<META NAME="description" CONTENT="Wavetables and samplers">
<META NAME="keywords" CONTENT="book">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<LINK REL="STYLESHEET" HREF="book.css">
<LINK REL="next" HREF="node40.html">
<LINK REL="previous" HREF="node7.html">
<LINK REL="up" HREF="book.html">
<LINK REL="next" HREF="node27.html">
</HEAD>
<BODY >
<!--Navigation Panel-->
<A NAME="tex2html919"
HREF="node27.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
SRC="next.png"></A>
<A NAME="tex2html913"
HREF="book.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
SRC="up.png"></A>
<A NAME="tex2html907"
HREF="node25.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
SRC="prev.png"></A>
<A NAME="tex2html915"
HREF="node4.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
SRC="contents.png"></A>
<A NAME="tex2html917"
HREF="node201.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html920"
HREF="node27.html">The Wavetable Oscillator</A>
<B> Up:</B> <A NAME="tex2html914"
HREF="book.html">book</A>
<B> Previous:</B> <A NAME="tex2html908"
HREF="node25.html">Exercises</A>
&nbsp; <B> <A NAME="tex2html916"
HREF="node4.html">Contents</A></B>
&nbsp; <B> <A NAME="tex2html918"
HREF="node201.html">Index</A></B>
<BR>
<BR>
<!--End of Navigation Panel-->
<H1><A NAME="SECTION00600000000000000000"></A>
<A NAME="chapter-wavetable"></A>
<BR>
Wavetables and samplers
</H1>
<P>
In Chapter 1 we treated audio signals as if they always flowed by in
a continuous stream at some sample rate. The sample rate isn't really a
quality of the audio signal, but rather it specifies how fast the individual
samples should flow into or out of the computer. But audio signals are at
bottom just sequences of numbers, and in practice there is no requirement that
they be ``played" sequentially. Another, complementary view is that
they can be stored in memory, and, later, they can be read back in any
order--forward, backward, back and forth, or totally at random. An
inexhaustible range of new possibilities opens up.
<P>
For many years (roughly 1950-1990), magnetic tape served as the main storage
medium for sounds. Tapes were passed back and forth across magnetic pickups to
play the signals back in real time. Since 1995 or so, the predominant way
of storing sounds has been to keep them as digital audio signals, which are read
back with much greater freedom and facility than were the magnetic tapes. Many
modes of use dating from the tape era are still current, including cutting,
duplication, speed change, and time reversal. Other techniques, such as
<I>waveshaping</I>, have come into their own only in the digital era.
<P>
Suppose we have a stored digital audio signal, which is just a sequence of
samples (i.e., numbers) <IMG
WIDTH="31" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img80.png"
ALT="$x[n]$"> for <!-- MATH
$n = 0, ..., N-1$
-->
<IMG
WIDTH="111" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
SRC="img166.png"
ALT="$n = 0, ..., N-1$">, where <IMG
WIDTH="18" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
SRC="img3.png"
ALT="$N$"> is the length
of the sequence. Then if we have an input signal <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$"> (which we can imagine
to be flowing in real time), we can use its values as indices to look up values
of the stored signal <IMG
WIDTH="31" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img80.png"
ALT="$x[n]$">. This operation, called
<A NAME="2151"></A><I>wavetable lookup</I>,
gives us a new signal, <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img167.png"
ALT="$z[n]$">, calculated as:
<BR><P></P>
<DIV ALIGN="CENTER">
<!-- MATH
\begin{displaymath}
z[n] = x[y[n]]
\end{displaymath}
-->
<IMG
WIDTH="91" HEIGHT="28" BORDER="0"
SRC="img168.png"
ALT="\begin{displaymath}
z[n] = x[y[n]]
\end{displaymath}">
</DIV>
<BR CLEAR="ALL">
<P></P>
Schematically we represent this operation as shown in Figure <A HREF="#fig02.01">2.1</A>.
<P>
<DIV ALIGN="CENTER"><A NAME="fig02.01"></A><A NAME="2156"></A>
<TABLE>
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 2.1:</STRONG>
Diagram for wavetable lookup. The input is in samples,
ranging approximately from 0 to the wavetable's size <IMG
WIDTH="18" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
SRC="img3.png"
ALT="$N$">, depending on the
interpolation scheme.</CAPTION>
<TR><TD><IMG
WIDTH="110" HEIGHT="175" BORDER="0"
SRC="img169.png"
ALT="\begin{figure}\psfig{file=figs/fig02.01.ps}\end{figure}"></TD></TR>
</TABLE>
</DIV>
<P>
Two complications arise. First, the input values, <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">, might lie outside
the range <IMG
WIDTH="80" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
SRC="img170.png"
ALT="$0, ..., N-1$">, in which case the wavetable <IMG
WIDTH="31" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img80.png"
ALT="$x[n]$"> has no value and
the expression for the output <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img167.png"
ALT="$z[n]$"> is undefined. In this situation we might
choose to
<A NAME="2159"></A><I>clip</I> the input, that is, to substitute 0 for
anything negative and <IMG
WIDTH="45" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
SRC="img171.png"
ALT="$N-1$"> for anything N or greater. Alternatively, we might
prefer to wrap the input around end to end. Here we'll adopt the convention that
out-of-range samples are always clipped; when we need wraparound, we'll
introduce another signal processing operation to do it for us.
<P>
The second complication is that the input values need not be integers; in other
words they might fall between the points of the wavetable. In general, this
is addressed by choosing some scheme for interpolating between the points of
the wavetable. For the moment, though, we'll just round
down to the nearest integer below the input. This is called
<A NAME="2161"></A><I>non-interpolating</I> wavetable lookup, and its full definition is:
<BR><P></P>
<DIV ALIGN="CENTER">
<!-- MATH
\begin{displaymath}
z[n] = \left \{ {
\begin{array}{ll}
x[ \lfloor y[n] \rfloor ] & \mbox{if $0 \le y[n] < N-1$} \\
x[0] & \mbox{if $y[n] < 0$} \\
x[N-1] & \mbox{if $y[n] \ge N-1$} \\
\end{array}
} \right .
\end{displaymath}
-->
<IMG
WIDTH="279" HEIGHT="64" BORDER="0"
SRC="img172.png"
ALT="\begin{displaymath}
z[n] = \left \{ {
\begin{array}{ll}
x[ \lfloor y[n] \rflo...
...x[N-1] &amp; \mbox{if $y[n] \ge N-1$} \\
\end{array} } \right .
\end{displaymath}">
</DIV>
<BR CLEAR="ALL">
<P></P>
(where <!-- MATH
$\lfloor y[n] \rfloor$
-->
<IMG
WIDTH="44" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img173.png"
ALT="$\lfloor y[n] \rfloor$"> means, ``the greatest integer not
exceeding <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">").
<P>
Pictorally, we use <IMG
WIDTH="28" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img174.png"
ALT="$y[0]$"> (a number) as a
location on the horizontal axis of the wavetable shown in Figure <A HREF="#fig02.01">2.1</A>,
and the output, <IMG
WIDTH="28" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img175.png"
ALT="$z[0]$">, is whatever we get on the vertical axis; and the
same for <IMG
WIDTH="28" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img176.png"
ALT="$y[1]$"> and <IMG
WIDTH="28" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img177.png"
ALT="$z[1]$"> and so on. The ``natural" range for the input <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">
is <!-- MATH
$0 \le y[n] < N$
-->
<IMG
WIDTH="95" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img178.png"
ALT="$0 \le y[n] &lt; N$">. This is different from the usual range of an audio
signal suitable for output from the computer, which ranges from -1 to 1 in
our units. We'll see later that the usable range of input values,
from 0 to <IMG
WIDTH="18" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
SRC="img3.png"
ALT="$N$"> for non-interpolating lookup, shrinks slightly if interpolating lookup is used.
<P>
Figure <A HREF="#fig02.02">2.2</A> (part a) shows a wavetable and the result of using two
different input signals as lookup indices into it. The wavetable
contains 40 points, which are numbered from 0 to 39. In part (b), a
<A NAME="2171"></A><I>sawtooth wave</I> is used as the input signal <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">. A sawtooth wave
is nothing but a ramp function repeated end to end. In this example the
sawtooth's range is from <IMG
WIDTH="11" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
SRC="img179.png"
ALT="$0$"> to
<IMG
WIDTH="19" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
SRC="img180.png"
ALT="$40$"> (this is shown in the vertical axis). The sawtooth wave thus scans
the wavetable from left to right--from the beginning point 0 to the endpoint
39--and does so every time it repeats. Over the fifty points shown
in Figure <A HREF="#fig02.02">2.2</A> (part b) the sawtooth wave makes
two and a half cycles. Its period is twenty samples, or in other
words the frequency (in cycles per second) is <IMG
WIDTH="39" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img181.png"
ALT="$R/20$">.
<P>
<DIV ALIGN="CENTER"><A NAME="fig02.02"></A><A NAME="2176"></A>
<TABLE>
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 2.2:</STRONG>
Wavetable lookup: (a) a wavetable; (b) and (d) signal inputs for
lookup; (c) and (e) the corresponding outputs.</CAPTION>
<TR><TD><IMG
WIDTH="471" HEIGHT="664" BORDER="0"
SRC="img182.png"
ALT="\begin{figure}\psfig{file=figs/fig02.02.ps}\end{figure}"></TD></TR>
</TABLE>
</DIV>
<P>
Part (c) of Figure <A HREF="#fig02.02">2.2</A> shows the result of applying wavetable
lookup, using the table <IMG
WIDTH="31" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img80.png"
ALT="$x[n]$">, to the signal <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">. Since the sawtooth input
simply reads out the contents of the wavetable from left to right, repeatedly,
at a constant rate of precession, the result will be a new periodic signal,
whose waveform (shape) is derived from <IMG
WIDTH="31" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img80.png"
ALT="$x[n]$"> and whose frequency is determined
by the sawtooth wave <IMG
WIDTH="30" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
SRC="img2.png"
ALT="$y[n]$">.
<P>
Parts (d) and (e) show an example where the wavetable is read in a nonuniform
way; since the input signal rises from <IMG
WIDTH="11" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
SRC="img179.png"
ALT="$0$"> to <IMG
WIDTH="18" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
SRC="img3.png"
ALT="$N$"> and then later recedes to
<IMG
WIDTH="11" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
SRC="img179.png"
ALT="$0$">, we see the wavetable appear first forward, then frozen at its endpoint,
then backward. The table is scanned from left to right and then, more quickly,
from right to left. As in the previous example the incoming signal controls
the speed of precession while the output's amplitudes are those of the wavetable.
<P>
<BR><HR>
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>
<UL>
<LI><A NAME="tex2html921"
HREF="node27.html">The Wavetable Oscillator</A>
<LI><A NAME="tex2html922"
HREF="node28.html">Sampling</A>
<LI><A NAME="tex2html923"
HREF="node29.html">Enveloping samplers</A>
<LI><A NAME="tex2html924"
HREF="node30.html">Timbre stretching</A>
<LI><A NAME="tex2html925"
HREF="node31.html">Interpolation</A>
<LI><A NAME="tex2html926"
HREF="node32.html">Examples</A>
<UL>
<LI><A NAME="tex2html927"
HREF="node33.html">Wavetable oscillator</A>
<LI><A NAME="tex2html928"
HREF="node34.html">Wavetable lookup in general</A>
<LI><A NAME="tex2html929"
HREF="node35.html">Using a wavetable as a sampler</A>
<LI><A NAME="tex2html930"
HREF="node36.html">Looping samplers</A>
<LI><A NAME="tex2html931"
HREF="node37.html">Overlapping sample looper</A>
<LI><A NAME="tex2html932"
HREF="node38.html">Automatic read point precession</A>
</UL>
<BR>
<LI><A NAME="tex2html933"
HREF="node39.html">Exercises</A>
</UL>
<!--End of Table of Child-Links-->
<HR>
<!--Navigation Panel-->
<A NAME="tex2html919"
HREF="node27.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
SRC="next.png"></A>
<A NAME="tex2html913"
HREF="book.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
SRC="up.png"></A>
<A NAME="tex2html907"
HREF="node25.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
SRC="prev.png"></A>
<A NAME="tex2html915"
HREF="node4.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
SRC="contents.png"></A>
<A NAME="tex2html917"
HREF="node201.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html920"
HREF="node27.html">The Wavetable Oscillator</A>
<B> Up:</B> <A NAME="tex2html914"
HREF="book.html">book</A>
<B> Previous:</B> <A NAME="tex2html908"
HREF="node25.html">Exercises</A>
&nbsp; <B> <A NAME="tex2html916"
HREF="node4.html">Contents</A></B>
&nbsp; <B> <A NAME="tex2html918"
HREF="node201.html">Index</A></B>
<!--End of Navigation Panel-->
<ADDRESS>
Miller Puckette
2006-12-30
</ADDRESS>
</BODY>
</HTML>