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>
 |