268 lines
11 KiB
HTML
268 lines
11 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||
|
|
||
|
<!--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>
|
||
|
<TITLE>The PAF generator</TITLE>
|
||
|
<META NAME="description" CONTENT="The PAF generator">
|
||
|
<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="node102.html">
|
||
|
<LINK REL="previous" HREF="node100.html">
|
||
|
<LINK REL="up" HREF="node97.html">
|
||
|
<LINK REL="next" HREF="node102.html">
|
||
|
</HEAD>
|
||
|
|
||
|
<BODY >
|
||
|
<!--Navigation Panel-->
|
||
|
<A NAME="tex2html2056"
|
||
|
HREF="node102.html">
|
||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/next.png"></A>
|
||
|
<A NAME="tex2html2050"
|
||
|
HREF="node97.html">
|
||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/up.png"></A>
|
||
|
<A NAME="tex2html2044"
|
||
|
HREF="node100.html">
|
||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/prev.png"></A>
|
||
|
<A NAME="tex2html2052"
|
||
|
HREF="node4.html">
|
||
|
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/contents.png"></A>
|
||
|
<A NAME="tex2html2054"
|
||
|
HREF="node201.html">
|
||
|
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/index.png"></A>
|
||
|
<BR>
|
||
|
<B> Next:</B> <A NAME="tex2html2057"
|
||
|
HREF="node102.html">Stretched wavetables</A>
|
||
|
<B> Up:</B> <A NAME="tex2html2051"
|
||
|
HREF="node97.html">Examples</A>
|
||
|
<B> Previous:</B> <A NAME="tex2html2045"
|
||
|
HREF="node100.html">Two-cosine carrier signal</A>
|
||
|
<B> <A NAME="tex2html2053"
|
||
|
HREF="node4.html">Contents</A></B>
|
||
|
<B> <A NAME="tex2html2055"
|
||
|
HREF="node201.html">Index</A></B>
|
||
|
<BR>
|
||
|
<BR>
|
||
|
<!--End of Navigation Panel-->
|
||
|
|
||
|
<H2><A NAME="SECTION001054000000000000000">
|
||
|
The PAF generator</A>
|
||
|
</H2>
|
||
|
|
||
|
<P>
|
||
|
|
||
|
<DIV ALIGN="CENTER"><A NAME="fig06.17"></A><A NAME="7005"></A>
|
||
|
<TABLE>
|
||
|
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 6.18:</STRONG>
|
||
|
The phase-aligned formant (PAF) synthesis algorithm.</CAPTION>
|
||
|
<TR><TD><IMG
|
||
|
WIDTH="482" HEIGHT="525" BORDER="0"
|
||
|
SRC="img621.png"
|
||
|
ALT="\begin{figure}\psfig{file=figs/fig06.17.ps}\end{figure}"></TD></TR>
|
||
|
</TABLE>
|
||
|
</DIV>
|
||
|
|
||
|
<P>
|
||
|
Example F12.paf.pd (Figure <A HREF="#fig06.17">6.18</A>) is a realization of the PAF generator,
|
||
|
described in Section <A HREF="node96.html#sect6.paf">6.4</A>.
|
||
|
The control inputs specify the fundamental frequency, the center frequency, and
|
||
|
the bandwidth, all in ``MIDI" units. The first steps taken in the realization
|
||
|
are to divide center frequency by fundamental (to get the center frequency quotient)
|
||
|
and bandwidth by fundamental to get the index of modulation for the
|
||
|
waveshaper. The center frequency quotient is sampled-and-held so that it is
|
||
|
only updated at periods of the fundamental.
|
||
|
|
||
|
<P>
|
||
|
The one oscillator (the <TT>phasor~</TT> object) runs at the fundamental
|
||
|
frequency. This is used both to control a <TT>samphold~</TT> object which
|
||
|
synchronizes updates to the center frequency quotient (labeled ``C.F. relative
|
||
|
to fundamental" in the figure), and to compute phases for both <TT>cos~</TT> objects which operate as shown earlier in Figure <A HREF="node100.html#fig06.16">6.17</A>.
|
||
|
|
||
|
<P>
|
||
|
The waveshaping portion of the patch uses a half period of a sinusoid
|
||
|
as a lookup function (to compensate for the frequency doubling because
|
||
|
of the symmetry of the lookup function). To get a half-cycle of the sine function
|
||
|
we multiply the phase by 0.5 and subtract 0.25, so that the adjusted phase
|
||
|
runs from -0.25 to +0.25, once each period. This scans the positive half
|
||
|
of the cycle defined by the <TT>cos~</TT> object.
|
||
|
|
||
|
<P>
|
||
|
The amplitude of the half-sinusoid is then adjusted by an index of modulation
|
||
|
(which is just the bandwidth quotient <!-- MATH
|
||
|
${\omega_b}/\omega$
|
||
|
-->
|
||
|
<IMG
|
||
|
WIDTH="38" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
|
||
|
SRC="img588.png"
|
||
|
ALT="${\omega_b}/\omega$">). The table
|
||
|
(``bell-curve") holds an unnormalized Gaussian curve sampled
|
||
|
from -4 to 4 over 200 points (25 points per unit), so the center of the table,
|
||
|
at point 100, corresponds to the central peak of the bell curve. Outside the
|
||
|
interval from -4 to 4 the Gaussian curve is negligibly small.
|
||
|
|
||
|
<P>
|
||
|
Figure <A HREF="#fig06.18">6.19</A> shows how the Gaussian wavetable is prepared. One new
|
||
|
control object is needed:
|
||
|
|
||
|
<P>
|
||
|
|
||
|
<DIV ALIGN="CENTER"><A NAME="fig06.18"></A><A NAME="7047"></A>
|
||
|
<TABLE>
|
||
|
<CAPTION ALIGN="BOTTOM"><STRONG>Figure 6.19:</STRONG>
|
||
|
Filling in the wavetable for Figure <A HREF="#fig06.17">6.18</A>.</CAPTION>
|
||
|
<TR><TD><IMG
|
||
|
WIDTH="476" HEIGHT="240" BORDER="0"
|
||
|
SRC="img622.png"
|
||
|
ALT="\begin{figure}\psfig{file=figs/fig06.18.ps}\end{figure}"></TD></TR>
|
||
|
</TABLE>
|
||
|
</DIV>
|
||
|
|
||
|
<P>
|
||
|
<BR><!-- MATH
|
||
|
$\fbox{ $\mathrm{until}$\ }$
|
||
|
-->
|
||
|
<IMG
|
||
|
WIDTH="57" HEIGHT="41" ALIGN="MIDDLE" BORDER="0"
|
||
|
SRC="img623.png"
|
||
|
ALT="\fbox{ $\mathrm{until}$\ }"> :
|
||
|
<A NAME="7054"></A>When the left, ``start" inlet is banged, output sequential bangs (with no
|
||
|
elapsed time between them) iteratively, until the right, ``stop" inlet is
|
||
|
banged. The stopping ``bang" message must originate somehow from the
|
||
|
<TT>until</TT> object's outlet; otherwise, the outlet will send ``bang" messages
|
||
|
forever, freezing out any other object which could break the loop.
|
||
|
|
||
|
<P>
|
||
|
As used here, a loop driven by an <TT>until</TT> object
|
||
|
counts from 0 to 199, inclusive. The loop count is maintained by the
|
||
|
``<TT>f</TT>" and ``<TT>+ 1</TT>" objects, each of which feeds the other. But
|
||
|
since the ``<TT>+ 1</TT>" object's output goes to the right inlet of the
|
||
|
``<TT>f</TT>", its result (one greater) will only emerge from the
|
||
|
``<TT>f</TT>" the next time it is banged by ``<TT>until</TT>". So each bang
|
||
|
from ``<TT>until</TT>" increments the value by one.
|
||
|
|
||
|
<P>
|
||
|
The order in which the loop is started matters: the upper ``<TT>t b b</TT>"
|
||
|
object (short for ``trigger bang bang") must first send zero to the
|
||
|
``<TT>f</TT>", thus initializing it, and then set the <TT>until</TT> object sending
|
||
|
bangs, incrementing the value, until stopped. To stop it when the value
|
||
|
reaches 199, a <TT>select</TT> object checks the value and, when it sees the
|
||
|
match, bangs the ``stop" inlet of the <TT>until</TT> object.
|
||
|
|
||
|
<P>
|
||
|
Meanwhile, for every number from 0 to 199 that comes out of the ``<TT>f</TT>"
|
||
|
object, we create an ordered pair of messages to the <TT>tabwrite</TT> object.
|
||
|
First, at right, goes the index itself, from 0 to 199. Then for the left inlet,
|
||
|
the first <TT>expr</TT> object adjusts the index to range from -4 to 4 (it
|
||
|
previously ranged from 0 to 199) and the second one evaluates the
|
||
|
Gaussian function.
|
||
|
|
||
|
<P>
|
||
|
In this patch we have not fully addressed the issue of updating the
|
||
|
center frequency quotient at the appropriate times. Whenever the carrier
|
||
|
frequency is changed the sample-and-hold step properly delays the update
|
||
|
of the quotient. But if, instead or in addition, the fundamental itself
|
||
|
changes abruptly, then for a fraction of a period the <TT>phasor~</TT> object's frequency and the quotient are out of sync. Pd does not allow
|
||
|
the <TT>samphold~</TT> output to be connected back into the <TT>phasor~</TT> input without the inclusion of an explicit delay (see the next chapter) and
|
||
|
there is no simple way to modify the patch to solve this problem.
|
||
|
|
||
|
<P>
|
||
|
Assuming that we <I>did</I> somehow clock the <TT>phasor~</TT> object's input
|
||
|
synchronously with its own wraparound points, we would then have to do the
|
||
|
same for the bandwidth/fundamental quotient on the right side of the patch
|
||
|
as well. In the current scenario, however, there is no problem updating
|
||
|
that value continuously.
|
||
|
|
||
|
<P>
|
||
|
A practical solution to this updating problem could be simply to rewrite the
|
||
|
entire patch in C as a Pd class; this also turns out to use much less CPU time
|
||
|
than the pictured patch, and is the more practical solution overall--as long
|
||
|
as you don't want to experiment with making embellishments or other changes to
|
||
|
the algorithm. Such embellishments might include: adding an inharmonic upward
|
||
|
or downward shift in the partials; allowing to switch between smooth and
|
||
|
sampled-and-held center frequency updates; adding separate gain controls for
|
||
|
even and odd partials; introducing gravel by irregularly modulating the phase;
|
||
|
allowing mixtures of two or more waveshaping functions; or making sharper
|
||
|
percussive attacks by aligning the phase of the oscillator with the timing of
|
||
|
an amplitude envelope generator.
|
||
|
|
||
|
<P>
|
||
|
One final detail about amplitude is in order: since the amplitude of the
|
||
|
strongest partial decreases roughly as <IMG
|
||
|
WIDTH="66" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
|
||
|
SRC="img572.png"
|
||
|
ALT="$1/(1+b)$"> where <IMG
|
||
|
WIDTH="10" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
|
||
|
SRC="img21.png"
|
||
|
ALT="$b$"> is the index of
|
||
|
modulation, it is sometimes (but not always) desirable to correct the amplitude
|
||
|
of the output by multiplying by <IMG
|
||
|
WIDTH="37" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
|
||
|
SRC="img606.png"
|
||
|
ALT="$1+b$">. This is only an option if <IMG
|
||
|
WIDTH="10" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
|
||
|
SRC="img21.png"
|
||
|
ALT="$b$"> is
|
||
|
smoothly updated (as in this example), not if it is sampled-and-held.
|
||
|
One situation in which this is appropriate is in simulating plucked strings (by
|
||
|
setting center frequency to the fundamental, starting with a high index of
|
||
|
modulation and dropping it exponentially); it would be appropriate to hear
|
||
|
the fundamental dropping, not rising, in amplitude as the string decays.
|
||
|
|
||
|
<P>
|
||
|
<HR>
|
||
|
<!--Navigation Panel-->
|
||
|
<A NAME="tex2html2056"
|
||
|
HREF="node102.html">
|
||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/next.png"></A>
|
||
|
<A NAME="tex2html2050"
|
||
|
HREF="node97.html">
|
||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/up.png"></A>
|
||
|
<A NAME="tex2html2044"
|
||
|
HREF="node100.html">
|
||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/prev.png"></A>
|
||
|
<A NAME="tex2html2052"
|
||
|
HREF="node4.html">
|
||
|
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/contents.png"></A>
|
||
|
<A NAME="tex2html2054"
|
||
|
HREF="node201.html">
|
||
|
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
|
||
|
SRC="file:/usr/local/share/lib/latex2html/icons/index.png"></A>
|
||
|
<BR>
|
||
|
<B> Next:</B> <A NAME="tex2html2057"
|
||
|
HREF="node102.html">Stretched wavetables</A>
|
||
|
<B> Up:</B> <A NAME="tex2html2051"
|
||
|
HREF="node97.html">Examples</A>
|
||
|
<B> Previous:</B> <A NAME="tex2html2045"
|
||
|
HREF="node100.html">Two-cosine carrier signal</A>
|
||
|
<B> <A NAME="tex2html2053"
|
||
|
HREF="node4.html">Contents</A></B>
|
||
|
<B> <A NAME="tex2html2055"
|
||
|
HREF="node201.html">Index</A></B>
|
||
|
<!--End of Navigation Panel-->
|
||
|
<ADDRESS>
|
||
|
Miller Puckette
|
||
|
2006-12-30
|
||
|
</ADDRESS>
|
||
|
</BODY>
|
||
|
</HTML>
|