305 lines
12 KiB
HTML
305 lines
12 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>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>
|
|
<B> <A ID="tex2html1627"
|
|
HREF="node4.html">Contents</A></B>
|
|
<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>
|
|
<B> <A ID="tex2html1627"
|
|
HREF="node4.html">Contents</A></B>
|
|
<B> <A ID="tex2html1629"
|
|
HREF="node201.html">Index</A></B>
|
|
<!--End of Navigation Panel-->
|
|
<ADDRESS>
|
|
Miller Puckette
|
|
2006-12-30
|
|
</ADDRESS>
|
|
</BODY>
|
|
</HTML>
|