You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
miller-book/node73.html

304 lines
12 KiB

<!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>Polyphonic synthesis: sampler</TITLE>
<META NAME="description" CONTENT="Polyphonic synthesis: sampler">
<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="previous" HREF="node72.html">
<LINK REL="up" HREF="node68.html">
<LINK REL="next" HREF="node74.html">
</HEAD>
<BODY >
<!--Navigation Panel-->
<A ID="tex2html1630"
HREF="node74.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
SRC="next.png"></A>
<A ID="tex2html1624"
HREF="node68.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
SRC="up.png"></A>
<A ID="tex2html1620"
HREF="node72.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
SRC="prev.png"></A>
<A ID="tex2html1626"
HREF="node4.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
SRC="contents.png"></A>
<A ID="tex2html1628"
HREF="node201.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
SRC="index.png"></A>
<BR>
<B> Next:</B> <A ID="tex2html1631"
HREF="node74.html">Exercises</A>
<B> Up:</B> <A ID="tex2html1625"
HREF="node68.html">Examples</A>
<B> Previous:</B> <A ID="tex2html1621"
HREF="node72.html">Additive synthesis: spectral envelope</A>
&nbsp; <B> <A ID="tex2html1627"
HREF="node4.html">Contents</A></B>
&nbsp; <B> <A ID="tex2html1629"
HREF="node201.html">Index</A></B>
<BR>
<BR>
<!--End of Navigation Panel-->
<H2><A ID="SECTION00885000000000000000">
Polyphonic synthesis: sampler</A>
</H2>
<A ID="4831"></A>
<P>
We move now to an example using dynamic voice allocation as described in
Section <A HREF="node65.html#sect4.voicealloc">4.5</A>. In the additive synthesis examples shown
previously, each voice is used for a fixed purpose. In the
present example, we allocate voices from a bank as needed to play
notes in a control stream.
<P>
Example D11.sampler.poly.pd (Figure <A HREF="#fig04.20">4.20</A>) shows the polyphonic sampler, which
uses the abstraction <TT>sampvoice</TT> (whose interior
is shown in Figure <A HREF="#fig04.21">4.21</A>).
The techniques for altering the pitch and other parameters in a one-shot
sampler are shown in Example D10.sampler.notes.pd (not shown) which in turn is derived from
the original one-shot sampler from the previous chapter (C05.sampler.oneshot.pd, shown
in Figure <A HREF="node53.html#fig03.14">3.14</A>).
<P>
<DIV ALIGN="CENTER"><A ID="fig04.20"></A><A ID="4839"></A>
<TABLE>
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 4.20:</STRONG>
A polyphonic sampler demonstrating voice allocation and use
of tags.</CAPTION>
<TR><TD><IMG
WIDTH="459" HEIGHT="598" BORDER="0"
SRC="img393.png"
ALT="\begin{figure}\psfig{file=figs/fig04.20.ps}\end{figure}"></TD></TR>
</TABLE>
</DIV>
<P>
<DIV ALIGN="CENTER"><A ID="fig04.21"></A><A ID="4895"></A>
<TABLE>
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 4.21:</STRONG>
The <TT>sampvoice</TT> abstraction used in the polyphonic sampler
of Figure <A HREF="#fig04.20">4.20</A>.</CAPTION>
<TR><TD><IMG
WIDTH="562" HEIGHT="630" BORDER="0"
SRC="img394.png"
ALT="\begin{figure}\psfig{file=figs/fig04.21.ps}\end{figure}"></TD></TR>
</TABLE>
</DIV>
<P>
The <TT>sampvoice</TT> objects in Figure <A HREF="#fig04.20">4.20</A> are arranged in a
different kind of summing bus from the ones before; here, each one adds its
own output to the signal on its inlet, and puts the sum on its outlet. At the
bottom of the eight objects, the outlet therefore holds the sum of all eight.
This has the advantage of being more explicit than the <TT>throw~</TT> /
<TT>catch~</TT> busses, and is preferable when visual clutter is not a
problem.
<P>
The main job of the patch, though, is to distribute the "note" messages to
the <TT>sampvoice</TT> objects. To do this we must introduce some new Pd
objects:
<P>
<BR><!-- MATH
$\fbox{ $\mathrm{mod}$}$
-->
<IMG
WIDTH="50" HEIGHT="41" ALIGN="MIDDLE" BORDER="0"
SRC="img395.png"
ALT="\fbox{ $\mathrm{mod}$}">:
<A ID="4910"></A><A ID="4911"></A>Integer modulus. For instance, 17 mod 10 gives 7, and -2 mod 10 gives 8.
There is also an integer division object named <TT>div</TT> ; dividing 17 by
10 via <TT>div</TT> gives 1, and -2 by 10 gives -1.
<P>
<BR><!-- MATH
$\fbox{ $\mathrm{poly}$}$
-->
<IMG
WIDTH="49" HEIGHT="41" ALIGN="MIDDLE" BORDER="0"
SRC="img397.png"
ALT="\fbox{ $\mathrm{poly}$}">:
<A ID="4912"></A>Polyphonic voice allocator. Creation arguments give the number of
voices in the bank and a flag (1 if voice stealing is needed, 0 if not).
The inlets are a numeric tag at left and a flag at right indicating whether
to start or stop a voice with the given tag (nonzero numbers meaning "start"
and zero, "stop"). The outputs are, at left, the voice number, the tag
again at center, and the start/stop flag at right. In MIDI applications, the
tag can be pitch and the start/stop flag can be the note's velocity.
<P>
<BR><!-- MATH
$\fbox{ \texttt{makenote}}$
-->
<IMG
WIDTH="86" HEIGHT="39" ALIGN="MIDDLE" BORDER="0"
SRC="img398.png"
ALT="\fbox{ \texttt{makenote}}">:
<A ID="4913"></A>Supply delayed note-off messages to match note-on messages. The inlets are
a tag and start/stop flag ("pitch" and "velocity" in MIDI usage) and the
desired duration in milliseconds. The tag/flag pair are repeated to
the two outlets as they are received; then, after the delay, the tag is
repeated with flag zero to stop the note after the desired duration.
<P>
The "note" messages contain fields for pitch, amplitude, duration,
sample number, start location in the sample, rise time, and decay time. For
instance, the message,
<PRE>
60 90 1000 2 500 10 20
</PRE>
(if received by the <TT>r note</TT> object)
means to play a note at pitch 60 (MIDI units), amplitude 90 dB, one second
long, from the wavetable named "sample2", starting at a point 500 msec
into the wavetable, with rise and decay times of 10 and 20 msec.
<P>
After unpacking the message into its seven components, the patch
creates a tag for the note. To do this, first the <TT>t b f</TT> object
outputs a bang after the last of the seven parameters appear separately. The
combination of the <TT>+</TT>, <TT>f</TT>, and <TT>mod</TT> objects acts
as a counter that repeats after a million steps, essentially generating
a unique number corresponding to the note.
<P>
The next step is to use the <TT>poly</TT> object to determine which voice to play
which note. The <TT>poly</TT> object expects separate messages to start
and stop tasks (i.e., notes). So the tag and duration are first fed to the
<TT>makenote</TT> object, whose outputs include a flag ("velocity") at
right and the tag again at left. For each tag <TT>makenote</TT> receives, two pairs
of numbers are output, one to start the note, and another, after a delay
equal to the note duration, to stop it.
<P>
Having treated <TT>poly</TT> to this separated input, we now have to strip
the messages corresponding to the ends of notes, since we really only need
combined "note" messages with
duration fields. The <TT>stripnote</TT> object does this job. Finally, the
voice number we have calculated is prepended to the seven parameters we
started with (the <TT>pack</TT> object), so that the output of the
<TT>pack</TT> object looks like this:
<PRE>
4 60 90 1000 2 500 10 20
</PRE>
where the "4" is the voice number output by the <TT>poly</TT> object.
The voice number is used to route the message
to the desired voice using the <TT>route</TT> object. The appropriate
<TT>sampvoice</TT> object then gets the original list starting with
"60".
<P>
Inside the <TT>sampvoice</TT> object (Figure <A HREF="#fig04.21">4.21</A>), the message
is used to control the <TT>tabread4~</TT> and surrounding <TT>line~</TT> and <TT>vline~</TT> objects. The control takes place with a delay of
5 msec as in the earlier sampler example. Here, however, we must
store the seven parameters of the note (earlier there were no
parameters). This is done using the six <TT>f</TT> objects, plus the
right inlet of the rightmost <TT>delay</TT> object. These values are used after
the delay of 5 msec. This is done in tandem with the muting
mechanism described on Page <A HREF="node62.html#sect4.muting"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]"
SRC="crossref.png"></A>, using another
<TT>vline~</TT> object.
<P>
When the 5 msec have elapsed, the <TT>vline~</TT> object in charge of
generating the wavetable index gets its marching orders (and,
simultaneously, the wavetable number is set for the <TT>tabread4~</TT> object and the amplitude envelope generator starts its attack.)
The wavetable index must be set discontinuously to the starting index, then
ramped to an ending index over an appropriate time duration to obtain the
needed transposition. The starting index in samples is just 44.1 times the
starting location in milliseconds, plus one to allow for four-point table
interpolation. This becomes the third number in a packed
list generated by the <TT>pack</TT> object at the center of the voice patch.
<P>
We arbitrarily decide that the ramp will last ten thousand seconds (this is the
"1e+07" appearing in the message box sent to the wavetable index generator),
hoping that this is at least as long as any note we will play. The ending index
is the starting index plus the number of samples to ramp through. At a
transposition factor of one, we should move by 441,000,000 samples during those
10,000,000 milliseconds, or proportionally more or less depending on the
transposition factor. This transposition factor is computed by the <TT>mtof</TT> object, dividing by 261.62 (the frequency corresponding to MIDI note 60) so
that a specified "pitch" of 60 results in a transposition factor of one.
<P>
These and other parameters are combined in one message
via the <TT>pack</TT> object so that the following message boxes can
generate the needed control messages. The only novelty is
the <TT>makefilename</TT> object, which converts numbers such as "2" to
symbols such as "sample2" so that the <TT>tabread4~</TT> object's
wavetable may be set.
<P>
At the bottom of the voice patch we see how a summing bus is implemented inside
a subpatch; an <TT>inlet~</TT> object picks up the sum of all the preceding
voices, the output of the current voice is added in, and the result is
sent on to the next voice via the <TT>outlet~</TT> object.
<P>
<HR>
<!--Navigation Panel-->
<A ID="tex2html1630"
HREF="node74.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
SRC="next.png"></A>
<A ID="tex2html1624"
HREF="node68.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
SRC="up.png"></A>
<A ID="tex2html1620"
HREF="node72.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
SRC="prev.png"></A>
<A ID="tex2html1626"
HREF="node4.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
SRC="contents.png"></A>
<A ID="tex2html1628"
HREF="node201.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
SRC="index.png"></A>
<BR>
<B> Next:</B> <A ID="tex2html1631"
HREF="node74.html">Exercises</A>
<B> Up:</B> <A ID="tex2html1625"
HREF="node68.html">Examples</A>
<B> Previous:</B> <A ID="tex2html1621"
HREF="node72.html">Additive synthesis: spectral envelope</A>
&nbsp; <B> <A ID="tex2html1627"
HREF="node4.html">Contents</A></B>
&nbsp; <B> <A ID="tex2html1629"
HREF="node201.html">Index</A></B>
<!--End of Navigation Panel-->
<ADDRESS>
Miller Puckette
2006-12-30
</ADDRESS>
</BODY>
</HTML>