summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
Diffstat (limited to 'demos')
-rw-r--r--demos/allewis/cell_aut.lsp83
-rw-r--r--demos/allewis/cellularautomata.htm79
-rw-r--r--demos/allewis/cmusic_pres.pptbin0 -> 51200 bytes
-rw-r--r--demos/allewis/rule30.jpgbin0 -> 39403 bytes
-rw-r--r--demos/arp.sal99
-rw-r--r--demos/arpeggiator.htm31
-rw-r--r--demos/bandfx.htm59
-rw-r--r--demos/beginclip.jpgbin0 -> 10372 bytes
-rw-r--r--demos/demo-snd.aiffbin0 -> 8054 bytes
-rw-r--r--demos/demo.midbin0 -> 1601 bytes
-rw-r--r--demos/distortion.htm118
-rw-r--r--demos/examples.lsp424
-rw-r--r--demos/examples.sal518
-rw-r--r--demos/examples_home.htm116
-rw-r--r--demos/fft_demo.lsp176
-rw-r--r--demos/fft_tutorial.htm553
-rw-r--r--demos/largeclip.jpgbin0 -> 27006 bytes
-rw-r--r--demos/lpc-exmpl.dat162
-rw-r--r--demos/lpc_tutorial.htm186
-rw-r--r--demos/lpcdemo.lsp263
-rw-r--r--demos/mateos/bell.lsp33
-rw-r--r--demos/mateos/gong.lsp64
-rw-r--r--demos/mateos/organ.lsp58
-rw-r--r--demos/mateos/tuba.lsp94
-rw-r--r--demos/midi_tutorial.htm2
-rw-r--r--demos/osc-test.lsp90
-rw-r--r--demos/piano.htm2
-rw-r--r--demos/pitch_change.htm83
-rw-r--r--demos/pmorales/a4.lsp25
-rw-r--r--demos/pmorales/a5.lsp20
-rw-r--r--demos/pmorales/a6.lsp33
-rw-r--r--demos/pmorales/b1.lsp60
-rw-r--r--demos/pmorales/b10.lsp63
-rw-r--r--demos/pmorales/b2.lsp45
-rw-r--r--demos/pmorales/b3.lsp40
-rw-r--r--demos/pmorales/b5.lsp19
-rw-r--r--demos/pmorales/b7.lsp40
-rw-r--r--demos/pmorales/b8.lsp51
-rw-r--r--demos/pmorales/b9.lsp42
-rw-r--r--demos/pmorales/buzz.lsp88
-rw-r--r--demos/pmorales/c1.lsp32
-rw-r--r--demos/pmorales/d1.lsp43
-rw-r--r--demos/pmorales/e2.lsp157
-rw-r--r--demos/pmorales/ks.lsp33
-rw-r--r--demos/pmorales/partial.lsp30
-rw-r--r--demos/pmorales/phm.lsp79
-rw-r--r--demos/pmorales/pjmg.lsp40
-rw-r--r--demos/pmorales/readme.txt27
-rw-r--r--demos/probability_distributions.htm137
-rw-r--r--demos/rhythm_tutorial.htm2
-rw-r--r--demos/scratch_tutorial.htm93
-rwxr-xr-xdemos/sdl/ej2.lsp66
-rw-r--r--demos/sdl/inv-08.lsp180
-rw-r--r--demos/sequence_example.htm52
-rw-r--r--demos/shepard.lsp195
-rw-r--r--demos/shepard.ny139
-rw-r--r--demos/softclip.gifbin0 -> 16618 bytes
-rw-r--r--demos/softclip.jpgbin0 -> 11172 bytes
-rw-r--r--demos/stktest.lsp407
-rw-r--r--demos/voice_synthesis.htm290
-rw-r--r--demos/warble_tutorial.htm76
-rw-r--r--demos/wind_tutorial.htm43
62 files changed, 5940 insertions, 0 deletions
diff --git a/demos/allewis/cell_aut.lsp b/demos/allewis/cell_aut.lsp
new file mode 100644
index 0000000..3342843
--- /dev/null
+++ b/demos/allewis/cell_aut.lsp
@@ -0,0 +1,83 @@
+;; cell_aut.lsp -- cellular automata for sound generation
+;; originally by Ann Lewis
+;; revised by Roger B. Dannenberg
+;; March 2004
+
+;; compute-update-rule -- compute the output given a rule and 3 inputs
+;;
+(defun compute-update-rule (rule a b c)
+ ;; this is the most interesting part of the whole program
+ ;; the rule has 8 bits. Use a, b, c to index the rule bits
+ ;; and determine the result. To do this, we want a bit in
+ ;; the right position, e.g. if a=0,b=1,c=1, then the index
+ ;; is 011 = 3, and we want a bit pattern with "1" in position 3:
+ ;; 00001000. Note that this is 2^3 = a*2^4 + b*2^2 + c*2^1. So
+ ;; we can test a, b, and c and multiply by 16, 4, and 2 to get
+ ;; the right bit pattern. Then we can "and" it with rule to
+ ;; get either zero or a non-zero as the result.
+ (let ((abc 1))
+ (cond (a (setf abc 16)))
+ (cond (b (setf abc (* abc 4))))
+ (cond (c (setf abc (* abc 2))))
+ (setf rule (logand rule abc))
+ (> rule 0)))
+
+
+;; the main cellular automata implementation
+(defun cell-aut (sound-object-list duration update-rule iter)
+ (let (prev current array-len score (now 0.0) tmp)
+ ; create and initialize current and prev bit lists
+ (setf array-len (length sound-object-list))
+ (setf prev (make-array array-len))
+ (setf current (make-array array-len))
+ (setf prev (make-array array-len))
+ (setf (aref prev (/ array-len 2)) t)
+ ; create the score by computing iter generations of the automata
+ (dotimes (i iter)
+ (dotimes (j array-len)
+ (princ (if (aref prev j) " X" " 0"))
+ ; push a note on the list for each "true" in the prev array
+ (if (aref prev j)
+ (push (list now duration (nth j sound-object-list)) score)))
+ (terpri)
+ ; compute current from prev using update-rule
+ ; first do endpoints, wrap-around style
+ (setf (aref current 0)
+ (compute-update-rule update-rule
+ (aref prev (- array-len 1)) (aref prev 0) (aref prev 1)))
+ (setf (aref current (- array-len 1))
+ (compute-update-rule update-rule
+ (aref prev (- array-len 2)) (aref prev (- array-len 1))
+ (aref prev 0)))
+
+ ; then loop through everything else
+ ; want to cycle from 1 to array-len-2
+ (dotimes (j (- array-len 2))
+ (setf (aref current (+ j 1))
+ (compute-update-rule update-rule
+ (aref prev j) (aref prev (+ j 1)) (aref prev (+ j 2))))
+)
+ ; set prev to current
+ (setf tmp prev)
+ (setf prev current)
+ (setf current tmp)
+ ; increment the time
+ (setf now (+ now duration)))
+ ;; the score is now in reverse order, so fix it
+ (setf score (reverse score))
+ ;; now we have a score, render it to sound and return it:
+ (timed-seq score))
+)
+
+(defun cell-aut-major-scale ()
+ ;; for testing, this creates an 8-note scale
+ ;; requires (load "pianosyn") to get the piano library
+ (let (scale offsets)
+ (setf offsets '(0 2 4 5 7 9 11 12))
+ (dolist (p offsets)
+ (push (list 'piano-note-2 (+ A3 p) 100) scale))
+ (reverse scale)))
+
+(defun cell-aut-demo ()
+ (require-from piano-note-2 "pianosyn.lsp")
+ (play (scale 0.5 (cell-aut (cell-aut-major-scale) 0.2 30 80))))
diff --git a/demos/allewis/cellularautomata.htm b/demos/allewis/cellularautomata.htm
new file mode 100644
index 0000000..fe7d559
--- /dev/null
+++ b/demos/allewis/cellularautomata.htm
@@ -0,0 +1,79 @@
+<title>Cellular Automata</title>
+<h1>Cellular Automata Example</h1>
+<p><b>Ann Lewis and Roger B. Dannenberg</b></p>
+<p>This example is based on a class project by Ann Lewis.This project harnesses
+ the power of cellular automata for algorithmic composition. Cellular automata
+ have been applied to graphics and visual patterns as well as music. In this
+ work, the automaton consists of an array of boxes, where each box is initialized
+ to either black or white (on/off, 0/1). At every step the next row/generation
+ (represented visually as below the previous array) is computed from the first
+ array using an update rule on each array element. An update rule (that defines
+ the automaton itself) is simply a function from the array element's parent,
+ and the parent's left and right neighbors. This concept is illustrated here:
+</p>
+<pre> A1 A2 A3 ...
+ B1 B2 B3 ... </pre>
+<p>Let B2 be the element whose value is being computed. B2 is therefore dependent
+ on the values of A1, A2, and A3 only. An example of an update rule would be:</p>
+<pre>if A1 = A3 and A2 = 1 then B2 = 1, else B2 = 0</pre>
+<p> There are 2 possible values for each of A1, A2, and A3 which means there are
+ 2^3 = 8 possible configurations. And there are 2^8 = 256 possible functions
+ from A1, A2, and A3 to B2. Therefore there are only 256 possible update rules.
+ Note that the number of possible update rules is not dependent on the number
+ of elements in the array. The rules can be numbered from 0 to 255. In the picture
+ below, rule 30 is used to generate a series of rows, starting with a single
+ &quot;one&quot; in the first row.</p>
+<p align="center"><img src="rule30.jpg" width="370" height="270"></p>
+<p>Instead of B1 = 1 indicating that a box be colored black and B1 = 0 indicated
+ that a box be colored white, in the music model this will correspond to turning
+ certain sound objects on and off. For example, here we have an array of oscillators.
+</p>
+<pre>Osc 60 Osc 65 Osc 67 Osc 70 Osc 75 Osc 76 Osc 79</pre>
+<p> If only the 1st and 3rd elements are "turned on" this would result in the
+ chord (sum (Osc 60) (Osc 67)). So each array, or level of the automata would
+ correspond to a chord, and the chord progression would change over time as the
+ automata developed. </p>
+<p>This feature very versatile, so the user can specify the basic sound array,
+ the duration of each step, and which combining function to bring the activated
+ sounds together. This design allows the user to use any expression to create
+ sounds.</p>
+<p>The main function, <code>cell-aut</code>, takes the following parameters:</p>
+<ol>
+ <li>an array of sound objects, specified using expressions to be evaluated</li>
+ <li>the duration of each time step (also the duration for computing sound objects)</li>
+ <li>the update rule to use on array evolution, specified by number (0 - 255)</li>
+ <li>the number of iterations/generations the automata should allow itself to
+ grow </li>
+</ol>
+<p>Some interesting rules to try are Wolram's two most famous rules: 30 (chaotic)
+ and 90 (fractal patterns). </p>
+<h2>Algorithm Outline </h2>
+<p>Here is an outline of the algorithm implemented in <tt>cell-aut.lsp</tt>. </p>
+<ol>
+ <li>create and initialize "current" and "previous" bit lists -- these should
+ have the same length as the sound array the user gave this function) -- potentially
+ there could be a feature here allowing the user to specify the initial state
+ of the array.
+ <li>create and initialize the list of sounds to return
+ <li>loop iter times
+ <ol>
+ <li>get the list of currently activated sounds from the "previous" bit list
+ and extract the corresponding sounds from the sound array
+ <li>combine this set of sounds with the combining function (specified by
+ the user), and add the resulting sound to the output list
+ <li>compute the "current" bit list from the "previous" bit list using the
+ update rule iterated over all the elements -- this wraps around so that
+ endpoints are treated as being adjacent to each other
+ <li>set the "previous" bit array to the "current" bit array
+ <li>(end loop)
+ </ol>
+ <li>return the output list of sounds
+</ol>
+<h2>Demo</h2>
+<p>The file <code><a href="cell_aut.lsp">demos/allewis/cell_aut.lsp</a></code> includes the function <code>cell-aut-demo</code>
+ defined as follows:</p>
+<pre>(defun cell-aut-demo ()
+ (play (scale 0.5 (cell-aut (cell-aut-major-scale) 0.2 30 80))))</pre>
+<p>so you can run this to hear an example output from the <code>cell-aut</code>
+ function.</p>
+<p>&nbsp;</p>
diff --git a/demos/allewis/cmusic_pres.ppt b/demos/allewis/cmusic_pres.ppt
new file mode 100644
index 0000000..e3114c7
--- /dev/null
+++ b/demos/allewis/cmusic_pres.ppt
Binary files differ
diff --git a/demos/allewis/rule30.jpg b/demos/allewis/rule30.jpg
new file mode 100644
index 0000000..575eeb3
--- /dev/null
+++ b/demos/allewis/rule30.jpg
Binary files differ
diff --git a/demos/arp.sal b/demos/arp.sal
new file mode 100644
index 0000000..20e145a
--- /dev/null
+++ b/demos/arp.sal
@@ -0,0 +1,99 @@
+;; arpeggiation examples
+;; Roger B. Dannenberg
+
+;; An arpeggiator is a function that plays sequences of pitches in a pattern
+;; The typical patterns are very much like the palindrome pattern generator
+;; in Nyquist, so this example shows how to make arpeggiation patterns.
+
+;; A simple arpeggiation of a major-7th chord
+;;
+define function arp1()
+ begin
+ with pat = make-palindrome(list(c4, e4, g4, b4))
+ exec score-play(score-gen(score-len: 17, ioi: 0.2, pitch: next(pat)))
+ end
+
+;; This will play the simple arpeggio:
+;exec arp1()
+
+;; We can make an upward only arpeggiator using the cycle pattern:
+;;
+define function arp2()
+ begin
+ with pat = make-cycle(list(c4, e4, g4, b4))
+ exec score-play(score-gen(score-len: 17, ioi: 0.2, pitch: next(pat)))
+ end
+
+;; This will play it:
+;exec arp2()
+
+;; Arpeggios might sound a bit nicer with some legato or overlap, which
+;; is easy to do by changing the duration (dur:) parameter:
+;;
+define function arp3()
+ begin
+ with pat = make-cycle(list(c4, e4, g4, b4))
+ exec score-play(score-gen(score-len: 17, ioi: 0.2, dur: 0.4,
+ pitch: next(pat)))
+ end
+
+;; This will play it:
+;exec arp3()
+
+;; It might be more useful to add some parameters. They are:
+;;
+;; pitches -- a list of pitches to arpeggiate
+;; reps -- how many notes to generate
+;; ioi -- inter-onset interval
+;; dur -- a keyword parameter (optional), an ioi multiplier. Use 1
+;; to make the duration equal the ioi, use 2 for double the ioi
+;; instr -- a keyword parameter (must be quoted), naming an instrument
+;;
+;; Any parameter may be a pattern.
+;; Returns a score
+;;
+define function arp4(pitches, len, ioi, dur: 1, instr: quote(note))
+ begin
+ with n = next(len),
+ pat = make-cycle(next(pitches))
+ return score-gen(score-len: n, ioi: next(ioi), dur: next(dur),
+ name: next(instr), pitch: next(pat))
+ end
+
+;; Since arp4 returns a score, you can play it like this:
+; exec score-play(arp4(list(c4, e4, g4, b4, c5), 20, 0.15, 3))
+
+;; This will play the simple arpeggio:
+;exec arp4()
+
+;; Note: it might be nice to extend the parameters to let the user select
+;; the arpeggiation style (up, down, up-down, up-down with elision), but
+;; these can be specified just by writing out the full pattern, e.g. to
+;; get up-down with elision, write list(c4, e4, g4, b4, c5, b4, g4, e4),
+;; so I won't add that feature.
+
+;; Makeing sequences of arpeggios
+
+;; First define some pitch patterns:
+define variable c7 = list(c4, e4, g4, bf4, c5, bf4, g4, e4),
+ bf7 = list(bf3, d4, f4, af4, bf4, af4, f4, d4),
+ af7 = list(af3, c4, ef4, gf4, af4, gf4, ef4, c4),
+ g7 = list(g3, b3, d4, f4, g4, f4, d4, b3)
+
+;; now call arp4 to make some scores and splice them together
+
+define function arp-seq()
+ begin
+ with score = nil
+ loop
+ for pitches in list(c7, bf7, af7, g7, c7)
+ for len in list(16, 16, 16, 16, 33)
+ set score = score-append(score, arp4(pitches, len, 0.13, 3))
+ end
+ return score
+ end
+
+;; make the score and play it
+exec score-play(arp-seq())
+
+
diff --git a/demos/arpeggiator.htm b/demos/arpeggiator.htm
new file mode 100644
index 0000000..7ee0f35
--- /dev/null
+++ b/demos/arpeggiator.htm
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=ISO-8859-1">
+ <meta name="GENERATOR"
+ content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Untitled Document</title>
+</head>
+<body bgcolor="#ffffff">
+<h1>
+Arpeggiator Tutorial</h1>
+This page describes an arpeggiator example in Nyquist.
+<h2>What does it do?</h2>
+An arpeggiator plays a sequence of pitches over and over, usually
+outlining a chord.
+<h2>How does it work?</h2>
+The file <a href="arp.sal">arp.sal</a> has example code to create
+arpeggiator effects. There are comments in the code to describe how it
+works.<br>
+<h2>How can I use it?</h2>
+<pre>SAL&gt; load "arp.sal"<br></pre>
+Or, open demos/arp.sal using the Nyquist IDE and load the file with the
+load button.<br>
+<br>
+You should hear a short piece. There are simpler examples in the code
+-- read the comments in the code to see all the examples and to find
+commands to try them out.<br>
+<br>
+</body>
+</html>
diff --git a/demos/bandfx.htm b/demos/bandfx.htm
new file mode 100644
index 0000000..862af9c
--- /dev/null
+++ b/demos/bandfx.htm
@@ -0,0 +1,59 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Untitled Document</title>
+</head>
+<body bgcolor="#FFFFFF">
+
+<h1>
+Multiple Band Effects Tutorial</h1>
+This page describes how to use the bandfx library in Nyquist.
+<h2>
+What does it do?</h2>
+The idea is very simple: separate the incoming signal into different frequency
+bands. Apply an effect to each frequency band.
+<br>For example, apply a delay, with longer delays at higher frequencies.
+Then sum the outputs of the effects. In the delay example,
+<br>the result will be something like a filter sweep -- the low frequencies
+come out first, followed by increasingly higher frequencies.
+<h2>
+How does it work?</h2>
+Frequency bands are separated using Nyquist's <font face="">reson</font>
+filter. Although reson is not perfect for this job, it has the nice
+<br>feature that there is a complementary areson filter that returns everything
+removed by reson. We split off the lowest
+<br>frequency band with reson, then apply areson to get the remainder of
+the signal. We pass this through another reson
+<br>tuned to the second band and use another areson to get the remainder.
+Using a series of filters, we pull off all the
+<br>band except for the last one, which is just whatever is left over.
+<p>The function separate-into-bands constructs an array of frequency bands.
+The function reconstruct-from-bands sums an
+<br>array of frequency bands back into a single channel. Different functions
+apply effects to the frequency band representation.
+<br>Consult the code (see lib/bandfx.lsp) for details. You can use the
+code as a template for creating your own multiple band effects.
+<h2>
+How can I use it?</h2>
+
+<pre>> (load "bandfx")</pre>
+
+<pre>> (f2)</pre>
+
+<pre>> (f3)</pre>
+
+<pre>> (f4)</pre>
+
+<pre>> (f5)</pre>
+The commands shown above will play some examples that are included in lib/bandfx.lsp.
+You can read the code for
+<br>a description of the functions and to see examples of their use. The
+functions are also described in the Nyquist manual
+<br>(see "multiple band effects" in the index).<i></i>
+<p>The manual also describes some ways this library might be extended.
+Please contribute some examples if you find these effects useful.
+<br>&nbsp;
+</body>
+</html>
diff --git a/demos/beginclip.jpg b/demos/beginclip.jpg
new file mode 100644
index 0000000..feae664
--- /dev/null
+++ b/demos/beginclip.jpg
Binary files differ
diff --git a/demos/demo-snd.aiff b/demos/demo-snd.aiff
new file mode 100644
index 0000000..6ab7265
--- /dev/null
+++ b/demos/demo-snd.aiff
Binary files differ
diff --git a/demos/demo.mid b/demos/demo.mid
new file mode 100644
index 0000000..472dc6b
--- /dev/null
+++ b/demos/demo.mid
Binary files differ
diff --git a/demos/distortion.htm b/demos/distortion.htm
new file mode 100644
index 0000000..915fa0d
--- /dev/null
+++ b/demos/distortion.htm
@@ -0,0 +1,118 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Untitled Document</title>
+</head>
+<body bgcolor="#FFFFFF">
+
+<h1>
+Distortion Tutorial</h1>
+This page describes how to use the Nyquist <tt>shape</tt> function to achieve distortion.
+<h2>
+Terminology</h2>
+First, some terminology:
+<blockquote><i>Clipping</i> means that you limit the amplitude of samples,
+e.g.
+<p>sample_out = min(sample_in, 1.0),</blockquote>
+or, observing that you might want to limit negative excursions as well
+as positive ones:
+<blockquote>sample_out = max(min(sample_in, 1.0), -1.0).</blockquote>
+This type of clipping is called <i>hard clipping</i> because the transition
+from an undistorted one to a maximum or minimum value is instantaneous,
+as if the signal hit a brick wall and can go no more.
+<p>As you might guess, you can also have <i>soft clipping</i> where the
+transition is more gradual, and that's what this tutorial is about.
+<p>Before discussing soft clipping, let's introduce a few other terms.
+Since <i>clipping</i> seems to be a way of <i>limiting</i> the values of
+the signal or <i>compressing</i> the range of the signal, you might think
+that clipping is a form of compressing or limiting; however, these terms
+have special meanings in the audio processing world.
+<blockquote><i>Compression</i>, or <i>dynamics compression</i> (not to
+be confused with <i>data compression</i>) is a way of reducing the overall
+range of soft to loud.</blockquote>
+To do dynamics compression, you generally detect the intensity or peak
+level of a sound over a time scale of a few milliseconds, and then construct
+a relatively smooth amplitude control that you apply to the signal. For
+compression, the amplification goes down as the intensity of the input
+goes up, so loud passages get (relatively) softer and soft passages get
+(relatively) louder. (Dynamics expansion does just the opposite.) <i>Limiters</i>
+work like compressors, but are designed to eliminate peaks -- conceptually,
+there is no real difference, and products are often sold as "compressor/limiters".
+See nyquist/lib/compress.lsp for an implementation.
+<p>In some ways, soft clipping is like dynamics compression. Both reduce
+the gain at high levels, but dynamics compression operates relatively slowly,
+effectively turning the volume knob up and down, whereas clipping operates
+on a sample-by-sample basis. The effect of clipping is to distort the input.
+<p>In Nyquist, you use the <tt>shape</tt> function to implement clipping. <tt>shape</tt>
+applies a function to each sample, where the function is specified by a
+sound. The following is a typical function for soft clipping:
+<center><img SRC="softclip.jpg" ></center>
+Notice how the function is essentially y=x at small amplitudes, so there
+is no distortion for small signals, but at large input values, the function
+becomes very non-linear. Also, notice that this is similar to the behavior
+of real-life amplifiers, where small signals are undistorted, but at some
+point, the power limits of the amplifier clip the output signal.
+<p>The Nyquist <tt>shape</tt> function is allows you to specify any function you
+like using a sound. Therefore you can use any of the Nyquist primitives
+to construct the function. Since a sound is a function of time, where time
+must be non-negative, how do you specify a shape function over a range
+that includes negative values? The trick is that <tt>shape</tt> takes an <i>offset</i>
+parameter that shifts the whole function to the left (in the -y direction).
+Note also that whereas a Nyquist sound is generally regarded as a function
+of time, <tt>shape</tt> treats the sound as just a real-valued function.
+<p>The typical way to use shape is to create some increasing signal over
+the interval [0,2] that crosses zero at 1.0. Then you give 1.0 as the offset
+(3rd parameter). The result will look something like the graph above.
+<h2>Implementation</h2>
+In the figure above, I used a sine function to generate the smooth curve. Here is an implementation of distortion in Nyquist using the sine curve:
+<blockquote>
+<pre>(setf distortion
+ (osc (hz-to-step 0.25) 2.01 *SINE-TABLE* -90.0))
+(defun distort (snd)
+ (shape snd distortion 1.0))
+
+(play (distort (mult 15.0 (ramp 4) (osc c4 4))))
+</pre>
+</blockquote>
+<p>Even though I am an expert, and I have done this before, it still took
+me a few tries to get right. Here's a step-by-step explanation:
+<ul>
+<li>I used <tt>osc</tt> to generate a sinusoid so I could control the initial phase.
+<li>I set the osc duration to 2 because I want the table to go from
+0 to 2 (after which we'll shift it back to [-1, +1]), but 2 is not enough because the interval [0,2] is closed, which
+means I need one extra sample. I used 2.01 to be conservative.
+<li>I specified <tt>*SINE-TABLE*</tt>, the default value, because the table
+parameter comes before the phase parameter.
+<li>I specified the phase to get the sine curve to go through zero
+in the <i>middle</i> of the generated function.
+<li>I assigned this to the variable distortion so I could plot it; try:
+<pre>(s-plot (force-srate 100 distortion))</pre>
+<li>Finally, I put in a tone that ramps up from zero to 15 in amplitude
+to cause some serious clipping. The output amplitude is limited to 1.
+</ul>
+<p>Note that the input to <tt>shape</tt> is pre-clipped to the range
+[-1, +1] so you only need to specify the table from [0, 2] if the origin (third parameter to <tt>shape</tt>) is 1.0. If you specify a little extra, as
+in this example, it will be ignored.
+<h2>The Output</h2>
+<p>
+Look
+at the generated waveform to observe the soft clipping effect. Here we see the beginning of the output, where the input amplitude is low and there is very little distortion:
+<p>
+<center>
+<img src="beginclip.jpg">
+</center>
+But when the input amplitude becomes large, the clipping becomes substantial. This plot is at the same scale, but taken from a later portion of the generated output. Remember that the input at this point is a high-amplitude sinusoid:<p>
+<center>
+<img src="largeclip.jpg">
+</center>
+Also notice
+that the distortion is symetrical, so it generates even harmonics. If you
+put in an asymetric function, you'll get odd harmonics too. Note that at
+soft levels, I actually get some gain from this function.
+<p><i>Generated by Roger Dannenberg (roger.dannenberg@cs.cmu.edu) Feb,
+2004.</i></blockquote>
+
+</body>
+</html>
diff --git a/demos/examples.lsp b/demos/examples.lsp
new file mode 100644
index 0000000..58fd9ae
--- /dev/null
+++ b/demos/examples.lsp
@@ -0,0 +1,424 @@
+;; examples.lsp -- these are from the Nyquist Manual examples
+
+(defun ex1 ()
+ (play (osc 60)))
+
+(defun ex2 ()
+ (play (scale 0.5 (osc 60))))
+
+; build-harmonic is already defined in nyquist.lsp
+;
+;(defun build-harmonic (n) (snd-sine 0 n tablesize 1))
+
+(defun mkwave ()
+ (setf *table* (sim (scale 0.5 (build-harmonic 1.0 2048))
+ (scale 0.25 (build-harmonic 2.0 2048))
+ (scale 0.125 (build-harmonic 3.0 2048))
+ (scale 0.062 (build-harmonic 4.0 2048))))
+ (setf *table* (list *table* (hz-to-step 1) T)))
+
+(cond ((not (boundp '*mkwave*))
+ (mkwave)
+ (setf *mkwave* t)))
+
+(defun note (pitch dur)
+ (osc pitch dur *table*))
+
+(defun ex3 ()
+ (play (seq (note c4 i)
+ (note d4 i)
+ (note f4 i)
+ (note g4 i)
+ (note d4 q))))
+
+(defun env-note (p)
+ (mult (note p 1.0)
+ (env 0.05 0.1 0.5 1.0 0.5 0.4)))
+
+(defun ex4 ()
+ (play (env-note c4)))
+
+
+(defun ex5 ()
+ (play (seq (stretch 0.25
+ (seq (env-note c4)
+ (env-note d4)))
+ (stretch 0.5
+ (seq (env-note f4)
+ (env-note g4)))
+ (env-note c4))))
+
+(defun ex6 ()
+ (play (seq (note c4 q) (note d4 i))))
+
+
+(defun ex7 ()
+ (play (scale 0.5 (sim (note c4 q) (note d4 i)))))
+
+;; previous versions could not get current-path to locate demo-snd.aiff...
+;(format t "~%examples.lsp tries to load demo-snd.aiff from the~%")
+;(format t "default sound file directory, which is stored in~%")
+;(format t "the variable *default-sf-dir*. The current value is:~%")
+;(format t "\"~A\". If you get an error immediately, you should~%"
+; *default-sf-dir*)
+;(format t "either set *default-sf-dir* or copy demo-snd.aiff~%")
+;(format t "where Nyquist will find it.~%")
+
+(display "examples.lsp" (current-path))
+
+(if (not (boundp 'a-snd))
+ (setf a-snd (s-read (strcat (current-path)
+ "demo-snd.aiff"))))
+
+(defun ex8 ()
+ (play a-snd))
+
+(defun ex9 ()
+ (play (seq (cue a-snd) (cue a-snd))))
+
+(defun ex10 ()
+ (play (sim (at 0.0 (cue a-snd))
+ (at 0.7 (cue a-snd))
+ (at 1.0 (cue a-snd))
+ (at 1.2 (cue a-snd)))))
+
+(defun ex11 ()
+ (play (sim (cue a-snd)
+ (loud 6.0 (at 3.0 (cue a-snd))))))
+
+(defun ex12 ()
+ (play (loud 6.0 (sim (at 0.0 (cue a-snd))
+ (at 0.7 (cue a-snd))))))
+
+(defun snds (dly)
+ (sim (at 0.0 (cue a-snd))
+ (at 0.7 (cue a-snd))
+ (at 1.0 (cue a-snd))
+ (at (+ 1.2 dly) (cue a-snd))))
+
+(defun ex13 ()
+ (play (snds 0.1)))
+
+(defun ex14 ()
+ (play (loud 0.25 (stretch 0.9 (snds 0.3)))))
+
+(defun ex15 ()
+ (play (sound-srate-abs 44100.0 (osc c4))))
+
+(defun tone-seq ()
+ (seqrep (i 16)
+ (stretch 0.25 (osc-note c4))))
+
+(defun pitch-rise () (stretch 4.0 (scale 16 (ramp))))
+
+(defun chromatic-scale ()
+ (transpose (pitch-rise) (tone-seq)))
+
+(defun ex16 ()
+ (play (chromatic-scale)))
+
+(defun ex17 ()
+ (play (sustain (stretch 4 (sum 0.2 (ramp)))
+ (chromatic-scale))))
+
+(defun warper ()
+ (pwl .25 .4 .75 .6 1.0 1.0 2.0 2.0 2.0))
+
+(defun warp4 () (stretch 4 (scale 4 (warper))))
+
+(defun ex18 ()
+ (play (warp (warp4) (tone-seq))))
+
+; note: as explained in the manual, the following is NOT
+; the solution to a fixed duration/variable tempo sequence:
+;
+(defun tone-seq-2 ()
+ (seqrep (i 16)
+ (stretch-abs 0.25 (osc-note c4))))
+
+(defun ex19 ()
+ (play (warp (warp4) (tone-seq-2))))
+
+; here is the proper solution (vs. ex19):
+;
+(defun tone-seq-3 ()
+ (seqrep (i 16)
+ (set-logical-stop
+ (stretch-abs 0.25 (osc-note c4))
+ 0.25)))
+
+(defun ex20 ()
+ (play (warp (warp4) (tone-seq-3))))
+
+(defun ex21 ()
+ (play (warp (warp4)
+ (transpose (pitch-rise) (tone-seq)))))
+
+(defun ex22 ()
+ (play (warp (warp4)
+ (transpose (control-warp (get-warp)
+ (warp-abs nil (pitch-rise)))
+ (tone-seq)))))
+
+(defun ex23 ()
+ (play (force-srate *default-sound-srate* (stretch 3.0 (sound a-snd)))))
+
+(defun down ()
+ (force-srate *default-sound-srate*
+ (seq (stretch 0.2 (sound a-snd))
+ (stretch 0.3 (sound a-snd))
+ (stretch 0.4 (sound a-snd))
+ (stretch 0.5 (sound a-snd))
+ (stretch 0.6 (sound a-snd)))))
+
+(defun ex24 () (play (down)))
+
+(defun up ()
+ (force-srate *default-sound-srate*
+ (seq (stretch 0.5 (sound a-snd))
+ (stretch 0.4 (sound a-snd))
+ (stretch 0.3 (sound a-snd))
+ (stretch 0.2 (sound a-snd)))))
+
+(defun ex25 ()
+ (play (seq (down) (up) (down))))
+
+(defun ex26 ()
+ (s-save a-snd 1000000000 "./a-snd-file.snd")
+ (play-file "./a-snd-file.snd")
+ (system "rm ./a-snd-file.snd"))
+
+(defun ex27 ()
+ (setf my-sound-file "./a-snd-file.snd")
+ (s-save a-snd 1000000000 my-sound-file)
+ (play-file my-sound-file)
+ (system (strcat "rm " my-sound-file)))
+
+(defun ex28 ()
+ ; normalize in memory. First, assign the sound to a variable so
+ ; it will be retained:
+ (setf mysound (sim (osc c4) (osc c5)))
+ ; now compute the maximum value (ny:all is a 1 giga-samples, you may want a
+ ; smaller constant if you have less than 4GB of memory :-):
+ (setf mymax (snd-max mysound NY:ALL))
+ (display "Computed max" mymax)
+ ; now write out and play the sound from memory with a scale factor:
+ (play (scale (/ 1.0 mymax) mysound)))
+
+(defun ex29 ()
+ ; if you don't have space in memory, here's how to do it:
+ (defun myscore () (sim (osc c4) (osc c5)))
+ ; compute the maximum, don't forget the quote!:
+ (setf mymax (snd-max '(myscore) NY:ALL))
+ (display "Computed max" mymax)
+ ; now we know the max, but we don't have a the sound (it was garbage
+ ; collected and never existed all at once in memory). Compute the sound
+ ; again, this time with a scale factor:]
+ (play (scale (/ 1.0 mymax) (myscore))))
+
+(defun ex30 ()
+ (play (fmosc c4 (pwl 0.1))))
+
+(defun ex31 ()
+ (play (fmosc c4 (pwl 0.5))))
+
+(defun ex32 ()
+ (play (fmosc c4 (pwl 0.5 (step-to-hz c4) 0.501))))
+
+(defun ex33 ()
+ (setf *fm-voice* (list
+ (extract 0.110204 0.13932 (cue a-snd))
+ 24.848422
+ T))
+ (play (fmosc cs2 (pwl 0.5 (step-to-hz cs2) 0.501)
+ *fm-voice* 0.0)))
+
+(defun sweep (delay pitch-1 sweep-time pitch-2 hold-time)
+ (let ((interval (- (step-to-hz pitch-2)
+ (step-to-hz pitch-1))))
+ (pwl delay 0.0
+ ; sweep from pitch 1 to pitch 2
+ (+ delay sweep-time) interval
+ ; hold until about 1 sample from the end
+ (+ delay sweep-time hold-time -0.0005) interval
+ ; quickly ramp to zero (pwl always does this,
+ ; so make it short)
+ (+ delay sweep-time hold-time))))
+
+
+(defun ex34 ()
+ (play (fmosc cs2 (sweep 0.1 cs2 0.6 gs2 0.5)
+ *fm-voice* 0.0)))
+
+(defun ex35 ()
+ (play (fmosc cs2 (scale 10.0 (lfo 6.0))
+ *fm-voice* 0.0)))
+
+(defun ex36 ()
+ (let (modulator)
+ (setf modulator (mult (pwl 1.0 1000.0 1.0005)
+ (osc c4)))
+ (play (fmosc c4 modulator))))
+
+;;; FINDING ZERO CROSSINGS, SND-SAMPLES
+
+(setf max-samples-for-zeros 1000)
+
+(defun zeros (snd)
+ ; start by getting the samples, only take 1000 samples max
+ (prog ((s (snd-samples snd max-samples-for-zeros))
+ newsign sign n len result result2 starttime srate)
+ ; go through the array looking for zero crossings
+ (setf len (length s))
+ ; stop if there are no samples
+ (if (= len 0) (return nil))
+ (setf sign (> 0.0 (aref s 0)))
+ ; get the start time and sample rate of the sound for use below
+ (setf starttime (car (snd-extent snd max-samples-for-zeros)))
+ (setf srate (snd-srate snd))
+ (setf n 1)
+ loop
+ (if (>= n len) (go done))
+ (setf newsign (> 0.0 (aref s n)))
+ (if (not (eq sign newsign)) (setf result (cons n result)))
+ (setf sign newsign)
+ (setf n (1+ n))
+ (go loop)
+ done ; now we have the zero crossings, convert them to times
+ (dolist (num result)
+ ; return the time of the zero crossing, which is the start time
+ of the snd plus the sample number / srate
+
+ (setf result2 (cons (+ starttime (/ num srate))
+ result2)))
+
+ (return result2)))
+
+(defun ex37 ()
+ ; extract a short piece of this sample
+ (setf short (extract 0.1 0.14 (cue a-snd)))
+ (setf z (zeros short))
+ (format t "Zero crossings from a-snd: ~A~%" z))
+
+
+; find the differences between zero crossings reported by zeros
+; print the result in terms of samples for readability
+;
+(defun periods (lis short)
+ (prog (result prev srate)
+ (if (null lis) (return nil))
+ (setf srate (snd-srate short))
+ loop
+ (setf prev (car lis))
+ (setf lis (cdr lis))
+ (if (null lis) (return (reverse result)))
+ (setf result (cons (* srate (- (car lis) prev)) result))
+ (go loop)))
+
+(defun ex38 ()
+ ; ex38 depends upon z, set by (ex37)
+ (cond ((not (boundp 'z)) (ex37)))
+ (setf p (periods z short))
+ (format t "The intervals (in samples) between zero crossings are: ~%~A~%" p))
+
+
+; build a wavetable using zero crossing information
+;
+; I interactively played with the data and decided to extract from the
+; 5th period to the 21st period (these had 86 and 87 samples each and
+; seem to indicate some kind of periodicity). The 1st period measures
+; from the zeroth zero crossing to the first, so the 5th period measures
+; from the 4th zero crossing to the 5th. I'll arbitrarily take
+; the 4th and 20th zero crossing times (the 5th and 20th should work as
+; well), and from the data, this looks like 2 waveform periods.
+; This is very clear if you plot the data.
+;
+; arguments are:
+; snd - the sound to extract from
+; zeros - the result of (zeros snd)
+; start - the number of the starting zero crossing
+; stop - the number of the ending zero crossing
+; n - number of periods contained in the extracted sound
+;
+(defun extract-table (snd zeros start stop n)
+ (let (starttime extent hz)
+ ; Start by shifting snd to time zero:
+ (setf starttime (car (snd-extent snd max-samples-for-zeros)))
+ (setf snd (at (- starttime) (cue snd)))
+
+ (format t "~A~%" snd)
+ ; also get the start and stop times and shift them:
+ (setf start (- (nth start zeros) starttime))
+ (setf stop (- (nth stop zeros) starttime))
+
+ (format t "table ~A start ~A stop ~A~%" snd start stop)
+
+ ; now extract the samples of interest, note that we are
+ ; overwriting our pointer to the snd argument
+ (setf snd (extract start stop (cue snd)))
+ (format t "table now ~A~%" snd)
+
+ ; now we need to figure out the pitch this sound would represent
+ ; when played at its samplerate. The pitch in hz is 1 / duration,
+ ; and duration is the extent of the sound / n. Therefore, take
+ ; n/extent
+ (setf extent (snd-extent snd max-samples-for-zeros))
+ (setf hz (/ n (- (cadr extent) (car extent))))
+ ; an osc table is a list of the sound, pitch number, and T (periodic)
+ (list snd (hz-to-step hz) T)))
+
+
+(defun ex39 ()
+ ; try it out
+ (setf *a-voice* (extract-table short z 4 20 2))
+ ; now use the table with an oscillator
+ (play (osc c3 1.0 *a-voice* )))
+
+(defun ex40 ()
+ ; play it at its normal pitch
+ (play (osc (cadr *a-voice*) 1.0 *a-voice*)))
+
+(defun ex41 ()
+ (play (noise)))
+
+(defun ex42 ()
+ (play (lp (noise) 1000.0)))
+
+(defun ex43 ()
+ (play (hp (noise) 1000.0)))
+
+; low pass sweep from 100 hz to 2000 hz
+(defun ex44 ()
+ (play (lp (noise) (pwl 0.0 100.0 1.0 2000.0 1.0))))
+
+; high pass sweep from 50 hz to 4000 hz
+(defun ex45 ()
+ (play (hp (noise) (pwl 0.0 50.0 1.0 4000.0 1.0))))
+
+; band pass at 500 hz, 20 hz bandwidth
+(defun ex46 ()
+ (play (reson (scale 10.0 (noise)) 500.0 20.0 1)))
+
+; band pass sweep from 100 to 1000 hz, 20 hz bandwidth
+(defun ex47 ()
+ (play (reson (scale 0.04 (noise))
+ (pwl 0.0 200.0 1.0 1000.0 1.0) 20.0)))
+
+(format t "\nType (ex1) through (ex47) to run these examples.\n")
+(format t "See demos/stktest.lsp for more simple sound examples.\n")
+(format t "\nI'm turning off Auto-normalization. See AUTONORM-ON\n")
+(format t "in the documentation for an explanation:\n\n")
+(autonorm-off)
+
+(defun ex-all ()
+ (format t
+ "Warning: turning automatic normalization feature off~%")
+ (autonorm-off)
+ (dotimes (i 47)
+ (let ((j (+ i 1)) fn)
+ (setf fn (intern (format nil "EX~A" j)))
+ (setf fn (list fn))
+ (format t "~A~%" fn)
+ (eval fn))))
+
+(format t "\n(ex-all) will compute and play all examples for testing purposes.\n")
diff --git a/demos/examples.sal b/demos/examples.sal
new file mode 100644
index 0000000..c746628
--- /dev/null
+++ b/demos/examples.sal
@@ -0,0 +1,518 @@
+;; examples.lsp -- these are from the Nyquist Manual examples
+
+define function ex1()
+ play osc(60)
+
+define function ex2()
+ play 0.5 * osc(60)
+
+; build-harmonic is already defined in nyquist.lsp
+;
+;(defun build-harmonic (n) (snd-sine 0 n tablesize 1))
+
+define function mkwave()
+ begin
+ set *table* = 0.5 * build-harmonic(1.0, 2048) +
+ 0.25 * build-harmonic(2.0, 2048) +
+ 0.125 * build-harmonic(3.0, 2048) +
+ 0.0625 * build-harmonic(4.0, 2048)
+ set *table* = list(*table*, hz-to-step(1.0), #t)
+ end
+
+
+if ! boundp(quote(*mkwave*)) then
+ begin
+ exec mkwave()
+ set *mkwave* = #t
+ end
+
+
+define function my-note(pitch, dur)
+ return osc(pitch, dur, *table*)
+
+
+define function ex3()
+ play seq(my-note(c4, i), my-note(d4, i), my-note(f4, i),
+ my-note(g4, i), my-note(d4, q))
+
+
+define function env-note(p)
+ return my-note(p, 1.0) *
+ env(0.05, 0.1, 0.5, 1.0, 0.5, 0.4)
+
+
+define function ex4()
+ play env-note(c4)
+
+
+define function ex5()
+ play seq(seq(env-note(c4), env-note(d4)) ~ 0.25,
+ seq(env-note(f4), env-note(g4)) ~ 0.5,
+ env-note(c4))
+
+
+define function ex6()
+ play seq(my-note(c4, q), my-note(d4, i))
+
+
+define function ex7()
+ play 0.5 * sim(my-note(c4, q), my-note(d4, i))
+
+;; previous versions could not get current-path to locate demo-snd.aiff...
+;(format t "~%examples.lsp tries to load demo-snd.aiff from the~%")
+;(format t "default sound file directory, which is stored in~%")
+;(format t "the variable *default-sf-dir*. The current value is:~%")
+;(format t "\"~A\". If you get an error immediately, you should~%"
+; *default-sf-dir*)
+;(format t "either set *default-sf-dir* or copy demo-snd.aiff~%")
+;(format t "where Nyquist will find it.~%")
+
+set a-snd = s-read(strcat(current-path(), "demo-snd.aiff"))
+
+
+define function ex8()
+ play a-snd
+
+
+define function ex9()
+ play seq(cue(a-snd), cue(a-snd))
+
+
+define function ex10()
+ play sim(cue(a-snd) @ 0.0,
+ cue(a-snd) @ 0.7,
+ cue(a-snd) @ 1.0,
+ cue(a-snd) @ 1.2)
+
+
+define function ex11()
+ play sim(cue(a-snd),
+ loud(6.0, cue(a-snd) @ 3))
+
+
+define function ex12()
+ play loud(6.0, sim(cue(a-snd) @ 0.0,
+ cue(a-snd) @ 0.7))
+
+
+define function snds(dly)
+ return sim(cue(a-snd) @ 0.0,
+ cue(a-snd) @ 0.7,
+ cue(a-snd) @ 1.0,
+ cue(a-snd) @ (1.2 + dly))
+
+
+define function ex13()
+ play snds(0.1)
+
+
+define function ex14()
+ play loud(0.25, snds(0.3) ~ 0.9)
+
+
+define function ex15()
+ play sound-srate-abs(44100.0, osc(c4))
+
+
+define function tone-seq()
+ return seqrep(i, 16,
+ osc-note(c4) ~ 0.25)
+
+
+define function pitch-rise()
+ ; pitch-rise turns tone-seq into a chromatic scale
+ ; through transposition
+ ; override sustain to avoid changing ramp duration
+ return sustain-abs(1.0, 16 * ramp() ~ 4)
+
+
+define function chromatic-scale()
+ return transpose(pitch-rise(), tone-seq())
+
+
+define function ex16()
+ play chromatic-scale()
+
+
+define function ex17()
+ play sustain((0.2 + ramp()) ~ 4,
+ chromatic-scale())
+
+
+define function warper()
+ ; between 0 and 1, warper goes slow/fast/slow, then
+ ; it adds extra 1-to-1 mapping from 1 to 2, which is
+ ; just "padding" to avoid numerical problems near 1.0
+ return pwl(0.25, .4, .75, .6, 1.0, 1.0, 2.0, 2.0, 2.0)
+
+
+define function warp4()
+ ; stretch by 4 and scale by 4: now we're warping
+ ; a 4 second sequence within a 4 second duration
+ return 4 * warper() ~ 4
+
+
+define function ex18()
+ play warp(warp4(), tone-seq())
+
+
+; note: as explained in the manual, the following is NOT
+; the solution to a fixed duration/variable tempo sequence:
+;
+define function tone-seq-2 ()
+ return seqrep(i, 16,
+ osc-note(c4) ~~ 0.25)
+
+
+define function ex19()
+ play warp(warp4(), tone-seq-2())
+
+; here is the proper solution (vs. ex19):
+;
+define function tone-seq-3()
+ return seqrep(i, 16,
+ set-logical-stop(osc-note(c4) ~~ 0.25, 0.25))
+
+
+define function ex20()
+ play warp(warp4(), tone-seq-3())
+
+
+define function ex21()
+ play warp(warp4(),
+ transpose(pitch-rise(), tone-seq()))
+
+
+define function ex22()
+ play warp(warp4(),
+ transpose(control-warp(get-warp(),
+ warp-abs(nil, pitch-rise())),
+ tone-seq()))
+
+
+if not(boundp(quote(a-snd))) then
+ set a-snd = s-read("demo-snd.aiff")
+
+
+define function ex23()
+ play force-srate(*default-sound-srate*, sound(a-snd) ~ 3.0)
+
+define function down()
+ return force-srate(*default-sound-srate*,
+ seq(sound(a-snd) ~ 0.2,
+ sound(a-snd) ~ 0.3,
+ sound(a-snd) ~ 0.4,
+ sound(a-snd) ~ 0.6))
+
+
+define function ex24()
+ play down()
+
+define function up()
+ return force-srate(*default-sound-srate*,
+ seq(sound(a-snd) ~ 0.5,
+ sound(a-snd) ~ 0.4,
+ sound(a-snd) ~ 0.3,
+ sound(a-snd) ~ 0.2))
+
+
+define function ex25()
+ play seq(down(), up(), down())
+
+
+define function ex26()
+ begin
+ exec s-save(a-snd, 1000000000, "./a-snd-file.snd")
+ play "./a-snd-file.snd"
+ exec system("rm ./a-snd-file.snd")
+ end
+
+
+define function ex27()
+ begin
+ set my-sound-file = "./a-snd-file.snd"
+ exec s-save(a-snd, 1000000000, my-sound-file)
+ exec play-file(my-sound-file)
+ exec system(strcat("rm ", my-sound-file))
+ end
+
+
+; note that Nyquist's "Autonorm" facility probably makes this example
+; superfluous
+define function ex28()
+ begin
+ ; normalize in memory. First, assign the sound to a variable so
+ ; it will be retained:
+ set mysound = sim(osc(c4), osc(c5))
+ ; now compute the maximum value (ny:all is a 1 giga-samples, you may want a
+ ; smaller constant if you have less than 4GB of memory :-):
+ set mymax = snd-max(mysound, NY:ALL)
+ display "Computed max", mymax
+ ; now write out and play the sound from memory with a scale factor:
+ play mysound * (0.9 / mymax)
+ end
+
+
+define function myscore()
+ return sim(osc(c4), osc(c5))
+
+
+define function ex29()
+ begin
+ ; if you don't have space in memory, here's how to do it:
+ ; Compute the maximum. This is a bit tricky in SAL because snd-max
+ ; is looking for an expression (in LISP) to evaluate, not a sound.
+ ; Use list and quote to create the LISP expression '(myscore):
+ set mymax = snd-max(list(quote(myscore)), NY:ALL)
+ display "Computed max", mymax
+ ; now we know the max, but we don't have a the sound (it was garbage
+ ; collected and never existed all at once in memory). Compute the sound
+ ; again, this time with a scale factor:]
+ play myscore() * (0.9 / mymax)
+ end
+
+
+define function ex30()
+ play fmosc(c4, pwl(0.1))
+
+
+define function ex31()
+ play fmosc(c4, pwl(0.5))
+
+
+define function ex32()
+ play fmosc(c4, pwl(0.5, step-to-hz(c4), 0.501))
+
+
+define function ex33()
+ begin
+ set *fm-voice* = list(extract(0.110204, 0.13932, cue(a-snd)),
+ 24.848422,
+ #T)
+ play fmosc(cs2, pwl(0.5, step-to-hz(cs2), 0.501),
+ *fm-voice*, 0.0)
+ end
+
+
+define function sweep(delay, pitch-1, sweep-time, pitch-2, hold-time)
+ begin
+ with interval = step-to-hz(pitch-2) - step-to-hz(pitch-1)
+ return pwl(delay, 0.0,
+ ; sweep from pitch 1 to pitch 2
+ delay + sweep-time, interval,
+ ; hold until about 1 sample from the end
+ delay + sweep-time + hold-time - 0.0005, interval,
+ ; quickly ramp to zero (pwl always does this,
+ ; so make it short)
+ delay + sweep-time + hold-time)
+ end
+
+
+define function ex34()
+ play fmosc(cs2, sweep(0.1, cs2, 0.6, gs2, 0.5),
+ *fm-voice*, 0.0)
+
+
+define function ex35()
+ play fmosc(cs2, 10.0 * lfo(6.0), *fm-voice*, 0.0)
+
+
+define function ex36()
+ begin
+ with modulator
+ set modulator = pwl(1.0, 1000.0, 1.0005) *
+ osc(c4)
+ play fmosc(c4, modulator)
+ end
+
+
+;;; FINDING ZERO CROSSINGS, SND-SAMPLES
+
+set max-samples-for-zeros = 1000
+
+define function zeros(snd)
+ begin
+ ; start by getting the samples, only take 1000 samples max
+ with s = snd-samples(snd, max-samples-for-zeros),
+ newsign, sign, n, len, result, result2, starttime, srate
+ ; go through the array looking for zero crossings
+ set len = length(s)
+ ; stop if there are no samples
+ if len = 0 then return nil
+ set sign = 0.0 > s[0]
+ ; get the start time and sample rate of the sound for use below
+ set starttime = car(snd-extent(snd, max-samples-for-zeros))
+ set srate = snd-srate(snd)
+ set n = 1
+ loop
+ until n >= len
+ set newsign = 0.0 > s[n]
+ if not(eq(sign, newsign)) then
+ set result = cons(n, result)
+ set sign = newsign
+ set n += 1
+ end
+ ; now we have the zero crossings, convert them to times
+ loop
+ with result2 = nil
+ for num in result
+ ; return the time of the zero crossing, which is the start time
+ ; of the snd plus the sample number / srate
+ set result2 = cons(starttime + num / srate, result2)
+ finally return result2
+ end
+ end
+
+
+define function ex37()
+ begin
+ ; extract a short piece of this sample
+ set short = extract(0.1, 0.14, cue(a-snd))
+ set z = zeros(short)
+ exec format(t, "Zero crossings from a-snd: ~A~%", z)
+ end
+
+
+; find the differences between zero crossings reported by zeros
+; print the result in terms of samples for readability
+;
+define function periods(lis, short)
+ begin
+ with result, prev, srate
+ if null(lis) then return nil
+ set srate = snd-srate(short)
+ loop
+ set prev = car(lis)
+ set lis = cdr(lis)
+ if null(lis) then return reverse(result)
+ set result = cons(srate * car(lis) - prev, result)
+ end
+ end
+
+define function ex38()
+ ; ex38 depends upon z, set by (ex37)
+ begin
+ if not(boundp(quote(z))) then exec ex37()
+ set p = periods(z, short)
+ exec format(t,
+ "The intervals (in samples) between zero crossings are: ~%~A~%",
+ p)
+ end
+
+
+; build a wavetable using zero crossing information
+;
+; I interactively played with the data and decided to extract from the
+; 5th period to the 21st period (these had 86 and 87 samples each and
+; seem to indicate some kind of periodicity). The 1st period measures
+; from the zeroth zero crossing to the first, so the 5th period measures
+; from the 4th zero crossing to the 5th. I'll arbitrarily take
+; the 4th and 20th zero crossing times (the 5th and 20th should work as
+; well), and from the data, this looks like 2 waveform periods.
+; This is very clear if you plot the data.
+;
+; arguments are:
+; snd - the sound to extract from
+; zeros - the result of (zeros snd)
+; start - the number of the starting zero crossing
+; stop - the number of the ending zero crossing
+; n - number of periods contained in the extracted sound
+;
+define function extract-table(snd, zeros, start, stop, n)
+ begin
+ with starttime, extent, hz
+ ; Start by shifting snd to time zero:
+ set starttime = car(snd-extent(snd, max-samples-for-zeros))
+ set snd = cue(snd) @ - starttime
+
+ exec format(t, "~A~%", snd)
+ ; also get the start and stop times and shift them:
+ set start = nth(start, zeros) - starttime
+ set stop = nth(stop, zeros) - starttime
+
+ exec format(t, "table ~A start ~A stop ~A~%", snd, start, stop)
+
+ ; now extract the samples of interest, note that we are
+ ; overwriting our pointer to the snd argument
+ set snd = extract(start, stop, cue(snd))
+ exec format(t, "table now ~A~%", snd)
+
+ ; now we need to figure out the pitch this sound would represent
+ ; when played at its samplerate. The pitch in hz is 1 / duration,
+ ; and duration is the extent of the sound / n. Therefore, take
+ ; n/extent
+ set extent = snd-extent(snd, max-samples-for-zeros)
+ set hz = n / (cadr(extent) - car(extent))
+ ; an osc table is a list of the sound, pitch number, and T (periodic)
+ return list(snd, hz-to-step(hz), #t)
+ end
+
+
+define function ex39()
+ begin
+ ; try it out
+ set *a-voice* = extract-table(short, z, 4, 20, 2)
+ ; now use the table with an oscillator
+ play osc(c3, 1.0, *a-voice*)
+ end
+
+
+define function ex40()
+ ; play it at its normal pitch
+ play osc(cadr(*a-voice*), 1.0, *a-voice*)
+
+
+define function ex41()
+ play noise()
+
+
+define function ex42()
+ play lp(noise(), 1000.0)
+
+
+define function ex43()
+ play hp(noise(), 1000.0) * 0.5
+
+
+; low pass sweep from 100 hz to 2000 hz
+define function ex44()
+ play lp(noise(), pwl(0.0, 100.0, 1.0, 2000.0, 1.0))
+
+
+; high pass sweep from 50 hz to 4000 hz
+define function ex45()
+ play hp(noise(), pwl(0.0, 50.0, 1.0, 4000.0, 1.0)) * 0.5
+
+
+; band pass at 500 hz, 20 hz bandwidth
+define function ex46()
+ play reson(10.0 * noise(), 500.0, 20.0, 1)
+
+
+; band pass sweep from 100 to 1000 hz, 20 hz bandwidth
+define function ex47()
+ play reson(0.04 * noise(),
+ pwl(0.0, 200.0, 1.0, 1000.0, 1.0),
+ 20.0)
+
+
+exec format(t, "\nType (ex1) through (ex47) to run these examples.\n")
+exec format(t, "See demos/stktest.lsp for more simple sound examples.\n")
+exec format(t, "\nI'm turning off Auto-normalization. See AUTONORM-ON\n")
+exec format(t, "in the documentation for an explanation:\n\n")
+exec autonorm-off()
+
+define function ex-all ()
+ begin
+ exec format(t, "Warning: turning automatic normalization feature off~%")
+ exec autonorm-off()
+ loop
+ for i from 1 to 47
+ for fn = list(intern(format(nil, "EX~A", i)))
+ exec format(t, "~A~%", fn)
+ exec eval(fn)
+ end
+ end
+
+
+exec format(t, "\n\"exec ex-all()\" in SAL or (ex-all) in Lisp will compute and play all examples for testing purposes.\n")
diff --git a/demos/examples_home.htm b/demos/examples_home.htm
new file mode 100644
index 0000000..7339a5f
--- /dev/null
+++ b/demos/examples_home.htm
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=ISO-8859-1">
+ <meta name="GENERATOR"
+ content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Nyquist Examples and Tutorials</title>
+</head>
+<body>
+<h1>
+Nyquist Examples and Tutorials</h1>
+<ul>
+ <h2><a href="arpeggiator.htm">Arpeggiator Example</a><br>
+ </h2>
+ <h2><a href="allewis/cellularautomata.htm">Cellular Automata Example</a></h2>
+ <h2>
+ <a href="distortion.htm">Distortion Tutorial</a></h2>
+ <h2>
+ <a href="fft_tutorial.htm">FFT Tutorial</a></h2>
+ <h2>
+ <a href="lpc_tutorial.htm">LPC Tutorial</a></h2>
+ <h2>
+ <a href="midi_tutorial.htm">Midi Tutorial</a></h2>
+ <h2>
+ <a href="bandfx.htm">Multiple Band Effects</a></h2>
+ <h2>
+ <a href="piano.htm">Piano Synthesizer Tutorial</a></h2>
+ <h2>
+ <a href="pitch_change.htm">Pitch Change by Resampling</a></h2>
+ <h2>
+ <a href="rhythm_tutorial.htm">Rhythmic Pattern Tutorial</a></h2>
+ <h2>
+ <a href="sequence_example.htm">Sequence Example</a></h2>
+ <h2>
+ <a href="shepard.lsp">Shepard Tones Example</a></h2>
+ <h2>
+ <a href="scratch_tutorial.htm">Vinal Scratch Tutorial</a></h2>
+ <h2>
+ <a href="voice_synthesis.htm">Voice Synthesis</a></h2>
+ <h2>
+ <a href="warble_tutorial.htm">Warble Tutorial</a></h2>
+ <h2>
+Pedro Morales' Example Files</h2>
+ <ul>
+ <h3>
+ <a href="pmorales/pjmg.lsp">Some Helper Functions:<tt> randi1,
+randi2,
+randh1, rndh2</tt></a></h3>
+ <h3>
+Simple Synthesis</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/A4.lsp">Waveform + Envelope, Modulating the
+envelope
+with noise</a></h4>
+ <h4>
+ <a href="pmorales/A5.lsp">Waveform + Envelope, Modulating the
+frequency</a></h4>
+ <h4>
+ <a href="pmorales/A6.lsp">Waveform + Envelope, Modulating the
+frequency,
+2</a></h4>
+ </ul>
+ <h3>
+Additive Synthesis</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/b1.lsp">Gong like sounds</a></h4>
+ <h4>
+ <a href="pmorales/b2.lsp">Risset's Spectral Analysis of a Chord</a></h4>
+ <h4>
+ <a href="pmorales/b3.lsp">Risset Bell</a></h4>
+ <h4>
+ <a href="pmorales/b4.lsp">Continuous pitch control by LFO</a></h4>
+ <h4>
+ <a href="pmorales/b7.lsp">Risset Tibetan</a></h4>
+ <h4>
+ <a href="pmorales/b8.lsp">Risset Drum</a></h4>
+ <h4>
+ <a href="pmorales/b9.lsp">Risset Endless</a></h4>
+ <h4>
+ <a href="pmorales/c1.lsp">Random Signals</a></h4>
+ <h4>
+ <a href="pmorales/partial.lsp">Bell</a></h4>
+ </ul>
+ <h3>
+Subtractive Synthesis</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/buzz.lsp">Buzz with Formant Filters</a></h4>
+ </ul>
+ <h3>
+Karplus-Strong Synthesis</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/d1.lsp">Simple KARPLUS-STRONG</a></h4>
+ <h4>
+ <a href="pmorales/ks.lsp">Karplus-Strong Algorithm</a></h4>
+ </ul>
+ <h3>
+FM Synthesis</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/e2.lsp">Chowning Dynamic Spectral Evolution</a></h4>
+ </ul>
+ <h3>
+Physical Modelling</h3>
+ <ul>
+ <h4>
+ <a href="pmorales/phm.lsp">Flute Physical Modelling</a></h4>
+ </ul>
+ </ul>
+</ul>
+</body>
+</html>
diff --git a/demos/fft_demo.lsp b/demos/fft_demo.lsp
new file mode 100644
index 0000000..f0e0f73
--- /dev/null
+++ b/demos/fft_demo.lsp
@@ -0,0 +1,176 @@
+;; this code is extracted from fft_tutorial.htm
+;;
+;; Roger B. Dannenberg, 2001
+;;
+;; Please see fft_tutorial.htm for more in-depth comments and explanations.
+;;
+
+(setf fft1-class (send class :new '(sound length skip)))
+
+(send fft1-class :answer :next '() '(
+ (snd-fft sound length skip nil)))
+
+(send fft1-class :answer :isnew '(snd len skp) '(
+ (setf sound snd)
+ (setf length len)
+ (setf skip skp)))
+
+(defun make-fft1-iterator (sound length skip)
+ (send fft1-class :new (snd-copy sound) length skip))
+
+;; create a 1-second sinusoid with points samples at cycles hz:
+(defun short-sine (points cycles)
+ (control-srate-abs points (lfo cycles)))
+
+(defun fft-test ()
+ (let (fft-iter)
+ ;; signal will have 4 cycles in 32 points:
+ (setf fft-iter (make-fft1-iterator (short-sine 32 4) 32 32))
+ (display "fft-test" (send fft-iter :next))))
+
+(defun ifft-test ()
+ (let (fft-iter ifft-snd)
+ (setf fft-iter (make-fft1-iterator (short-sine 32 4) 32 32))
+ (setf ifft-snd (snd-ifft 0 32 fft-iter 32 NIL))
+ (display "fft-ifft" (snd-length ifft-snd 200))
+ (display "fft-ifft" (snd-samples ifft-snd 200)) ))
+
+(defun file-fft1 (filename frame-length skip)
+ (make-fft1-iterator (s-read filename) frame-length skip))
+
+(defun play-fft1 (iterator skip)
+ (play (snd-ifft 0 *sound-srate* iterator skip NIL)))
+
+;; a convenient sound file name (change this to one of your soundfiles):
+(setf sfn "/Users/rbd/class/icm2009/sounds/talking.wav")
+
+(defun file-test () (play-fft1 (file-fft1 sfn 512 512) 512))
+
+
+(setf fft-hp-class (send class :new '(source bins)))
+
+(send fft-hp-class :answer :next '() '(
+ (let ((frame (send source :next)))
+ (cond (frame
+ (dotimes (i bins)
+ (setf (aref frame i) 0.0))))
+ frame)))
+
+(send fft-hp-class :answer :isnew '(s b) '(
+ (setf source s)
+ (setf bins b)))
+
+(defun make-fft-hp (source bins)
+ (send fft-hp-class :new source bins))
+
+(defun hp-test ()
+ (play-fft1 (make-fft-hp (file-fft1 sfn 512 512) 11) 512))
+
+(defun fm-tone (step mi1 mi2 mi3)
+ (let ((hz (step-to-hz step)))
+ (setf mi1 (* mi1 hz))
+ (setf mi2 (* mi2 hz))
+ (setf mi3 (* mi3 hz))
+ (fmosc c4 (partial step
+ (control-srate-abs *sound-srate*
+ (pwl 0 mi1 0.5 mi2 1 mi3 1))))))
+
+(defun mod-snd (sfn)
+ ; to get duration of file, open it and look at the 6th element
+ ; of the extra return values in *rslt*
+ (stretch (nth 6 (progn (s-read sfn) *rslt*))
+ (sum
+ (fm-tone c3 15 20 15) ;; adjust FM parameters here
+ (fm-tone d3 15 20 15) ;; adjust FM parameters here
+ (fm-tone e3 15 20 15)))) ;; adjust FM parameters here
+
+(setf fft-modulator-class (send class :new '(src1 src2)))
+
+(send fft-modulator-class :answer :isnew '(s1 s2) '(
+ (setf src1 s1)
+ (setf src2 s2)))
+
+(send fft-modulator-class :answer :next '() '(
+ (let ((frame1 (send src1 :next))
+ (frame2 (send src2 :next))
+ n half_n)
+ (cond ((and frame1 frame2)
+ ; multiply frame2 by the amplitude coefficients of frame1
+ (setf (aref frame2 0) (* (aref frame2 0) (aref frame1 0))) ;; DC
+ (setf n (- (length frame1) 1))
+ ; Subtracted 1 because we already took care of DC component
+ (setf half_n (/ n 2)) ; integer divide
+ (dotimes (i half_n)
+ (let* ((i2 (+ i i 2))
+ (i2m1 (- i2 1))
+ (amp (sqrt (+ (* (aref frame1 i2m1) (aref frame1 i2m1))
+ (* (aref frame1 i2) (aref frame1 i2))))))
+ (setf (aref frame2 i2m1) (* (aref frame2 i2m1) amp))
+ (setf (aref frame2 i2) (* (aref frame2 i2) amp))))
+ (cond ((= n (+ half_n half_n 2)) ;; n is even -> nyquist component
+ (setf (aref frame2 n) (* (aref frame2 n) (aref frame1 n)))))
+ frame2)
+ (t nil)))))
+
+(defun make-fft-modulator (src1 src2)
+ (send fft-modulator-class :new src1 src2))
+
+(defun mod-test ()
+ (let ((fs 512)) ;; frame size
+ (play-fft1 (make-fft-modulator
+ (file-fft1 sfn fs fs)
+ (make-fft1-iterator (mod-snd sfn) fs fs))
+ fs)))
+
+(defun raised-cosine ()
+ (scale 0.5
+ (sum (const 1)
+ (lfo (/ 1.0 (get-duration 1)) 1 *sine-table* 270))))
+
+(defun fft-window (frame-size)
+ (control-srate-abs frame-size (raised-cosine)))
+
+(defun play-fft (iterator frame-size skip)
+ (play (snd-ifft 0 *sound-srate* iterator
+ skip (fft-window frame-size))))
+
+
+(defun mod-test-w ()
+ (let ((fs 512)) ;; frame size
+ (play-fft (make-fft-modulator
+ (file-fft1 sfn fs (/ fs 2))
+ (make-fft1-iterator (mod-snd sfn) fs (/ fs 2)))
+ fs (/ fs 2))))
+
+
+(setf fft-class (send class :new '(sound length skip window)))
+
+(send fft-class :answer :next '() '(
+ (snd-fft sound length skip window)))
+
+(send fft-class :answer :isnew '(snd len skp) '(
+ (setf sound snd)
+ (setf length len)
+ (setf skip skp)
+ (setf window (fft-window len)) ))
+
+(defun make-fft-iterator (sound length skip)
+ (send fft-class :new (snd-copy sound) length skip))
+
+(defun file-fft (filename frame-length skip)
+ (make-fft-iterator (s-read filename) frame-length skip))
+
+(defun mod-test-ww ()
+ (let ((fs 512)) ;; frame size
+ (play-fft (make-fft-modulator
+ (file-fft sfn fs (/ fs 2))
+ (make-fft-iterator (mod-snd sfn) fs (/ fs 2)))
+ fs (/ fs 2))))
+
+(defun mod-test-wws ()
+ (let ((fs 1024)) ;; frame size
+ (play-fft (make-fft-modulator
+ (file-fft sfn fs (/ fs 16))
+ (make-fft1-iterator (mod-snd sfn) fs (/ fs 16)))
+ fs (/ fs 2))))
+
diff --git a/demos/fft_tutorial.htm b/demos/fft_tutorial.htm
new file mode 100644
index 0000000..08cc91b
--- /dev/null
+++ b/demos/fft_tutorial.htm
@@ -0,0 +1,553 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
+<title>Nyquist FFT and Inverse FFT Tutorial</title>
+</head>
+
+<body>
+
+<h1>Nyquist FFT and Inverse FFT Tutorial</h1>
+
+<p>Nyquist provides functions for FFT and inverse FFT operations on streams of audio data.
+Because sounds can be of any length, but an FFT operates on a fixed amount of data, FFT
+processing is typically done in short blocks or windows that move through the audio. Thus,
+a stream of samples is converted in to a sequence of FFT frames representing short-term
+spectra. </p>
+
+<p>Nyquist does not have a special data type corresponding to a sequence of FFT frames.
+This would be nice, but it would mean creating a large set of operations suitable for
+processing frame sequences. Another approach, and perhaps the most &quot;pure&quot; would
+be to convert a single sound into a multichannel sound, with one channel per bin of the
+FFT. </p>
+
+<p>Instead, Nyquist violates its &quot;pure&quot; functional model and resorts to objects
+for FFT processing. A sequence of frames is represented by an XLISP object. Whenever you
+send the selector <tt>:next</tt> to the object, you get back either NIL, indicating the
+end of the sequence, or you get an array of FFT coefficients. </p>
+
+<p>The Nyquist function FFT (mnemonic, isn't it?) returns one of the frame sequence
+generating objects. You can pass any frame sequence generating object to another function,
+IFFT, and turn the sequence back into audio. </p>
+
+<p>With&nbsp; FFT and IFFT, you can create all sorts of interesting processes. The main
+idea is to create intermediate objects that both accept and generate sequences of frames.
+These objects can operate on the frames to implement the desired spectral-domain
+processes. Examples of this will follow, but first, let's try something simpler. </p>
+
+<h2>Simple FFT Example</h2>
+<p>[<i>Special thanks to James Valenti for detailed comments and explanations
+ about this code. -RBD</i>]</p>
+
+<p>Just to convince ourselves that this works and to explore the FFT function, let's
+perform an FFT on a sinusoid. To make the outcome predictable, we will use 32 samples of
+sinusoid with a period of 8 samples. If we take a 32-point FFT, the spectrum should show a
+strong 4th harmonic (there are 4 8-sample periods) and zero everywhere else. </p>
+
+<p>Before the test, we will introduce a simple function to create an FFT sequence
+ generating object, which is called an iterator: The function is called <tt>make-fft1-iterator</tt>,
+ and creates an object of class <tt>fft1-class</tt> (I am using <tt>fft1</tt>
+ rather than <tt>fft</tt> because this is a simplified version that will be improved
+ later). Objects of this class will have the fields <tt>sound</tt>, <tt>length</tt>,
+ and <tt>skip</tt>. Create the class by sending <tt>class</tt> (the super class
+ of all classes) a <tt>:new</tt> message to create a new class that will be a
+ sub-class of <tt>class</tt>:</p>
+
+<pre>(setf fft1-class (send class :new '(sound length skip)))
+</pre>
+Add a method named :next to the <tt>fft1-class</tt>. The method will have a formal
+argument list of <tt>()</tt> and the code body of <tt>(snd-fft sound length skip
+nil)</tt>, so this is simply a wrapper for calling <tt>snd-fft</tt> which has
+takes as parameters: the source sound, the fft length, the number of samples to
+advance for each fft, and the sound to use as a window function (in this case,
+no windowing is indicated by <tt>nil</tt>.) Each time <tt>snd-fft</tt> is called,
+it will advance by <tt>skip</tt> to the next set of samples. The function (and
+thus the <tt>:next</tt> method) will return an array containing the results of
+the next short-time fft:
+<pre>
+(send fft1-class :answer :next '() '(
+&nbsp;&nbsp;&nbsp; (snd-fft sound length skip nil)))
+</pre>
+Add a method named <tt>:isnew</tt> to the <tt>fft1-class</tt>. This is a
+"standard" method that is called automatically to initialize a new object
+of the class when the <tt>:new</tt> method is sent to the class. Any
+parameters sent to <tt>:new</tt> are passed on to <tt>:isnew</tt>, and in
+this case the formal parameter list is <tt>(snd len skp)</tt> and the body
+of the function is three <tt>setf</tt>'s that copy the parameters into the
+fields (or instance variables) of the new object, which are named
+<tt>sound</tt>, <tt>length</tt>, and <tt>skip</tt>:
+
+<pre>
+(send fft1-class :answer :isnew '(snd len skp) '(
+&nbsp;&nbsp;&nbsp; (setf sound snd)
+&nbsp;&nbsp;&nbsp; (setf length len)
+&nbsp;&nbsp;&nbsp; (setf skip skp)))
+</pre>
+Make a new function named <tt>make-fft1-iterator</tt>
+to create an <tt>fft1-iterator</tt> with the parameters
+<tt>sound</tt>, <tt>length</tt>, and <tt>skip</tt>. The
+function makes a new object by sending the <tt>:new</tt>
+message to the <tt>fft1-class</tt>. Because <tt>fft1-class</tt>
+consumes the sound (by calling <tt>snd-fft</tt>), this function
+copies the sound with <tt>snd-copy</tt> to avoid any unexpected
+side effects on the <tt>sound</tt> parameter.
+<pre>
+(defun make-fft1-iterator (sound length skip)
+&nbsp; (send fft1-class :new (snd-copy sound) length skip))</pre>
+
+<p>For test data, create a sinusoid. <tt>lfo</tt> generates a
+one second sinusoid.
+The <tt>control-srate-abs</tt> transformation changes the sample rate
+generated by the <tt>lfo</tt> to <tt>points</tt> and since the duration
+is one second, there will be exactly <tt>points</tt> samples
+generated. The <tt>cycles</tt> parameter is the frequency of the
+sinusoid, so a value of 1 will generate one cycle (in one second) and
+a value of 2 will generate 2 cycles in one second, etc.</p>
+
+<pre>;; create a 1-second sinusoid with points samples at cycles hz:
+(defun short-sine (points cycles)
+&nbsp; (control-srate-abs points (lfo cycles)))
+</pre>
+In the <tt>fft-test</tt> function, the <tt>let</tt> introduces a list of
+local variables (just <tt>fft-iter</tt in this case)
+that exist until the function returns. If there is a
+global variable also named ><tt>fft-iter</tt>, it will be ignored by this
+function. Inside the <tt>let</tt>, <tt>fft-iter</tt> is set to a newly
+created instance of <tt>fft1-iterator</tt>, initialized with a signal
+that has 4 cycles of a sinusoid in 32 points, with an fft length of 32
+samples and a skip of 32 samples (zero overlap):
+<pre>
+(defun fft-test ()
+&nbsp; (let (fft-iter)
+&nbsp;&nbsp;&nbsp; ;; signal will have 4 cycles in 32 points:
+&nbsp;&nbsp;&nbsp; (setf fft-iter (make-fft1-iterator (short-sine 32 4) 32 32))
+&nbsp;&nbsp;&nbsp; (display &quot;fft-test&quot; (send fft-iter :next))))</pre>
+
+<p>Running this prints an array of nearly-zero values except for the 9th element (index
+8), which is -1. The layout is as follows:
+
+<ul>
+ <li>the DC component goes in array element 0</li>
+ <li>the Cosine part is in elements 2i - 1</li>
+ <li>the Sine part is in elements 2i</li>
+ <li>the Nyquist frequency component is in the last element</li>
+</ul>
+The output should look like this:
+<pre>
+> (load "fft1.lsp")
+;loading "fft1.lsp"
+;[ gc: total 20640, 3360 free; samples 12 KB, 7KB free ]
+;fft-test : (SEND FFT-ITER :NEXT) = #(1.53076e-017 0 0 0 0 0 0 -3.06152e-017
+; -1 0 0 0 0 0 0 3.06152e-017
+; 0 0 0 0 0 0 0 -3.06152e-017
+; 8.9407e-008 0 0 0 0 0 0 1.53076e-017)
+;T
+;>
+</pre>
+<p>Thus, the element at index 8 is the 4th Sine component, indicating a 4th harmonic as
+expected. </p>
+
+<h2>Simple Inverse FFT Example</h2>
+
+<p>Now, let's try to reverse the FFT and recover the sinusoid. We will use the
+ <tt>snd-ifft</tt> function, which takes five parameters:
+<ul>
+ <li>the starting time of the resulting sound</li>
+ <li>the sample rate of the resulting sound</li>
+ <li>the iterator object, which will be called to obtain short term spectra (frames)</li>
+ <li>the step-size, how many samples to advance for each frame</li>
+ <li>the window (or NIL), by which each frame is multiplied after the IFFT</li>
+</ul>
+<p>The result returned from snd-ifft is a sound which is assigned here to local
+ variable ifft-snd. In this case, the sound will have a start time of 0, a sample
+ rate of 32, the spectral frames (actually just one frame) will be obtained by
+ sending the <tt>:next</tt> message to <tt>fft-iter</tt>, the skip between successive
+ frames is 32, and no windowing is applied.</p>
+<pre>(defun ifft-test ()
+&nbsp; (let (fft-iter ifft-snd)
+&nbsp;&nbsp;&nbsp; (setf fft-iter (make-fft1-iterator (short-sine 32 4) 32 32))
+&nbsp;&nbsp;&nbsp; (setf ifft-snd (snd-ifft 0 32 fft-iter 32 NIL))
+&nbsp;&nbsp;&nbsp; (display &quot;fft-ifft&quot; (snd-length ifft-snd 200))
+&nbsp;&nbsp;&nbsp; (display &quot;fft-ifft&quot; (snd-samples ifft-snd 200))
+ ifft-snd )) ; return the sound</pre>
+
+<p>Now call the function:</p>
+<pre>(ifft-test)</pre>
+<p>Looking at the printed samples, you can see that the result is a close approximation
+ to the expected sinusoid. Since <tt>ifft-test</tt> returns a sound, you can
+ call<tt> (play (ifft-test))</tt>, but in this case you won't hear much because
+ the sound is only 32 samples, and there may also be problems trying to play
+ a sound that is only sampled at 32 samples per second.</p>
+
+<p><b>Exercise: </b>Modify <tt>short-sine</tt> to produce a cosine and observe the
+difference in the FFT. Confirm that the IFFT reproduces the original cosine. (Hint: the
+parameters to <tt>LFO</tt> should be: <tt>(lfo cycles 1.0 *sine-table* 90.0)</tt>,
+indicating frequency, duration, the waveform, and the initial phase, respectively.) <br>
+&nbsp; </p>
+
+<h2>Sequence of FFT Frames</h2>
+
+<p>Let's create an FFT iterator that reads sounds from a file. This is similar
+ to what was done before, but here, <tt>s-read</tt> is used to read samples instead
+ of using <tt>lfo</tt> to compute samples: </p>
+
+<pre>(defun file-fft1 (filename frame-length skip)
+&nbsp; (make-fft1-iterator (s-read filename) frame-length skip))</pre>
+
+<p>And here is a function to recover the sound file from spectral frames and play
+ it. The sound will start at time 0, at the sample rate <tt>*sound-srate*</tt>,
+ using <tt>iterator</tt> to generate successive spectral frames, advancing <tt>skip</tt>
+ samples between fft's, and no windowing. Note: <tt>*sound-srate*</tt> is a global
+ variable from Nyquist that is the default sample rate for sounds. It can be
+ read directly, but you should only modify it by calling <tt>sound-srate-abs</tt>:</p>
+
+<pre>(defun play-fft1 (iterator skip)
+&nbsp; (play (snd-ifft 0 *sound-srate* iterator skip NIL)))</pre>
+
+<p>Define a filename for testing. Remember that the backslash (<tt>\</tt>) character
+ is the <i>escape</i> character for XLisp strings, so you need to type two backslashes
+ to denote one backslash character. Windows will also accept forward slashes
+ (<tt>/</tt>) as a separator, and the forward slash does not need to be escaped.
+ Be sure to test this with a mono file at the default sample rate of 44100:</p>
+
+<pre>;; a convenient sound file name (change this to one of your mono soundfiles):
+(setf sfn &quot;D:\\brain\\outro\\soup.wav&quot;)
+</pre>
+Define a function to call <tt>play-fft1</tt> using <tt>sfn</tt> as the input function
+for analysis, a frame length (fft size) of 512, and a skip size of 512 (no overlap).
+The start time (0), sample rate (<tt>*sound-srate*</tt>) and windowing function
+(none) are hard-coded in <tt>play-fft1</tt>.
+<pre>(defun file-test () (play-fft1 (file-fft1 sfn 512 512) 512))</pre>
+
+<p>If you do not hear your original file, try playing the original file by typing
+ <tt>(play-file sfn)</tt>, and make sure the file is a mono file at 44,100 Hz
+ sample rate (to match <tt>*sound-srate*</tt> used in <tt>play-fft1</tt>). Check
+ out the file by typing <tt>(sf-info sfn)</tt>.</p>
+<p>You can try different skip parameters, e.g. to play the sound at double speed,
+ try this:</p>
+<pre>(play-fft1 (file-fft1 sfn 512 512) 256)</pre>
+<h2>XLisp and Garbage Collection</h2>
+<p>In the previous example, you may have noticed a lot of messages that look something
+like the following:</p>
+
+<pre>[ gc: total 18640, 3114 free; samples 49KB, 39KB free ]</pre>
+
+<h3>What the gc: Messages Mean</h3>
+
+<p>These messages are printed whenever the garbage collector runs to reclaim memory that
+was allocated but is no longer in use by the program. The memory found by the garbage
+collector is reused in future computation to avoid allocating more memory than is
+necessary. The particular message here says that 18640 &quot;cells&quot; have been
+allocated. Each cell is 10 bytes, so there are 186,400 bytes, or about 186KB used to store
+XLisp programs and data. This does not include the XLisp interpreter, Nyquist functions,
+and system libraries, that take an additional 500KB or so. It also does not include audio
+samples, which are stored separately. Of the 18640 cells, 3114 were free after garbage
+collection. Of the 49KB of audio data (samples) allocated by Nyquist, 39KB were free for
+reuse after after garbage collection.</p>
+
+<h3>Making GC More Effective</h3>
+
+<p>Nyquist and XLisp do a pretty good job of effective, automatic garbage collection, but
+since XLisp was designed to run on small machines, it favors using a minimal amount of
+memory, and this may result in frequent garbage collections. FFT processing, in
+particular, makes heavy use of XLisp, since every floating point number in every FFT frame
+requires the allocation of a 10-byte cell. When you are processing with FFTs, you can
+often gain some speed by telling XLisp to allocate more memory cells. Do this by calling <tt>expand</tt>:</p>
+
+<pre>(expand 100)</pre>
+
+<p>The parameter tells how many additional internal blocks of memory to allocate. Each
+block is 2000 cells, or about 20KB, so if the parameter is 100, you will allocate about
+2MB. After allocating memory, the next garbage collection might look like:</p>
+
+<pre>[ gc: total 218640, 204298 free; samples 49KB, 44KB free ]</pre>
+
+<p>Notice that now, garbage collection frees a higher proportion of memory than before
+&nbsp; (204298 out of 218640 cells). Garbage collection is more efficient when there is a
+higher proportion of memory to free.</p>
+
+<p>On the other hand, you should not allocate more memory than necessary. If you allocate
+too much, parts of Nyquist and other programs will be paged out of RAM and onto your disk
+drive. Since Nyquist must access all of its memory for every garbage collection, it is
+very inefficient to have any of that memory reside on disk.</p>
+
+<p>Should you always expand memory? Almost all non-FFT audio processing uses special data
+structures that are outside of XLisp and are managed without the use of the garbage
+collector. Since audio processing normally takes over 95% of the execution time, you
+normally do not have to worry much about the efficiency of XLisp.</p>
+
+<h2>Simple Spectral Processing</h2>
+
+<p>The main purpose of FFT and IFFT functions is to enable processing in the spectral
+ domain. Let's create a very simple example in which certain frequencies are
+ set to zero, creating a filter effect. (Note that this is not a very good way
+ to create filters because of boundary effects.) We need to create an object
+ that will access an FFT iterator to get frames, and that will serve as an iterator
+ to deliver frames. The code is as follows: </p>
+
+<pre>(setf fft-hp-class (send class :new '(source bins)))
+
+(send fft-hp-class :answer :next '() '(
+ ; get a new frame of fft coefficients from source
+ (let ((frame (send source :next))) ; creates local variable - frame
+ ; a note about let:
+ ; the first list after let names new local variables
+ ; the following lists (below) are expressions to be evaluated
+ ;
+ ; if frame is nil, there are no more frames to process
+&nbsp;&nbsp;&nbsp; (cond (frame
+ ; if frame is not nil, then do the following
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dotimes (i bins)
+ ; set all the bins from 0 to bins-1 (these are low frequency bins) to zero
+ ; the order of coefficients is:
+ ; DC coefficient
+ ; first real
+ ; first imaginary
+ ; second real
+ ; second imaginary
+ ; ...
+ ; if the length is even, then last is the real
+ ; coefficient of the Nyquist frequency
+ ;
+ ; (Note: aref gets the ith element of the array)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf (aref frame i) 0.0)))) ; end of cond
+&nbsp;&nbsp;&nbsp; frame))) ; frame is the last expression of the let, so it is the return value
+</pre>
+Create an <tt>fft-hp-class</tt> method called <tt>:isnew</tt> to initialize the
+<tt>fft-hp-class</tt> class variables <tt>source</tt> and <tt>bins</tt>. The <tt>source</tt>
+will be a <tt>file-fft</tt>.
+<p>A refresher as to what goes on with <tt>file-fft</tt>: <tt>file-fft1</tt> reads a file
+into a sound variable and calls <tt>make-fft1-iterator</tt>. Then
+<tt>make-fft1-iterator</tt> returns an <tt>fft-1</tt> class by sending
+<tt>fft1-class :new</tt> with a copy of the sound. It makes this copy because
+it will have <tt>skip</tt> samples removed every invocation of
+<tt>fft1-class:next</tt> because this method calls <tt>snd-fft</tt> which
+removes the samples every time a new fft frame is calculated.
+<pre>
+(send fft-hp-class :answer :isnew '(s b) '(
+&nbsp;&nbsp;&nbsp; (setf source s)
+&nbsp;&nbsp;&nbsp; (setf bins b)))
+</pre>
+This is a function to make and return an instance of the <tt>fft-hp-class</tt>
+class.
+<pre>
+(defun make-fft-hp (source bins)
+ ; Send the fft-hp-calss a :new message to create a new instance of the class
+ ; and to initialize the instance with the values of source and bins
+ ; Returns an object that responds to the :next message by getting the next
+ ; fft frame, zeroing the low frequencies, and returning the frame.
+&nbsp; (send fft-hp-class :new source bins))
+</pre>
+In <tt>play-fft1</tt>, fft frames from <tt>make-fft-hp</tt> are converted
+back into audio. The audio is reconstructed using a skip of 512.
+<pre>
+(defun hp-test ()
+&nbsp; (play-fft1 (make-fft-hp (file-fft1 sfn 512 512) 11) 512))</pre>
+
+<p>Note that <tt>make-fft-hp</tt> takes a parameter, bins, that tells how many
+coefficients of the FFT to zero. At 44,100 Hz, the frame rate is 44100/512 = 86.13 Hz, and
+this corresponds to the first bin (coefficients at locations 1 and 2). Since we specified
+11 for the bins parameter, this will zero the DC component and 5 complex pairs,
+representing frequencies up to 86.12 * 5 = 430.7 Hz. (If you are trying this on a laptop
+computer with small speakers, or if you are using a sound without low frequencies, you may
+want to increase the number of bins in <tt>hp-test</tt> from 11 to 30 to make the effect
+really obvious.)</p>
+
+<p>You will notice some raspy sounds in the output. Since the FFT frames are not smoothed
+by any window or overlapped, there are serious windowing artifacts that are easily heard.
+We will look at ways to reduce this problem later. </p>
+
+<h2>Spectral Modulation</h2>
+
+<p>An interesting effect is to let one spectrum modulate another one. By multiplying the
+amplitude spectrum of one signal onto that of another, one can superimpose the two
+signals. (Note that adding spectra is simply a way to mix them and is equivalent to
+addition in the time domain.) </p>
+
+<p>Let's create a bright FM sound to serve as a spectral modulation &quot;carrier&quot;.
+First, create the FM sound. This sound has an initial, middle, and fiinal modulation index
+as well as a (constant) pitch:</p>
+
+<pre>(defun fm-tone (step mi1 mi2 mi3)
+&nbsp; (let ((hz (step-to-hz step)))
+&nbsp;&nbsp;&nbsp; (setf mi1 (* mi1 hz))
+&nbsp;&nbsp;&nbsp; (setf mi2 (* mi2 hz))
+&nbsp;&nbsp;&nbsp; (setf mi3 (* mi3 hz))
+&nbsp;&nbsp;&nbsp; (fmosc c4 (partial step&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (control-srate-abs *sound-srate*&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (pwl 0 mi1 0.5 mi2 1 mi3 1))))))</pre>
+
+<p>The modulated sound will be a cluster of three FM tones. You could use just one tone,
+but I have had better luck with chords or noise. You want to make sure the signal has
+plenty of amplitude at many frequencies; otherwise, the spectral modulation will not have
+anything to modulate.</p>
+
+<pre>(defun mod-snd ()
+ (sum
+ (fm-tone c3 15 20 15) ;; adjust FM parameters here
+ (fm-tone d3 15 20 15) ;; adjust FM parameters here
+ (fm-tone e3 15 20 15))) ;; adjust FM parameters here</pre>
+
+<p>Next, we need a class to do the modulation. As before, objects of this class respond to
+the <tt>:next </tt>message. In this case, the <tt>:next</tt> method sends&nbsp; <tt>:next</tt>
+to both sources. It then multiplies the coefficients of one by the computed amplitude
+spectrum of the other. </p>
+
+<pre>(setf fft-modulator-class (send class :new '(src1 src2)))
+
+(send fft-modulator-class :answer :isnew '(s1 s2) '(
+&nbsp;&nbsp;&nbsp; (setf src1 s1)
+&nbsp;&nbsp;&nbsp; (setf src2 s2)))
+
+(send fft-modulator-class :answer :next '() '(
+&nbsp; (let ((frame1 (send src1 :next))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (frame2 (send src2 :next))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n half_n)
+&nbsp;&nbsp;&nbsp; (cond ((and frame1 frame2)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; multiply frame2 by the amplitude coefficients of frame1
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf (aref frame2 0) (* (aref frame2 0) (aref frame1 0))) ;; DC
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf n (- (length frame1) 1))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Subtracted 1 because we already took care of DC component
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf half_n (/ n 2)) ; integer divide
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dotimes (i half_n)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (let* ((i2 (+ i i 2))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (i2m1 (- i2 1))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (amp (sqrt (+ (* (aref frame1 i2m1) (aref frame1 i2m1))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (* (aref frame1 i2)&nbsp;&nbsp; (aref frame1 i2))))))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf (aref frame2 i2m1) (* (aref frame2 i2m1) amp))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf (aref frame2 i2) (* (aref frame2 i2) amp))))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cond ((= n (+ half_n half_n 2)) ;; n is even -&gt; nyquist component
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf (aref frame2 n) (* (aref frame2 n) (aref frame1 n)))))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; frame2)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (t nil)))))
+
+(defun make-fft-modulator (src1 src2)
+&nbsp; (send fft-modulator-class :new src1 src2))</pre>
+
+<p>The code for&nbsp; <tt>:next</tt> is longer than you might expect, but it is basically
+just a vector multiplication. Lisp is not ideal for numerical algorithms like this. The
+following code will test the new class: </p>
+
+<pre>(defun mod-test ()
+&nbsp; (let ((fs 512)) ;; frame size
+&nbsp;&nbsp;&nbsp; (play-fft1 (make-fft-modulator&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (file-fft1 sfn fs fs)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (make-fft1-iterator (mod-snd) fs fs))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs)))</pre>
+
+<p>Here, we pass in iterators for the sound stored in a file and for the modulated sound.
+This example seems to work best if the sound in the file is a voice. You can also try
+stretching the speech by reducing the step parameter to <tt>file-fft</tt> and by making
+the modulated sound longer. You might also try different sizes of FFTs using the frame
+size (<tt>fs</tt>) parameter. If the FFT frame size is too big, you will resolve
+individual harmonics of the voice, and if it is too small, you will not resolve formants.
+256 and 512 seem to be good numbers when working at 44,100 Hz sampling rates.</p>
+
+<h2>Smoothing Windows</h2>
+
+<p>In the previous examples, and especially in the last one, a lot of buzzing and noise is
+created because the boundaries of the FFT frames are no longer continuous when the
+spectrum is altered. To reduce the buzzing effect, we can multiply the frame by a
+smoothing window before reconstructing the time domain signal. We can also use a smoothing
+window on the input side, before taking the FFT. For now, we will try just a smoothing
+window on the IFFT side. </p>
+
+<p>The smoothing window will be a raised cosine pulse, although other window shapes could
+be used. The following code implements a raised cosine. (A raised cosine is a smooth
+bell-shaped curve that rises from zero to 1 and back again. The curve is one period of a
+sinusoid or cosine, but &quot;raised&quot; so that its minimum value is at zero.) The lfo
+function computes a sine curve, so we use an initial phase of 270 degrees to get the
+proper shape: </p>
+
+<pre>(defun raised-cosine ()
+&nbsp; (scale 0.5&nbsp;
+&nbsp;&nbsp;&nbsp; (sum (const 1)&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lfo (/ 1.0 (get-duration 1)) 1 *sine-table* 270))))</pre>
+
+<p>Next, we need a function to create a window of the proper length. The sample rate of
+the window does not matter because the FFT and IFFT functions will simply take the proper
+number of samples (without any interpolation or resampling). Therefore, we will use the <tt>frame-size</tt>
+as the sample rate, insuring that there are <tt>frame-size</tt> samples: </p>
+
+<pre>(defun fft-window (frame-size)
+&nbsp; (control-srate-abs frame-size (raised-cosine)))</pre>
+
+<p>Now we can pass in a window to the IFFT. Let's redo the spectral modulation example
+with smoothing windows on the IFFT side. First, we will rewrite <tt>play-fft</tt> to use
+windowing: </p>
+
+<pre>(defun play-fft (iterator frame-size skip)
+&nbsp; (play (snd-ifft 0 *sound-srate* iterator&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; skip (fft-window frame-size))))</pre>
+
+<p>Now, we can rewrite <tt>mod-test:</tt> </p>
+
+<pre>(defun mod-test-w ()
+&nbsp; (let ((fs 512)) ;; frame size
+&nbsp;&nbsp;&nbsp; (play-fft (make-fft-modulator&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (file-fft1 sfn fs (/ fs 2))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (make-fft1-iterator (mod-snd) fs (/ fs 2)))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs (/ fs 2))))</pre>
+
+<p>Notice that we reduced the step size to half the frame size. This is because we want
+the windows to overlap by 50%, creating a nice cross-fade from one frame to the next. </p>
+
+<p>You might guess that the square windowing on the analysis (FFT) side is injecting high
+frequencies into the spectrum. We can introduce windowing there too. We can modify <tt>make-fft-iterator</tt>
+to use a window. This will require changes to <tt>fft1-class</tt>, so we will use the name
+<tt>fft-class:</tt> </p>
+
+<pre>(setf fft-class (send class :new '(sound length skip window)))
+
+(send fft-class :answer :next '() '(
+&nbsp;&nbsp;&nbsp; (snd-fft sound length skip window)))
+
+(send fft-class :answer :isnew '(snd len skp) '(
+&nbsp;&nbsp;&nbsp; (setf sound snd)
+&nbsp;&nbsp;&nbsp; (setf length len)
+&nbsp;&nbsp;&nbsp; (setf skip skp)
+&nbsp;&nbsp;&nbsp; (setf window (fft-window len)) ))
+
+(defun make-fft-iterator (sound length skip)
+&nbsp; (send fft-class :new (snd-copy sound) length skip))</pre>
+
+<p>Now, we can rewrite <tt>file-fft</tt> to use windowing: </p>
+
+<pre>(defun file-fft (filename frame-length skip)
+&nbsp; (make-fft-iterator (s-read filename) frame-length skip))</pre>
+
+<p>Now, we can rewrite <tt>mod-test</tt> yet again: </p>
+
+<pre>(defun mod-test-ww ()
+&nbsp; (let ((fs 512)) ;; frame size
+&nbsp;&nbsp;&nbsp; (play-fft (make-fft-modulator&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (file-fft sfn fs (/ fs 2))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (make-fft-iterator (mod-snd) fs (/ fs 2)))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs (/ fs 2))))</pre>
+
+<p>This version seems to have less definition for speech input than the previous one. It
+might be that some windowing artifacts in the right places are actually beneficial! In
+fact, some simple experiments indicate that, in this example, the speech sounds better
+when the (mod-snd) sound is analyzed without windowing. This probably creates more noise
+to be modulated by the speech signal, so more speech information gets through. </p>
+
+<p>We can also stretch the result by taking smaller steps during the analysis (FFT) stage
+so that more frames are generated. I will also increase the frame size to obtain fewer
+frames/second. </p>
+
+<pre>(defun mod-test-wws ()
+&nbsp; (let ((fs 1024)) ;; frame size
+&nbsp;&nbsp;&nbsp; (play-fft (make-fft-modulator&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (file-fft sfn fs (/ fs 16))
+ (make-fft1-iterator (mod-snd) fs (/ fs 16)))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs (/ fs 2))))</pre>
+
+<h2>Acknowledgments</h2>
+
+<p>Cort Lippe and Zack Settel have explored cross synthesis and other effects with FFTs
+extensively, and their work inspired these examples.</p>
+</body>
+</html>
+
diff --git a/demos/largeclip.jpg b/demos/largeclip.jpg
new file mode 100644
index 0000000..6b745e9
--- /dev/null
+++ b/demos/largeclip.jpg
Binary files differ
diff --git a/demos/lpc-exmpl.dat b/demos/lpc-exmpl.dat
new file mode 100644
index 0000000..66332d3
--- /dev/null
+++ b/demos/lpc-exmpl.dat
@@ -0,0 +1,162 @@
+(0.0205328 0.000539653 0.162119 #(0.0172437 -0.00206371 0.0199834 0.0140023 -0.107106 0.105376 -0.014147 -0.0456254 -0.035733 0.000526876 0.024559 -0.077979 0.0379572 0.0550832 0.0251978 -0.0158793 0.000201547 0.0183836 0.0120267 -0.0145289 0.0270053 0.0215023 -0.0674045 0.0868633 -0.0759818 0.0123872 -0.100426 0.0670379 0.153223 -0.160887 0.0200027 0.00857184 -0.0319345 0.0372642 -0.039906 0.0370124 -0.0406953 0.0916241 -0.0794324 0.0994091 -0.152256 0.122422 -0.131096 0.143904 -0.182573 0.107067 -0.216319 0.338997 -0.171402 1.04299))
+(0.0746031 0.000883533 0.108826 #(0.043002 -0.0168565 0.0116234 -0.031321 -0.0728684 0.134856 0.0052372 -0.0477521 -0.0767405 0.0307031 0.00286882 -0.0188694 -0.0103552 0.0410824 -0.00991496 0.0129631 -0.0070764 0.0446677 -0.0316206 0.0103328 -0.00314631 0.0721652 -0.028264 0.0429488 -0.0757499 0.0355948 -0.124679 0.0341884 0.147169 -0.115948 0.0350534 -0.022784 0.00255128 0.000132609 0.00266292 0.0235752 -0.0270638 0.00319338 -0.0405898 0.0510949 -0.0525406 0.112875 -0.120262 0.103579 -0.140658 0.030511 -0.195171 0.226418 -0.194436 1.19625))
+(7.90651 0.00254103 0.0179272 #(0.0298438 -0.0150177 0.00856811 0.00178307 -0.156251 0.141521 0.0377321 -0.00862076 0.0358013 -0.0526648 -0.0746482 0.0176761 0.0180553 0.0110547 -0.0149859 -0.00274912 0.00753696 0.0570906 -0.00985159 -0.0460384 -0.0312089 0.0275762 -0.00179828 0.0498972 -0.0462076 0.111785 -0.101277 -0.0429219 0.135046 -0.118618 0.0320909 0.0152628 0.00229011 0.000619642 -0.00148223 0.0698463 -0.0192731 -0.061608 -0.105966 0.00760205 -0.0556964 0.172818 -0.0018539 0.14807 -0.115714 0.0485711 -0.341883 0.118442 -0.644804 1.76356))
+(16.8204 0.00353871 0.0145046 #(0.0242379 0.0163801 -0.0441124 0.0515951 -0.165318 0.0553254 0.118888 -0.00888211 0.0686623 -0.103195 -0.109872 0.0873954 -0.00312068 -0.0157818 0.00793753 -0.0102677 0.0385871 0.0402539 0.0275778 -0.124176 -0.0224998 -0.0083091 0.139262 -0.0326057 -0.0686154 0.152026 -0.0710961 -0.100093 0.0921394 -0.0886168 0.0962788 0.0235546 -0.0835561 0.0289921 -0.0519826 0.0819953 0.0677047 -0.04636 -0.154177 0.0188317 -0.0733893 0.18706 -0.117089 0.276443 -0.188078 0.136406 -0.348012 0.354862 -1.21044 2.05642))
+(15.7527 0.00488585 0.0176113 #(0.0410332 -0.0212341 -0.0186016 0.0139835 -0.10253 0.0317464 0.098534 0.0577219 -0.00603218 -0.119189 -0.0560336 0.0600247 0.00563636 -0.00741701 -0.022568 0.0551003 0.0172174 -0.0145449 0.0377798 -0.0774387 -0.0623132 0.0156745 0.116856 0.0167625 -0.0740776 0.0976961 -0.0589157 -0.0592283 0.0621122 -0.0668073 0.0672344 0.0433492 -0.0724394 -0.0149194 -0.0174723 0.0940844 0.0192709 -0.037947 -0.145742 0.0166333 -0.0382952 0.137928 -0.0235971 0.142885 -0.0641163 -0.0401743 -0.14418 0.182686 -1.00692 1.93978))
+(16.3531 0.0136897 0.0289333 #(-0.024896 0.016421 0.00786502 -0.0118406 0.00603457 0.0343453 0.0250988 -0.00670104 -0.0483285 -0.0402459 0.00284676 0.0223309 0.00649693 -0.0116516 0.00923614 0.0111503 -0.000440774 -0.0275555 0.00682401 -0.0125723 0.00263826 0.0153074 0.0242379 0.0142031 0.0060273 0.0192062 -0.0368178 0.00965019 0.0058204 -0.00736851 0.0414994 0.00440613 -0.0394615 -0.0217087 0.0132956 0.0116567 -0.024931 -0.0592983 -0.0327111 0.00831445 0.0282831 0.0678891 0.00450369 0.00915988 -0.0181229 -0.0469828 -0.0555707 -0.0913728 -0.228273 1.41019))
+(22.7776 0.0128829 0.0237823 #(-0.0244512 0.00852192 0.00355279 0.0100932 -0.00419528 0.0237172 0.0103759 -0.0137028 -0.0251104 -0.0134613 -0.000615256 0.00165147 -0.00407305 -0.00344569 -0.00120993 0.0089017 0.000495352 -0.000238208 0.00294549 0.00112805 0.00425276 0.0266437 0.0165051 -0.0296654 -0.00157895 0.0406957 -0.0203225 0.000875471 0.0187371 -0.00604564 0.0124178 0.00848914 -0.00870932 -0.0345038 -0.0166086 -0.00777551 -0.0127552 -0.0198208 -0.018883 0.00170381 0.0281818 0.0335668 0.00621638 0.000123257 -0.0400046 -0.0251494 -0.0599436 -0.0484318 -0.0953316 1.26394))
+(25.9418 0.014063 0.023283 #(-0.0146976 0.0123669 -0.00238331 -0.00566441 0.000213927 0.0251708 0.0058586 -0.0152624 -0.0096643 0.000380473 -0.00692432 -0.0103325 -0.00570062 -0.00779317 -0.00373097 -0.00244446 0.0232326 0.00687431 -0.0123666 0.0136142 0.000873428 0.01297 0.00157535 -0.0189359 0.0103542 0.0149338 -0.00232667 0.018195 0.0122806 0.000705099 0.0180465 -0.00723085 -0.0333543 -0.0209618 -0.00258482 -0.00346647 -0.0161793 -0.00443528 -0.0107334 -0.00729346 0.0212632 0.017004 -0.0134609 -0.0122188 -0.0266593 -0.0240987 -0.0584669 -0.0204726 -0.0728998 1.23429))
+(26.411 0.0454326 0.0414755 #(-0.0109339 -0.0010968 -0.0010053 0.00617609 0.00306015 0.000136934 0.00372594 -0.00564924 -0.00591968 -0.00522412 -0.00509402 -3.17432e-006 -0.00446083 0.00456961 0.00243643 0.00451923 0.00334826 0.00559344 0.00805774 0.000849614 0.00365901 -0.000214671 -0.00258062 0.00132718 0.00916179 0.00321858 -0.00441098 0.00674969 0.00362521 0.00233835 0.00103611 -0.00365412 -0.0110665 -0.0113001 -0.00483079 -0.00471838 -0.0072024 -0.0112189 -0.00842469 -0.00122134 0.00258161 -0.00404681 -0.0108012 -0.0163903 -0.0156165 -0.0101237 -0.0119205 -0.0127908 -0.0241693 1.1353))
+(26.023 0.0171174 0.0256472 #(-0.00659148 -0.0022813 0.00245043 0.0119932 0.00673879 0.0106215 0.000193227 -0.0118672 -0.00229731 -8.44562e-005 -0.010244 -0.0224172 -0.0074773 0.00139424 0.00442344 -0.00372009 0.00631038 0.00399001 0.00074413 0.00143648 0.0117816 0.0167116 -0.011429 0.00660101 -0.0154429 0.0245051 0.00954568 0.00221017 0.00972422 0.00691179 0.00198784 0.00641321 -0.0164092 -0.0286664 -0.00348171 -0.00646432 -0.0149224 -0.00929398 0.000946284 -0.00786511 0.0105857 0.0116371 -0.0208869 -0.0167969 -0.039235 -0.0416232 -0.0188724 -0.0395318 -0.0672928 1.2529))
+(20.1471 0.0413173 0.0452855 #(0.0028042 0.00238915 0.00320531 0.00204744 -0.00128491 -0.000625469 0.00121502 -0.00053792 -0.00926453 -0.00168529 -0.0176347 -0.00451895 0.000996928 0.00430582 0.00194222 -0.00398466 0.00259957 0.00390882 0.0116503 0.00167209 -0.001884 0.00309071 0.00380416 0.00551039 0.0052082 0.00707811 -0.00293764 0.0110331 0.0118179 0.000155053 0.0029885 -0.0120471 -0.00528422 -0.0186305 -0.00389795 -0.01138 -0.0130287 -0.0114016 -0.00348096 0.00720399 -0.00393767 -0.00782219 -0.00889679 -0.0106665 -0.0241594 -0.0212916 -0.0261109 -0.0222356 -0.042137 1.1898))
+(15.5487 0.0153078 0.0313768 #(0.0038797 -0.00898583 -0.00129375 0.0135476 0.00658722 0.0365788 0.00343157 -0.0308747 -0.0106992 -0.00551437 0.00041832 -0.0139702 -0.0154675 -0.0119801 -0.00961124 0.0151818 0.00235315 -0.00360607 -0.00300882 0.0133151 0.00953059 0.00235415 -1.91313e-005 0.00280704 0.0099642 0.0205634 0.00397632 0.00529698 0.023866 -0.00799138 0.0100504 0.0079582 -0.0250386 -0.029848 -0.0097943 -0.00418491 -0.0133331 -0.0233978 -0.00335522 0.0048438 0.0168547 0.0205229 -0.0161785 -0.0256227 -0.0427417 -0.0322054 -0.0493791 -0.0330071 -0.0981295 1.29245))
+(19.0253 0.00596731 0.0177102 #(-0.0146168 -0.0100904 0.00214927 0.0184939 0.01049 0.0612408 -0.00438104 -0.0265871 -0.026429 0.00668405 0.0269023 -0.0263329 -0.0230587 -0.0429497 0.00384385 0.0294333 -0.00318107 -0.0136982 -0.00792112 0.0090845 0.0366004 -0.0174499 -0.00897093 -0.00784815 -0.00441435 0.0551205 -0.0163865 0.00471411 0.0446577 -0.0132054 0.0401863 0.0217569 -0.0372981 -0.0637524 -0.0140608 0.0379691 -0.012396 -0.0571539 -0.0387487 0.0285809 0.0555209 0.0533837 -0.020053 -0.00430533 -0.102708 -0.0554588 -0.0775484 0.00345876 -0.257812 1.45669))
+(24.3361 0.00252815 0.0101924 #(-0.0257512 -0.0008726 0.0176086 0.0124685 -0.0534896 0.100064 0.0398205 -0.0701561 -0.0307596 0.00460567 0.0732452 -0.00591591 -0.0655563 -0.0244842 0.0128442 0.0333025 -0.0171489 -0.0529101 -0.0145168 -0.00558627 0.0716373 0.0169233 -0.00522713 0.00671804 -0.0615778 0.0634442 -0.0921752 0.00951979 0.120483 -0.077487 0.0914363 0.104565 -0.0653618 -0.089458 -0.0420491 0.0741933 -0.0368942 -0.0224205 -0.159684 0.0706304 0.0604807 0.156387 -0.0368354 0.00141878 -0.11703 -0.0250188 -0.215087 0.140998 -0.528956 1.65826))
+(25.4722 0.00168582 0.00813527 #(-0.0361914 0.0503908 -0.052739 0.0874611 -0.161167 0.205034 -0.030822 -0.0297436 -0.0881124 0.0515133 0.029009 0.0911085 -0.133234 0.00447612 -0.0102752 0.0672411 -0.0743354 0.0278325 -0.088049 0.0254583 0.00378763 0.110739 -0.0335123 0.0437825 -0.111471 0.143021 -0.205556 0.0105061 0.178276 -0.139079 0.108138 0.100769 -0.0514441 -0.061891 -0.0335699 0.078663 -0.0342434 -0.0322647 -0.218112 0.133516 -0.053587 0.327015 -0.200594 0.23237 -0.331232 0.175309 -0.44634 0.403636 -0.874447 1.84189))
+(24.4789 0.00660193 0.0164225 #(-0.0129511 0.000294328 -0.0197443 0.0228973 0.0144379 0.0576108 -0.00978518 -0.00793303 -0.0138883 -0.0222251 0.0319748 -0.0148723 -0.0204648 -0.0414119 -0.0116904 0.010987 -0.0113676 0.0117234 -0.00638076 0.0237907 0.020048 0.00399678 -0.00498899 -0.00973827 -0.00584135 0.0192609 -0.0220209 0.0192987 0.0427776 -0.0141488 0.0260689 0.053246 -0.0359298 -0.0407085 -0.0153808 0.000894089 -0.0255827 -0.0505249 -0.0252819 0.0272812 0.0597201 0.0367404 0.00457889 -0.0014007 -0.0717525 -0.0699291 -0.107446 -0.0187547 -0.27242 1.49509))
+(26.2758 0.0176864 0.0259442 #(0.0033549 -0.00945348 0.0065972 0.011377 0.00754275 0.0138938 0.00853247 0.000314037 -0.00732074 -0.0137922 -0.008441 -0.0188535 -0.0266481 -0.0205979 0.00421144 0.0117094 0.0169971 -0.0179554 -0.00098244 0.035148 0.00857569 -0.0052743 -0.000887931 0.00311146 -0.00552477 0.00948484 -0.000848823 0.0254957 0.0295882 -0.0096005 0.019213 0.00984905 -0.0239854 -0.0251062 -0.0378088 -0.00656597 -0.0252241 -0.0322219 0.024789 0.0259035 0.0228412 0.0272441 -0.00713364 -0.0104557 -0.0465321 -0.0714479 -0.0841954 -0.0538046 -0.134946 1.37684))
+(33.8769 0.00801222 0.0153789 #(-0.00258214 -0.00821759 0.0196898 -0.000392261 0.0140521 0.00440578 -0.0286329 0.000567736 0.0125327 0.00426797 -0.0066993 0.0334311 -0.0281124 -0.0422645 -0.0221943 0.0377913 -0.00618192 -0.0265775 -0.00448782 0.027992 0.0456436 0.00158737 -0.0145791 -0.00474223 -0.0115839 0.0136965 -0.0283794 0.032301 0.000935378 -0.0386639 0.0497046 0.0790239 -0.0338661 -0.0499984 -0.00571791 0.0381896 -0.0512542 -0.0879677 -0.0317509 0.0295627 0.0690141 0.0544617 0.0545729 0.0472211 -0.0781932 -0.090823 -0.112884 -0.113677 -0.42381 1.68183))
+(47.5854 0.03461 0.0269689 #(0.00703504 0.0042176 -0.007448 0.00601103 0.00320568 0.00838487 0.0062723 -0.0120179 0.000336154 0.000458805 -0.00549983 -0.000896449 -0.0239517 -0.0277963 -0.00199031 0.00441657 0.0118858 -0.00555538 0.0186382 0.000599233 0.0253149 0.00947596 -0.0151058 -0.0109278 -0.00257833 0.0161187 -0.000843106 0.0151509 0.00682266 0.00837561 0.0212141 0.019091 -0.0166389 -0.0383569 -0.0276626 -0.0067535 -0.0278646 -0.0358582 -0.00485826 0.02398 0.0407189 0.0544763 0.0300379 -0.00650959 -0.0404744 -0.0715788 -0.100036 -0.13855 -0.218292 1.50233))
+(67.1502 0.0503262 0.0273762 #(0.00163764 0.00156368 0.000896518 -0.00356924 0.0146311 0.0115155 0.000718131 -0.010003 -0.00103783 0.00202199 -0.00199034 -0.0161105 -0.0194743 -0.0104963 -0.00591896 0.0121449 0.00486055 -0.00401805 0.00316407 0.00376875 0.0156482 0.00483055 -0.00410957 -0.00432992 -0.00485066 0.0143753 0.00558336 0.0130507 0.00596937 0.00550279 0.0213288 0.00884339 -0.00423094 -0.0320471 -0.0225288 -0.0132194 -0.0288979 -0.0323811 -0.0196434 0.0287962 0.0448142 0.0421381 0.0389864 -0.00463365 -0.0331114 -0.0584344 -0.112601 -0.149007 -0.247096 1.5331))
+(87.0259 0.146162 0.040982 #(0.0066813 0.0031666 0.00524609 -0.0082533 -0.00391559 0.0131647 0.0226346 0.00201689 -0.0300066 -0.0164448 0.00249676 0.012122 -0.0120514 -0.0290936 -0.00477291 0.0062677 0.00679358 0.00355967 0.0074764 0.00641204 0.00203213 -0.000103927 0.00208319 0.00592471 -0.00531212 -0.00286345 0.0194362 0.0235452 0.0145299 0.000873052 0.0170015 0.00926635 -0.0249864 -0.0345525 -0.026674 -0.0209155 -0.0204941 -0.0180144 -0.000742368 0.0206704 0.0347392 0.0281013 0.0231078 0.00568184 -0.0455544 -0.0687793 -0.0774324 -0.112311 -0.16092 1.413))
+(103.805 0.0839127 0.0284317 #(0.0305305 -0.0232935 -0.0123279 -0.00539001 0.00241112 0.0181144 0.0198195 -0.0119952 -0.00946969 -0.00768942 0.0176179 0.0159392 -0.0270933 -0.0533804 -0.0238979 0.042285 0.0419821 -0.0130642 -0.02037 0.00470052 0.0265474 0.00800111 -0.0193407 -0.00539329 -0.00768145 -0.00352887 0.00818424 0.0306883 0.00191179 -0.011258 0.0201576 0.0424102 0.000582659 -0.0480861 -0.0335357 0.00238416 -0.000149278 -0.0762318 -0.0235003 0.0537691 0.0525345 0.0284459 0.0125174 0.044311 -0.0359816 -0.0879433 -0.0942918 -0.141744 -0.328099 1.59425))
+(124.841 0.162496 0.036078 #(0.0154669 -9.72884e-006 -0.0101342 -0.00793859 0.0059567 0.0228617 0.00768918 -0.0107367 -0.0153092 -0.00690622 0.00137529 0.00756771 -0.0173113 -0.0348903 -0.015329 0.0277865 0.0313134 0.00105124 -0.0143057 -0.00667794 0.011448 0.00558312 -0.00253005 0.000195594 -0.00582771 0.00497205 0.0183721 0.0241788 0.0151434 -0.0120356 0.00834879 0.019273 -0.0189529 -0.0436641 -0.017064 0.0110478 -0.0142619 -0.0454921 -0.0275606 0.0195142 0.0430997 0.0479311 0.0369613 0.00241956 -0.049964 -0.0670036 -0.063226 -0.132439 -0.269048 1.51163))
+(180.716 0.293325 0.040288 #(0.0258335 -0.0119538 -0.0193954 -0.00626257 0.0234294 0.0231874 0.0109882 -0.0140674 -0.0204807 -0.0175573 0.000633931 0.000397377 -0.011624 -0.022438 -0.0107618 0.0178291 0.0325036 0.0112156 -0.0171066 -0.00548084 0.00984786 -0.00170732 -0.00485124 -0.00691943 -0.00247698 0.0118085 0.0178137 0.0244233 0.0229053 0.003698 -0.0103266 -0.00441229 -0.00122563 -0.0243714 -0.0381239 -0.0309188 -0.0100181 -0.00337076 -0.00420997 0.0204227 0.0439681 0.0382338 0.00823855 -0.0138448 -0.0326542 -0.0661078 -0.097244 -0.115524 -0.154429 1.42031))
+(234.118 0.205985 0.029662 #(0.0192157 -0.0031935 -0.00784433 -0.00677489 0.00286156 0.0114244 0.0199407 0.00873447 -0.0210833 -0.0382217 0.00335562 0.018978 -0.0148748 -0.0242473 -0.0051396 0.0205883 0.00181457 -0.0139292 0.0109887 0.0201683 0.00322887 -0.00941825 -0.00196576 0.0112985 -0.0102269 -0.0019795 0.0216591 0.0239712 0.00292886 -0.0126777 0.0229174 0.0228922 -0.0279371 -0.0544655 -0.0105665 0.0201515 -0.0232041 -0.0500812 -0.0122807 0.0286273 0.0377097 0.0333467 0.0362003 0.00682096 -0.0421918 -0.0623608 -0.0697533 -0.142768 -0.286476 1.53382))
+(240.477 0.393671 0.0404604 #(0.0141351 -0.00376777 -0.0127499 0.00507208 0.0136482 0.0136646 0.00963351 -0.00969488 -0.0204225 -0.0195809 -0.00608936 0.0113476 -0.00348937 -0.0263493 -0.00860379 0.0196824 0.0270435 0.00279308 -0.0216122 -0.00311376 0.0167268 0.0026715 -0.00951989 -0.00655211 -0.000521916 0.00286717 0.0195184 0.0369098 0.0212964 -0.00938696 -0.00852238 0.0157752 -0.010538 -0.0511757 -0.0367333 -0.00701777 -0.00496757 -0.0218476 -0.00180121 0.0358277 0.0423497 0.0250602 0.0161893 -0.00886896 -0.0517459 -0.0757613 -0.0763744 -0.0986088 -0.163602 1.41088))
+(208.983 0.298555 0.0377969 #(0.0164121 0.0048719 -0.0123277 -0.0082839 0.00553303 0.0215874 0.00343585 -0.0106931 -0.0143605 -0.0149133 -0.000867135 0.00882374 -0.00160873 -0.0229544 -0.0199348 0.0112933 0.0268215 0.00930974 -0.0129465 0.00684308 0.00823984 -0.00100629 -0.00874536 -0.0125536 0.0018266 0.00222032 0.0179517 0.0318532 0.0216125 -0.00395573 0.00757547 0.000995567 -0.0228842 -0.0368795 -0.018438 -0.00111154 -0.0249076 -0.0299492 0.000929623 0.034715 0.0335621 0.0270658 0.0181262 -0.000710647 -0.0431774 -0.0595626 -0.0734814 -0.128686 -0.215031 1.46608))
+(169.872 0.295057 0.0416766 #(0.0319486 -0.0152698 -0.0178871 -0.00121978 0.0101795 0.0113419 0.00466058 -0.0163847 -0.00962441 -0.00255257 0.0034453 0.00333557 -0.00638092 -0.0185545 -0.0171695 0.00620859 0.027439 0.00889597 -0.00634335 0.00222882 0.00733991 0.00272018 -0.00324214 -0.00743471 -0.0202102 -0.0144455 0.0143375 0.0353734 0.03177 0.0180433 0.00470567 0.00350029 -0.0211588 -0.0400762 -0.0312031 -0.00502416 -0.0137467 -0.0287056 -0.00591527 0.0317417 0.0557392 0.030424 0.00295205 -0.00796262 -0.0331349 -0.0705161 -0.0935693 -0.117755 -0.17632 1.44112))
+(198.736 0.583121 0.0541678 #(0.0239533 -0.0108176 -0.0102808 0.00564068 0.0150349 0.00994732 -0.00604523 -0.00984589 -0.0142772 -0.0121714 -0.00415331 -9.11199e-005 -0.00732939 -0.0188397 -0.00379378 0.0155464 0.0238681 0.0102193 -0.00649659 -0.0166725 -0.00159701 0.0168372 0.00555774 -0.0076568 -0.0152812 0.00621925 0.0304524 0.0302777 0.0179796 -7.1259e-005 -0.0110991 -0.0120554 -0.0207771 -0.0196221 -0.019649 -0.0276093 -0.0267218 -0.00462518 0.0217483 0.0300955 0.0254635 0.0179527 0.00908021 -0.0147737 -0.0434505 -0.0549393 -0.067622 -0.0980195 -0.11752 1.34832))
+(235.893 0.196632 0.0288715 #(0.0304126 -0.0184424 -0.0165599 -0.000407823 0.00801631 0.0195737 0.0118165 -0.00905007 -0.0134561 -0.0135 -0.00394936 0.00567199 0.00352691 -0.0209869 -0.0335421 0.00501761 0.033716 0.0178405 0.00147093 -0.011718 -0.00133608 -0.00135017 0.00902945 0.00737444 -0.0033788 -0.00925621 -0.0209713 0.0180258 0.0548861 0.0175237 -0.0085279 -0.00515863 -0.0139746 -0.031351 -0.0115241 0.00705294 -0.0364894 -0.0527857 -0.0113735 0.0463322 0.0573369 0.0344311 0.019218 0.00187843 -0.0302693 -0.0656353 -0.0907326 -0.155003 -0.284321 1.55441))
+(250.351 0.920652 0.0606419 #(0.0221283 -0.00175026 -0.00689412 0.000872708 0.00825388 0.00110956 -0.00632789 -0.0125022 -0.0104057 -0.00936074 -0.00616766 0.00522704 0.000860839 -0.00548061 -0.0014818 0.00943791 0.00798624 0.000154997 -0.00816161 -0.00716682 0.000403966 0.00149304 0.00596023 0.00691071 0.00706264 0.0106029 0.0144444 0.01869 0.0103569 -0.00377258 -0.00598677 -0.011182 -0.0229358 -0.0277385 -0.0171593 -0.00963866 -0.0130767 -0.00448601 0.01284 0.0232398 0.0183027 0.00684207 0.000345183 -0.017907 -0.0388241 -0.0491714 -0.0555385 -0.0671155 -0.080383 1.27961))
+(265.144 0.37479 0.037597 #(0.0178487 0.0013791 -0.0116388 -0.00507206 0.0138357 0.0176418 0.0040927 -0.0179262 -0.017936 -0.00558455 0.00209339 -0.00600955 -0.011245 -0.00868085 -0.00205561 0.000295947 0.0125599 0.0156985 -0.00318278 -0.0132323 -0.000274777 0.00777626 -0.00183865 0.00266585 0.0125194 0.00603461 -0.00305746 0.0220627 0.0328774 0.00937883 -0.00296813 -0.0139498 -0.023661 -0.0265224 -0.0152562 -0.00981502 -0.0187505 -0.0249964 -0.00613381 0.0245956 0.0383716 0.0292479 -0.00259061 -0.00982094 -0.0297847 -0.0422148 -0.0701577 -0.115859 -0.177598 1.41175))
+(250.53 0.735674 0.0541892 #(0.0238545 -0.00486949 -0.00173591 0.00252099 0.00404998 0.00118642 -0.00418862 -0.0123793 -0.0138166 -0.00838696 -0.00266911 -0.000717441 -0.00433613 -0.00087901 3.08753e-005 0.00695944 0.00812309 0.00161619 -0.00106495 -0.00230766 -0.00318343 -0.00717512 0.00130251 0.0107457 0.00679086 0.00860716 0.0173261 0.0173051 0.0100283 0.00988019 0.00145606 -0.0181773 -0.0255863 -0.0227028 -0.0191551 -0.0156616 -0.0149123 -0.00943028 0.00703709 0.0185155 0.0208948 0.0180594 0.00541843 -0.016114 -0.0379061 -0.0507604 -0.0578965 -0.0768728 -0.0909356 1.29924))
+(197.598 0.485401 0.0495631 #(0.0248193 -0.00306678 -0.00667275 -0.0014236 0.0114491 0.0091926 -0.0023926 -0.0167224 -0.0201609 -0.00339142 -0.00311447 -0.00213343 -0.00661917 -0.00708419 0.00117074 0.0105285 0.010503 0.000885714 -0.00157855 -0.00449273 -0.0024985 -0.000379483 -0.0043849 0.0022342 0.0114984 0.0120889 0.0118227 0.0206663 0.0203387 0.01268 -0.00367646 -0.0148372 -0.0196786 -0.0256279 -0.0246386 -0.0201119 -0.0148319 -0.00916508 -0.00126804 0.0198383 0.0319355 0.0159117 0.00101828 -0.0089909 -0.0292361 -0.0476222 -0.0687146 -0.089934 -0.113823 1.33378))
+(125.124 0.316632 0.0503045 #(0.0130568 -0.00225892 0.00216152 0.0102169 0.00996052 -0.00255912 -0.0097279 -0.0196243 -0.00656228 -0.000937932 -6.12063e-005 -0.000608431 -0.00526008 -0.00223335 0.00268855 0.00317693 0.00183598 0.00660908 0.00583385 -0.00116981 -0.00278075 -0.00730575 -0.0127456 -0.00600758 0.00295042 0.00742113 0.0148913 0.0264792 0.0296855 0.00264396 -0.00385496 -0.00327753 -0.023196 -0.0218689 -0.015055 -0.00831472 -0.0139174 -0.0128882 -0.000967953 0.012294 0.0210776 0.0214656 0.0105105 -0.0134574 -0.0314187 -0.0453388 -0.0664272 -0.107779 -0.148171 1.37876))
+(71.37 0.227496 0.0564585 #(-0.0142429 0.012727 0.0152038 0.013247 0.0124478 0.00703828 -0.0126102 -0.0229412 -0.0168578 -0.00561364 0.00559436 0.00298623 -0.0049227 -0.00038521 -0.00127981 0.00423441 0.000763587 0.00976382 0.0108994 0.00630644 -0.00368733 -0.0148032 -0.023322 -0.0161698 -0.000889858 0.011531 0.0186532 0.0329139 0.0305486 0.00665483 -0.0125951 -0.0144017 -0.0205354 -0.0305956 -0.0183857 -0.000585577 0.0114074 0.00891327 0.00153785 0.00446643 0.00473343 0.015059 0.0101803 -0.0146464 -0.0351526 -0.0511088 -0.0647666 -0.0850186 -0.118079 1.33668))
+(40.4377 0.0852366 0.0459113 #(-0.0335089 0.029908 0.0183897 0.0176984 0.0101193 0.00829117 -0.0170098 -0.0268985 -0.022606 0.00232026 0.0189546 -0.0045041 -0.00575308 -0.0100939 0.00425405 0.00177554 0.00632439 0.0070991 0.0135077 0.0172888 -0.00309632 -0.0159993 -0.0288205 -0.0254887 -0.0108957 0.00733041 0.0214328 0.0301479 0.0306404 0.0070994 -0.0123194 -0.025963 -0.0100594 -0.00332728 -0.00658321 -0.000959254 0.00177248 0.00985076 -0.0049481 -0.00260225 0.00144116 0.00476165 0.00342908 -0.0128849 -0.0221734 -0.0326228 -0.0534822 -0.0924536 -0.143692 1.34984))
+(27.3832 0.070801 0.0508484 #(-0.0140748 0.0135211 0.0169284 0.0134048 0.00664361 -0.000844623 -0.025384 -0.00976012 0.00801802 0.00636203 -0.00289115 -0.0127367 0.000562452 0.00700169 0.00416503 0.00548033 0.00503239 0.00518513 0.00212309 -0.00811506 -0.0249022 -0.0165552 -0.00808011 -0.0032732 -0.00323997 0.0128592 0.0143886 0.0210239 0.0149843 -0.0102482 -0.00523455 -0.0127067 -0.00629629 -0.0118239 -0.00186732 0.00661671 0.000807708 0.0076143 -0.00151332 -0.0141276 0.000588052 0.013716 -0.00222398 -0.0188076 -0.0188453 -0.0187286 -0.0391334 -0.0564238 -0.0793644 1.23514))
+(30.7375 0.040934 0.0364929 #(-0.0243691 0.00812592 0.015261 0.01097 0.0205355 0.0101767 -0.0151796 -0.0251579 0.00184063 0.0088331 0.00252205 0.000583772 -0.00157531 -0.000798763 0.00905121 0.00117476 0.00355867 -0.00185548 0.00468458 -0.00729399 -0.0289016 -0.0190386 0.00930854 -0.00472978 -0.0131431 -0.00543118 0.00841419 0.0272355 0.0256443 -0.00636553 -0.00757628 -0.00558504 -0.000516058 -0.00121443 -0.0138289 0.00110727 0.00668947 0.00434654 -0.00919808 -0.0198922 0.00235468 0.0144602 -0.000975259 -0.0245124 -0.0246625 -0.015985 -0.0371288 -0.0397989 -0.0669062 1.22136))
+(42.0859 0.00626129 0.0121973 #(-0.0734655 0.0296172 0.013634 0.0452539 0.00702914 0.057469 -0.0232954 -0.0727147 -0.0229838 0.0545064 0.022556 -0.0378221 -0.0116609 -0.0131154 0.0381253 0.0259823 -0.0219215 -0.0248628 0.0469329 -0.00591986 0.0161304 -0.0248895 -0.0474258 -0.0134104 -0.011063 0.0414246 -0.0607445 0.0508991 0.0641952 0.00526139 -0.0600509 0.00150282 0.00627574 -0.070137 0.0242186 0.0169948 0.0408282 0.0438345 -0.0204922 -0.0610643 -0.0804496 0.0966152 0.0588874 -0.0136561 -0.0697122 0.00834575 -0.047428 -0.0855743 -0.478215 1.63444))
+(48.3822 0.0133138 0.0165886 #(-0.0991241 0.0620696 0.0256428 0.0325504 0.030601 0.0200286 -0.0346818 -0.0543453 -0.000353481 0.0292389 0.0225596 -0.0231814 -0.0230041 -0.00406665 0.0324386 0.00882869 -0.0235801 0.0419879 0.00354304 -0.0088214 0.00179125 -0.0386059 -0.020162 -0.0161291 -0.0274193 0.0200131 0.00125343 0.0450822 0.0571638 -0.0335057 -0.0273933 -0.0201817 -0.0220575 -0.0085605 -0.000251926 0.0202286 0.0402841 0.0305421 -0.0148375 -0.0251732 -0.04472 0.0420287 0.0255921 -0.0131808 -0.0380019 -0.0228509 -0.0479855 -0.104387 -0.277699 1.47947))
+(52.3586 0.0659523 0.0354912 #(-0.0350294 0.0226496 0.0266707 0.0151374 0.00559978 -0.00178336 -0.0131273 -0.00792491 0.00702189 0.00803718 0.000224972 -0.0104286 -0.0107735 0.000890825 0.000619345 0.00514007 -0.000477151 0.00445113 0.0122391 0.00292333 -0.0091859 -0.0264601 -0.0178257 -0.00867586 0.00144957 0.00389939 -0.00103973 0.00526759 0.0114127 0.00266532 -0.0114983 -0.0129203 -0.0101913 0.00682779 0.023871 0.0120872 0.00875099 0.0033859 -0.00336156 -0.00727741 -0.00798061 0.00279848 -0.00798744 -0.0160221 -0.02748 -0.0249909 -0.0413176 -0.0503363 -0.0665837 1.23408))
+(57.2864 0.0998289 0.0417448 #(-0.0107891 0.0182459 0.0133387 0.00654529 0.00351746 -0.0028236 -0.00652551 -0.00276973 0.00189705 0.00363537 -0.00543967 -0.00428984 -4.74181e-005 0.00728144 -0.000418819 -0.00318095 0.00296512 0.00149376 0.00209253 -0.0105876 -0.0105755 -0.00732988 -0.0124828 -0.00540931 -0.00364074 0.00253872 -0.000591894 0.0020125 0.00672111 -0.0103777 -0.00817489 -0.00341224 0.00892754 0.00393065 0.00183264 0.0170761 0.0103609 0.0093558 -0.00221637 -0.00689539 -0.00883095 -0.00260063 -0.00561736 -0.0152408 -0.0198652 -0.0251051 -0.0359384 -0.043327 -0.0516084 1.19939))
+(63.2886 0.0659521 0.0322813 #(-0.0395131 0.0278336 0.0226114 0.0208169 0.00156559 -0.00586198 -0.00373168 -0.0129797 -0.000442788 0.00591266 0.00384389 -0.00649693 -0.000432298 0.00820201 0.00205019 -0.00693928 -0.00561469 0.00651516 0.00426545 -0.00287469 -0.0195372 -0.0148713 -0.00282639 -0.00135895 0.00476877 0.00385195 -0.00114983 0.00160519 0.0150339 -0.00888809 -0.0157333 -0.00871617 -0.00192295 0.00638566 0.00653376 0.0147419 0.00964909 0.00830972 -0.00471322 -0.00721979 -0.00854983 -0.00297041 0.000582071 -0.00321452 -0.0251575 -0.0448269 -0.0465566 -0.0617166 -0.0814745 1.26877))
+(68.2143 0.127344 0.0432067 #(-0.00650372 0.0166661 0.0110006 0.0046084 -0.000191608 -0.000655383 -0.0075612 -0.00289214 0.00188358 0.00579054 0.000329202 -0.00681358 -0.00225101 -0.000353251 0.0031628 -0.0053415 -0.000525401 0.00656196 0.00272409 0.00256422 -0.0160209 -0.0140322 -0.00207772 -0.00301927 -0.000189949 -0.00236457 0.00311191 0.00706533 -0.000524762 -0.00984277 -0.0108244 -0.00768298 0.000888997 0.00214318 0.0071796 0.0118653 0.0159322 0.00963205 -0.00200409 -0.0107815 -0.00688397 0.000662548 0.00124322 -0.0216095 -0.024252 -0.0275861 -0.0290191 -0.0455658 -0.0594961 1.20854))
+(74.5766 0.00960274 0.0113474 #(-0.0930925 0.0474147 0.0783675 0.00847634 -0.0083235 0.0389507 -0.0156469 -0.0811489 -0.00383005 0.0271399 0.0027488 -0.0036905 -0.0380551 0.0424861 0.036423 -0.0258928 -0.0261861 0.00709007 0.0423739 0.0478494 -0.0457433 -0.0682701 -0.0230027 0.0330979 0.0021217 -0.00664132 -0.0268997 0.0548632 0.100473 -0.0711387 -0.0110561 -0.0158289 -0.0476065 -0.0351137 0.00284219 0.0323319 0.0313311 0.0736398 0.0142766 -0.10177 -0.0582263 0.0770375 0.0914699 0.0357695 -0.12508 -0.0345359 -0.0237482 -0.0585581 -0.687455 1.80702))
+(89.851 0.0668036 0.0272671 #(-0.047951 0.0391961 0.0312392 0.0264315 0.0152606 -0.0229461 -0.0203805 -0.0182092 -0.00178092 0.00435629 -0.00460121 -0.00718773 -0.00219992 0.00637422 0.00988643 0.00875952 0.00355863 0.0092556 -0.00376029 -0.00369781 -0.0084366 -0.0248106 -0.00997018 -0.00992863 -0.00298569 0.00552284 0.0193635 0.0324098 0.00560115 -0.0147652 -0.0174123 -0.0176175 -0.017063 -0.00976483 0.00645685 0.0115746 0.0243375 0.0212918 0.0038104 -0.00756 0.00845826 0.00991446 0.00809276 -0.000765567 -0.0407473 -0.0481121 -0.0785197 -0.118162 -0.175228 1.42139))
+(111.491 0.0612596 0.0234406 #(-0.071768 0.0568083 0.0427606 0.0216603 -0.00175519 0.00236969 -0.0168044 -0.027955 -0.00413897 0.00759891 0.00307185 -0.0137154 -0.021489 0.00188837 0.0194342 0.0167963 0.0109949 -0.00132022 0.0129203 0.00409717 -0.016515 -0.035451 -0.0211164 -0.0147696 -0.00623048 0.017651 0.0231703 0.0352329 0.0277801 -0.0201851 -0.0270755 -0.0333369 -0.0135395 -0.0048966 -0.00213377 0.01776 0.0243864 0.0268 0.00479255 -0.0136091 0.00196506 0.0109521 0.0263541 0.00149658 -0.0351393 -0.0414662 -0.0804536 -0.15343 -0.262886 1.52039))
+(131.563 0.0385887 0.0171263 #(-0.0518673 0.0134846 0.0263128 0.0468026 0.024454 0.0220736 -0.0400596 -0.0676488 -0.0114445 0.0413724 0.0448596 -0.0289181 -0.0607654 0.00419211 0.039212 0.0198165 -0.0106986 -0.00978497 0.0268256 0.0153281 -0.014289 -0.0258232 -0.021492 0.00140582 -0.0194537 -0.0176859 0.00346931 0.0616223 0.0476843 0.000242224 -0.0396149 -0.0480542 -0.0287999 0.00734256 0.00921102 0.0219239 0.0281868 0.0214498 0.0045841 -0.0526773 -0.0290021 0.0477786 0.066508 -0.00482082 -0.060896 0.00723903 0.00689539 -0.17291 -0.656903 1.81153))
+(151.886 0.102626 0.0259939 #(-0.070856 0.0486957 0.0480601 0.0368429 0.0182886 -0.00829156 -0.0513057 -0.0475156 -0.00697538 0.0443591 0.0264049 -0.0186967 -0.046636 -0.00991082 0.0358113 0.0296259 -0.00965236 -0.00183771 0.0116684 0.0166791 -0.0164862 -0.0397139 -0.0181811 -0.0084272 -0.01239 -0.000257272 0.0267701 0.0470878 0.0342028 -0.0154802 -0.0370322 -0.0415501 -0.0235126 1.97047e-005 0.0225005 0.0265028 0.0239742 0.0125777 -0.00895148 -0.0232263 -0.000947537 0.0428729 0.0258008 -0.0298816 -0.037036 -0.00471161 -0.0249833 -0.174155 -0.397768 1.60503))
+(165.11 0.169794 0.0320682 #(-0.0409658 0.0441689 0.0293712 0.0214998 0.0154116 -0.00248447 -0.0422952 -0.0478381 -0.00388453 0.0270632 0.0266513 -0.00557179 -0.022944 -0.0116277 0.0116475 0.0182246 0.00737678 -0.00598205 -0.00128794 0.00345216 -0.00394256 -0.00695017 -0.0256291 -0.0322332 -0.012631 0.0176517 0.0309905 0.0230604 0.0224319 -0.0106256 -0.0268479 -0.0207674 -0.00587152 -0.00570336 -0.00197812 0.0122906 0.0205968 0.031643 0.00252642 -0.0332331 -0.00542228 0.0405915 0.0309338 -0.0143715 -0.0384462 -0.0185082 -0.0347614 -0.166035 -0.349634 1.55773))
+(177.174 0.178624 0.0317519 #(-0.0375195 0.0292643 0.0300942 0.0307154 0.0193178 -0.00509529 -0.0345436 -0.0373165 -0.0172528 0.0236766 0.0201161 -0.0183973 -0.0276741 0.00996924 0.0330329 0.0152227 -0.00951397 -0.0122329 -0.00113485 0.0194899 -0.0119267 -0.0292984 -0.015638 -0.0142287 -0.0148578 -0.000859865 0.0260062 0.0534978 0.0402742 -0.0219816 -0.040437 -0.0341774 -0.0049463 -0.0116811 -0.0123897 0.0190348 0.0504628 0.0449273 -0.00894907 -0.0495895 -0.0187866 0.0407222 0.046073 -0.00801632 -0.0446076 -0.0182126 -0.03077 -0.167466 -0.369669 1.57394))
+(179.99 0.221245 0.03506 #(-0.037004 0.0260371 0.0372679 0.0497295 0.0157299 -0.0244911 -0.0537488 -0.0510671 0.00512908 0.05199 0.0203676 -0.0338469 -0.0238147 0.0127183 0.0230843 0.00442021 -0.0115414 0.00421587 0.0188467 -0.00272606 -0.0256457 -0.0344065 -0.0104499 -0.00267908 -0.00204974 0.00352165 0.02398 0.0343543 0.0255179 -0.0152773 -0.0303301 -0.0266642 -0.0139434 -0.00355751 -0.0084824 0.0107571 0.0423518 0.0526576 -0.00233367 -0.0445417 -0.0249914 0.0319504 0.0506834 -0.0160456 -0.0561795 -0.0084321 -0.00738221 -0.153557 -0.379863 1.55632))
+(166.887 0.252327 0.038884 #(-0.0419053 0.0366535 0.0498127 0.0359369 0.00208074 -0.0250268 -0.0524974 -0.0402762 0.00682585 0.0354895 0.0297739 -0.0147708 -0.0304251 -0.00374599 0.0183841 0.0130221 0.00121661 0.00411938 0.00494517 0.000507366 -0.0263356 -0.0463632 -0.0168647 0.0149596 0.0144969 0.00307392 0.0082568 0.0288554 0.0295293 -0.00737698 -0.0363064 -0.0244228 -0.0110509 -0.00137184 -0.01354 0.00159516 0.0392046 0.0550105 0.0155153 -0.0394186 -0.0271276 0.0202588 0.0342747 -0.0055672 -0.0407041 -0.0119139 -0.0198007 -0.157004 -0.344951 1.53129))
+(164.943 0.182476 0.0332611 #(-0.0614847 0.034366 0.0618075 0.0440773 0.010115 -0.0176925 -0.0502932 -0.0698586 -0.0117179 0.0583499 0.0553452 -0.0141319 -0.052825 -0.00920142 0.0291995 0.0159293 -0.00586749 -0.00306322 0.0226316 0.00427445 -0.0340741 -0.0437776 -0.0123615 0.00698813 0.00470649 0.00949797 0.00789906 0.0335011 0.0219034 -0.00266724 -0.0265675 -0.030155 -0.0143053 -0.0093868 -0.00158663 0.0163901 0.0203923 0.0417646 0.0187303 -0.0392964 -0.037276 0.0437944 0.0678762 -0.016769 -0.0789091 -0.0197703 0.0398731 -0.156601 -0.511722 1.65878))
+(176.99 0.261053 0.0384053 #(-0.06 0.056536 0.045999 0.0280942 0.0117416 -0.0124533 -0.0449422 -0.0463361 -0.00718186 0.0308653 0.0198448 -0.0192072 -0.0242862 0.0065568 0.031481 0.0162032 -0.00801501 -0.00216827 0.0134013 -0.00587761 -0.0383848 -0.0362193 -0.0129257 0.0157857 0.00474063 -0.00184301 0.0202611 0.041013 0.0198278 -0.0191734 -0.029208 -0.0221024 -0.0116136 -0.0121702 -0.00611537 0.0173498 0.0404119 0.0315245 -0.00593292 -0.0237962 -0.000431722 0.0439062 0.0334822 -0.0297822 -0.0607389 -0.0164012 -0.00830834 -0.154607 -0.362478 1.54998))
+(176.048 0.159462 0.0300963 #(-0.0377232 0.0103334 0.036835 0.0488153 0.0179723 -0.00819109 -0.0460628 -0.0619188 -0.00111458 0.0446256 0.032363 -0.00836746 -0.0360712 -0.00850298 0.0216202 0.0175984 -0.000914048 -0.0173185 0.00126597 0.0264074 -0.00629105 -0.043736 -0.017196 0.00494882 -0.000320422 -0.012511 0.00430157 0.0466093 0.0305521 -0.0031329 -0.0376142 -0.024873 0.00750779 -0.012678 -0.0104912 0.00134055 0.0376222 0.0412994 -0.0218273 -0.0452171 -0.0128663 0.072725 0.0680508 -0.0173601 -0.0684261 -0.0212582 0.0188153 -0.175166 -0.561992 1.72452))
+(171.946 0.2352 0.0369847 #(-0.0512015 0.0329072 0.0503361 0.0280294 0.00184622 -0.0107644 -0.0348259 -0.0337681 0.00209173 0.0265416 0.028044 -0.0189349 -0.0371111 -0.000802031 0.0279831 0.0122725 -0.00874739 -0.00112342 0.0180879 0.000223799 -0.0259366 -0.0351892 -0.00449204 0.00197593 -0.0162875 -0.011366 0.0181628 0.0541492 0.0395807 -0.0167336 -0.0418708 -0.0160073 -0.00774302 -0.00128406 -0.00712924 -0.00703709 0.0178146 0.0397532 0.00726889 -0.0174794 -0.00498909 0.0427668 0.0408804 -0.0175914 -0.0525046 -0.0244365 -0.014682 -0.171468 -0.395718 1.59284))
+(185.859 0.163683 0.0296764 #(-0.0468658 0.0116617 0.0555765 0.036102 0.0116869 -0.0136073 -0.0419413 -0.0311445 -0.015847 0.0536179 0.0374088 -0.0318291 -0.0562696 -0.0204646 0.0520056 0.0366832 -0.00267281 -0.0268453 0.00390152 0.0151844 -0.0141306 -0.026449 -0.00214409 -0.00146158 -0.0202671 -0.0306729 0.00986482 0.0542944 0.0595679 0.00293662 -0.0374089 -0.0316308 -0.0279362 -0.00383883 -0.00461755 -0.00381387 0.0302674 0.0462364 0.00234255 -0.0420869 -0.0176493 0.0621579 0.0781717 -0.0259631 -0.0837177 -0.0197173 0.0222038 -0.172749 -0.543442 1.71216))
+(211.324 0.258974 0.0350069 #(-0.0303184 0.0212199 0.0351346 0.0323836 0.0108293 -0.0194528 -0.0440712 -0.0258231 0.0179244 0.0423101 0.00743043 -0.040367 -0.0363898 0.0067014 0.0337238 0.0109171 -0.0145224 -0.00777405 0.0187512 0.010748 -0.0157507 -0.020169 -0.00503133 -0.00636303 -0.0319918 -0.0279937 0.0172805 0.0607111 0.0519986 -0.00764891 -0.0419867 -0.0321224 0.0100713 0.00236086 -0.0196657 -0.0170583 0.0223451 0.0362193 0.000122523 -0.0184589 0.0140273 0.0644042 0.0497302 -0.0380606 -0.0744375 -0.0264989 -0.0209174 -0.164711 -0.384479 1.59087))
+(230.546 0.254813 0.0332454 #(-0.0214216 0.00872379 0.0339929 0.0315809 0.0174031 -0.0232373 -0.0489485 -0.0241287 0.0209643 0.0453702 0.0190406 -0.0440306 -0.0441669 -0.00157853 0.0268724 0.0234296 -0.000401617 -0.0057701 0.000344993 -0.0054568 -0.0178071 0.0024068 0.0155485 0.000746876 -0.0375718 -0.0484998 0.00853225 0.0571187 0.0551759 -0.0142224 -0.0451274 -0.0277836 0.0263546 0.0402985 -0.0197452 -0.0401687 -0.00351748 0.0313089 0.00705256 -0.0369839 -0.00653953 0.0851077 0.0978434 -0.0156217 -0.102129 -0.0527658 0.00792703 -0.158984 -0.494505 1.67382))
+(251.512 0.22152 0.0296775 #(0.00271906 -0.0125085 0.0301646 0.0306547 0.00855251 -0.0179234 -0.0350287 -0.0305762 0.00779454 0.053486 0.0394365 -0.0393962 -0.0650717 -0.0198502 0.0326874 0.039916 -0.0010092 -0.0179188 0.00205602 -0.00398159 -0.00877683 0.0106262 0.0187416 -0.0120917 -0.0564597 -0.0545574 0.0119312 0.0765 0.0649359 -0.0149672 -0.0521681 -0.0268912 0.0228738 0.0277597 -0.00505434 -0.0391086 -0.000955081 0.0337932 -0.00277864 -0.0493297 -0.0119853 0.100552 0.124828 -0.0159932 -0.127861 -0.0612138 0.0295559 -0.144989 -0.555044 1.70991))
+(254.186 0.155867 0.0247629 #(0.011018 -0.035849 0.0315776 0.0392745 0.01848 -0.0184897 -0.0290829 -0.049739 -0.000114797 0.0517803 0.04403 -0.0251357 -0.0530782 -0.0079027 0.0214459 0.0319004 -0.0185972 -0.0210457 -0.00556451 0.0118538 0.000887009 0.0257463 0.0265477 -0.0284303 -0.0724463 -0.0721507 0.0469847 0.0785231 0.069301 -0.026447 -0.064972 -0.032767 0.00653783 0.0563972 0.0303594 -0.0350536 -0.0475477 0.0379776 0.00958391 -0.0490296 -0.0492565 0.0859668 0.161288 -0.000991608 -0.140484 -0.0439296 0.0763862 -0.147115 -0.750695 1.84834))
+(225.37 0.0803291 0.0188794 #(0.0290101 -0.0687017 0.0407707 0.0383633 -0.0152389 0.00254714 0.0114647 -0.0328925 -0.021924 0.00257726 0.0623568 -0.00416147 -0.0660898 -0.0300196 0.0572706 0.0552422 -0.027837 -0.0653128 0.00149151 0.0264922 -0.00315019 0.0193053 0.0486365 0.00427569 -0.0987687 -0.0861261 0.00501995 0.0945006 0.109231 -0.0131216 -0.077788 -0.0512939 -0.00858637 0.0620822 0.041699 -0.0369608 -0.0380424 0.0273551 0.0409665 -0.0644617 -0.0854918 0.0805598 0.178136 0.0300991 -0.186435 -0.0584791 0.205418 -0.075875 -1.13303 2.07226))
+(198.485 0.0417265 0.0144991 #(0.0414603 -0.0623938 0.0061811 0.0288222 -0.0158102 0.0252802 0.00307337 -0.00304176 0.00367747 -0.0489033 0.0357009 0.0204158 -0.0552591 -0.0256414 0.0346049 0.0958179 -0.0284009 -0.100873 -0.00722169 0.0205522 0.0295442 0.033256 0.0421494 0.00768483 -0.110423 -0.0846969 -0.0244979 0.0889337 0.157045 0.00102777 -0.0813333 -0.0900497 -0.0138341 0.0341514 0.0721558 0.00377355 -0.033424 0.010766 0.0245269 -0.0515001 -0.119286 0.0335791 0.213235 0.125951 -0.204453 -0.179761 0.270221 0.202002 -1.65027 2.32378))
+(171.548 0.1509 0.0296587 #(0.0250778 -0.0426171 0.00843798 0.0396997 0.0226322 -0.0146932 -0.0283293 -0.01936 0.0069322 0.0354412 0.0250028 -0.0357834 -0.0414478 -0.0136723 0.0292158 0.020287 -0.00117164 -0.00726955 -0.00706735 0.000159039 -0.00407658 0.0190887 0.0257392 -0.0278326 -0.0682253 -0.0552612 0.0202806 0.0931883 0.0784599 -0.037487 -0.082894 -0.0424946 0.0518775 0.0627942 0.000169138 -0.0458972 -0.0190695 0.0107115 -0.00659794 -0.0314802 0.00511231 0.0991288 0.0788463 -0.0108271 -0.0699992 -0.0146887 -0.00873203 -0.228192 -0.553044 1.75651))
+(138.651 0.0571929 0.02031 #(0.0213914 -0.0306978 0.00848927 0.0130779 0.00721775 0.00427365 0.00961346 -0.0314829 -0.018867 0.036295 0.03503 -0.0305203 -0.0463152 -0.0107846 0.0382213 0.0409777 -0.0373991 -0.0384969 0.0128019 0.00295524 0.0157249 0.0419502 0.0294107 -0.0318793 -0.11091 -0.0681277 0.0179675 0.131618 0.114326 -0.0427296 -0.109902 -0.0736138 0.0191553 0.091943 0.0543933 -0.0340794 -0.0436619 0.00746334 -0.0066161 -0.0679531 -0.0238454 0.0924077 0.161235 0.0122723 -0.139703 -0.0326624 0.115233 -0.166794 -0.931623 1.99133))
+(113.308 0.193753 0.0413518 #(-0.0270571 0.018724 0.0316812 0.0297654 0.00202789 -0.0163134 -0.0290023 -0.0123064 0.0176842 0.0233915 -0.00357253 -0.0336344 -0.0271282 0.00653117 0.0284495 0.0179925 -0.004167 -0.0157728 -0.00964692 0.000267421 0.00122534 0.0146035 0.00149512 -0.0396562 -0.058053 -0.0255875 0.0451789 0.0754793 0.044493 -0.0379303 -0.0597916 -0.015322 0.0420665 0.0354546 -0.0132543 -0.0383832 -0.0285421 0.000937585 0.0195054 0.0265873 0.0502106 0.0593278 0.0136192 -0.0502636 -0.0466451 -0.0180557 -0.0524014 -0.164365 -0.318595 1.53476))
+(103.037 0.0623253 0.0245944 #(-0.00724495 -0.00593484 0.0107629 0.0261896 0.0129414 0.00340164 -0.0251773 -0.0270683 0.00747135 0.0385192 0.018441 -0.0377958 -0.0304305 0.00450653 0.0229534 0.00567204 -0.0264594 -0.0176736 0.000876183 0.0471199 0.0172663 0.0124283 0.00241253 -0.0617734 -0.103682 -0.0406255 0.0578767 0.121063 0.0822661 -0.0454017 -0.102194 -0.042812 0.0321046 0.0833275 0.00602523 -0.0478943 -0.043304 0.000262387 0.00598665 -0.00374976 0.0385322 0.079333 0.0654235 -0.0354309 -0.092082 0.00159915 0.0131218 -0.204327 -0.571633 1.75234))
+(92.5577 0.120027 0.0360108 #(-0.0398489 0.0324612 0.0367935 0.0220619 0.00704562 -0.0272926 -0.0200099 -0.00659618 0.0169783 0.015708 -0.00599385 -0.0153675 -0.0128987 0.0082064 0.0102226 -0.000522355 -0.00199441 -0.00674596 -0.00220103 -0.00689017 -0.00809083 0.00336812 -0.0126411 -0.0439452 -0.04063 0.00361202 0.0505336 0.0555444 0.02238 -0.0310165 -0.038806 -0.00364963 0.0180895 0.00954 -0.00503501 -0.0195219 -0.0205427 0.00318622 0.0185383 0.0345637 0.0376351 0.0372337 0.00566722 -0.0260961 -0.0314731 -0.0229805 -0.0612615 -0.148592 -0.24421 1.45165))
+(66.5989 0.0842179 0.0355606 #(-0.0384904 0.0427509 0.0324356 0.0194716 -0.00585732 -0.0144022 -0.0118444 -0.00525952 0.0111836 0.00537657 -0.00948216 -0.00957872 -0.000929858 0.00996204 0.00650146 0.00151737 -0.00610687 -0.00883977 -0.0111524 -0.00821151 -0.0121669 -0.00254634 -0.0339117 -0.0355781 -0.013952 0.0280202 0.0436449 0.0292268 0.00874941 -0.0239858 -0.0194654 -0.00890681 0.0037191 -0.00475951 -0.00518569 -0.00236431 0.00776458 0.0118334 0.0107269 0.0178917 0.0261446 0.0384696 0.0138593 -0.0230752 -0.043364 -0.0319342 -0.0459236 -0.112816 -0.180369 1.35766))
+(42.7254 0.0264534 0.0248827 #(-0.0413135 0.0213958 0.036281 0.0248983 -0.0151715 -0.0222269 -0.00567853 0.00505671 0.017208 0.024368 -0.0203921 -0.0162792 0.000440382 0.0151094 0.0109901 -0.000613158 -0.00984668 -0.00906093 -0.00789341 0.00260445 0.0124987 -0.0123556 -0.0457957 -0.0562666 -0.0106157 0.0486385 0.0540115 0.0360568 -0.00307563 -0.0466828 -0.0306841 0.00913136 0.0174993 0.00528422 -0.0273256 -0.0166686 0.00261137 0.0230377 0.0120899 -0.00600584 0.0223933 0.0459099 0.00977329 -0.0223494 -0.0479412 -0.0230021 -0.0404154 -0.102133 -0.204478 1.38436))
+(30.9113 0.0516676 0.0408837 #(-0.014936 0.00941983 0.0118751 0.000575508 0.00581291 -0.00413739 -0.012136 0.0103523 0.00720992 0.0100773 -0.000124851 -0.00765056 0.00255218 0.000894253 0.00544408 0.000794387 -0.00215897 -0.00898489 -0.0117924 -0.00653947 -0.0064785 -0.00840759 -0.0105823 -0.0100678 0.000175767 0.0102663 0.00786819 0.0237505 -0.00215373 -0.0266525 -0.00900966 -0.00600343 -0.0028658 -0.00373159 -0.00238924 -0.00278976 -0.00429102 -0.00212087 0.00253061 0.0127614 0.0230914 0.0151189 0.00146143 -0.0117057 -0.00462498 -0.00318648 -0.0265484 -0.0369997 -0.0675645 1.14867))
+(15.3693 0.00836665 0.0233319 #(-0.0341159 0.00806944 0.0216334 0.0174292 -0.0149921 0.016248 -0.0180928 -0.00306738 0.0350942 0.00513288 -0.00769301 0.00579646 -0.0107035 0.0131971 0.00589453 -0.00674269 0.00261838 -0.00786856 -0.00176616 0.00564664 -0.0345646 -0.0240044 -0.0148234 -0.0133658 -0.00412353 0.0369617 0.00196105 0.0368174 0.00564198 -0.0501549 -0.0297051 0.0178704 0.0210161 -0.0155626 -0.00837293 -0.0178571 0.00812323 0.00816448 0.00151141 0.0221456 -0.00390799 0.026406 0.0064334 -0.00797861 -0.0261832 0.013857 -0.0837799 -0.0591936 -0.120175 1.27127))
+(7.76696 0.0131245 0.041107 #(-0.0123117 0.00617644 -0.00098044 0.00751582 -0.00251782 -0.00337365 -0.00106648 -0.00202962 0.024234 0.000865013 -0.000377017 0.00388929 -0.00333191 0.0133695 -0.00022004 -0.00378028 -0.00320862 -0.00759729 0.010062 -0.0256383 -0.0192849 -0.0214377 -0.0114302 -0.00124626 0.00155824 0.0193932 0.00236924 0.0225305 0.00325289 -0.026002 -0.0156565 0.0123504 0.013013 -0.00652565 -0.00493443 -0.0110295 -0.00472477 0.0120849 0.0080524 0.00918786 -0.00908903 0.0273415 -0.00444183 -0.0233399 -0.0047778 -0.00719849 -0.0426428 -0.018549 -0.0650151 1.15688))
+(8.89632 0.0142545 0.0400286 #(-0.00575181 0.0168131 -0.000191827 -0.023498 -0.00423681 0.025755 -0.0183111 -0.00376236 0.0252077 0.008183 -0.0122062 -0.003721 0.00288939 0.0148372 0.00886276 0.00423061 -0.00963574 0.000873132 0.00541097 -0.0280967 -0.00998672 -0.0238806 -0.0217161 -0.00753574 0.000230236 0.0280799 -0.00512027 0.00849866 0.0322065 -0.0343016 -0.00927757 0.00120511 0.0135002 -0.00237087 -0.0093355 -0.00156968 -0.00792312 0.012794 0.00838747 -0.0119611 0.00605868 -0.00193377 0.0117903 0.00816965 -0.0157005 -0.000300004 -0.0367019 -0.0246368 -0.0709357 1.15223))
+(9.78194 0.0170927 0.0418016 #(-0.0124638 0.0024989 -0.00185738 -0.00369259 -0.00329147 0.0015451 0.00184027 0.00970003 0.0141567 0.0120678 0.00775671 -0.00277263 0.00105104 0.000310846 0.00513042 -0.0141369 -0.008812 0.00521768 -0.00206552 -0.00604551 -0.0120649 -0.0176494 -0.0204137 -0.0115251 0.00627893 0.0162767 0.0108663 0.00560173 0.00467505 -0.02242 -0.0112209 0.000456198 0.00829053 2.30481e-005 0.00913467 -0.00846952 0.00517986 0.00864013 -0.00133154 0.00581594 -0.00610526 0.00869507 0.00727336 -0.00365842 -0.0143366 -0.0169279 -0.0336561 -0.0311221 -0.071088 1.16895))
+(11.5445 0.0160741 0.0373143 #(-0.0249007 -0.00275895 -0.000517276 0.00756758 -0.00172192 0.0176724 0.00486407 0.00102775 0.0190812 0.027876 -0.00029893 -0.00443258 -0.00532617 -0.0133783 -0.00615458 -0.00822798 -0.00903328 0.00488343 0.0122464 -0.0119956 -0.0122127 -0.0164293 -0.0183456 -0.00082874 -0.00101657 0.00939199 0.0092591 0.0164931 -0.0114048 -0.0252425 -0.0161846 -0.00699262 0.00668263 0.0180297 0.000800448 0.00638066 0.00681553 0.0168308 0.0103385 -0.00081722 -0.00148622 0.00392006 -0.00755191 -0.0011792 -0.0241647 -0.0123012 -0.0393747 -0.0402423 -0.0754633 1.19146))
+(13.3295 0.0127553 0.0309342 #(-0.0231698 0.0191559 -0.0139377 0.0092944 0.0121271 -0.000232179 -0.0124583 0.0134314 0.0164421 0.024357 -7.36386e-005 -0.0199401 -0.00337023 0.0151218 -0.00455778 -0.0115682 -0.0172743 0.000976708 0.017724 -0.0074562 -0.0285266 -0.0151716 -0.030822 0.00497904 0.00790638 0.0099445 0.0162362 0.0264739 0.0175367 -0.0501894 -0.0343044 -0.00901378 0.014952 0.0105903 -0.0101648 -0.000755211 0.0171476 0.0293293 0.00838466 -0.0102206 0.00315026 0.0306831 -0.00269206 0.00531439 -0.0326658 -0.0252288 -0.0474296 -0.0704353 -0.143764 1.28812))
+(15.3429 0.0120405 0.0280135 #(-0.0309064 0.0271264 0.0147487 0.00498133 0.00106183 0.0147637 -0.040844 -0.0169095 0.0389369 0.0194572 -0.00221378 -0.0170094 -0.00138509 0.0162374 0.00582746 -0.0230331 -0.0117961 -0.00156591 0.0229133 0.027122 -0.0540262 -0.0410968 -0.013133 -0.00158327 -0.0109391 0.0261228 0.0330272 0.0405228 0.0323432 -0.0623613 -0.0561195 -0.00527043 0.00668445 0.0267738 -0.00936441 -0.0283996 0.0234758 0.0255722 0.014511 -0.0129606 0.00174176 0.0403901 0.0353441 -0.000116604 -0.0455759 -0.0479024 -0.0481118 -0.0843258 -0.209947 1.37135))
+(17.6721 0.019402 0.0331344 #(-0.0350609 0.0339703 0.0145886 0.000690795 0.000922172 0.00738286 -0.01517 -0.0088783 0.0201723 0.0122574 -0.0158588 -0.0119165 -0.0019645 0.020945 -0.000870479 -0.0108681 -0.00586048 0.00538485 0.0104022 -0.00321434 -0.0157964 -0.0469299 -0.0215821 -0.00373954 0.00283885 0.0148254 0.0275313 0.0364303 0.0161417 -0.0308895 -0.0417433 -0.00377748 0.0165364 0.00397155 -0.0227846 -0.0260575 0.00618754 0.0551286 0.0147865 -0.0176932 0.00941883 0.0495573 0.031147 -0.00860301 -0.0380403 -0.0458936 -0.0610949 -0.096874 -0.18716 1.3588))
+(20.0442 0.0140521 0.0264774 #(-0.0709867 0.0453836 0.0460421 0.0146813 -0.0179832 0.00433517 -0.0165851 -0.00628279 0.0245804 0.0150767 -0.0114593 -0.0368579 0.00386748 0.0248403 0.00774181 -0.0237615 -0.0110972 0.00908011 0.0143327 0.012267 0.00781146 -0.0256289 -0.0705544 -0.0244927 -0.0213969 0.0392408 0.0426976 0.0769561 0.011974 -0.0784876 -0.0580746 0.0130622 0.0449024 0.0142022 -0.0384532 -0.0269607 0.00680663 0.0207385 0.0149218 -0.0149792 0.0278171 0.0648385 0.0568704 -0.00419316 -0.0892845 -0.0271809 -0.0635848 -0.137194 -0.290703 1.49428))
+(22.8017 0.0273646 0.0346427 #(-0.0720317 0.0448821 0.0348815 0.0233662 -0.000985435 0.00226309 -0.0135519 -0.0209769 0.0167468 0.0101012 -0.0194102 -0.00439263 0.00504041 0.0156837 0.00598467 -0.0264652 -0.0115608 0.0185426 -0.0068165 0.0100013 -0.00188157 -0.018496 -0.0458203 -0.0312296 -0.00116534 0.0335279 0.0330629 0.0395021 0.0183978 -0.0427994 -0.0459782 0.0054253 0.0243994 -0.00582722 -0.0111125 -0.0241409 0.0054475 0.0251814 0.00891366 -0.000905372 0.0228307 0.0523174 0.0382179 -0.00320691 -0.0354807 -0.0419394 -0.0835182 -0.139596 -0.249583 1.45587))
+(26.3474 0.0219953 0.0288932 #(-0.0765435 0.0426832 0.0419785 0.0283921 0.00340572 -0.00535423 -0.0212032 -0.0116924 0.00206213 0.00816488 -0.0127589 0.00934433 0.0163962 0.00930891 -0.00568188 -0.0355663 -0.0130979 0.0042239 0.0221761 0.0294585 -0.00590132 -0.0300225 -0.0529725 -0.04428 -0.00514512 0.0547305 0.0372759 0.0478592 0.0239117 -0.0702372 -0.0687804 0.0195622 0.0191373 0.0223794 0.0135526 -0.038104 -0.00282542 0.00433172 0.00929822 -0.00582157 0.0154465 0.0665377 0.0342229 0.00927136 -0.0205276 -0.0192793 -0.0956723 -0.177253 -0.343554 1.56045))
+(30.1984 0.030065 0.0315528 #(-0.0979213 0.0706986 0.0397353 0.027229 -0.00146723 -0.00438662 -0.0236935 -0.0188674 0.00900385 0.011066 0.00529251 -0.00704211 0.00609007 0.00670222 0.011048 -0.0216173 -0.0263168 0.00421382 0.0169606 0.0205924 -0.018071 -0.0136472 -0.0356033 -0.0382373 0.00240587 0.00751786 0.0412371 0.0584634 0.033329 -0.0663578 -0.0641406 -0.00811986 0.0285871 0.0444783 -0.00260303 -0.0335565 -0.018181 0.00985673 0.00558086 0.0118218 0.023386 0.0433098 0.0400329 0.0116843 -0.0148176 -0.058095 -0.0779079 -0.157939 -0.31358 1.52513))
+(32.1428 0.0318259 0.0314665 #(-0.0775589 0.051683 0.0288251 0.0187194 0.00984706 0.00338128 -0.0202275 -0.00651548 0.0136416 -0.00760369 0.00215332 -0.0233182 0.0134451 0.0247162 -0.00404254 -0.0118734 -0.018538 0.0113604 0.00736548 0.00204067 -0.0115196 -0.0197442 -0.0154772 -0.0363295 -0.0150368 0.0175515 0.0394107 0.053815 0.00585165 -0.0330152 -0.054677 -0.0159929 0.0341672 0.015965 -0.00299163 -0.0189119 -0.0067154 0.0143037 -0.000256563 -0.00532035 0.0260945 0.0429435 0.0476952 0.0109455 -0.0235557 -0.0298008 -0.0826709 -0.176099 -0.325686 1.54201))
+(31.4202 0.0318335 0.0318301 #(-0.0971744 0.0647286 0.0577288 0.0197214 -0.00649152 -0.0216951 -0.0189122 0.00437908 0.0284074 -0.000966733 -0.0171446 -0.0107114 0.00440035 0.0142388 0.00532634 -0.0126468 -0.02169 0.00523199 0.0297256 2.45184e-005 -0.00810739 -0.0215433 -0.0335994 -0.053856 -0.00465438 0.037238 0.0491757 0.0548962 0.014561 -0.073022 -0.0403319 -0.0130117 0.00834094 0.0434427 -0.00417276 -0.0078477 -0.0118494 0.00744896 -0.00313036 -0.0123154 0.0214602 0.059643 0.056315 0.00853147 -0.0377529 -0.0250175 -0.0860953 -0.178818 -0.327932 1.55029))
+(32.4444 0.0301064 0.0304621 #(-0.0807 0.057348 0.0412646 0.0366669 -0.00996071 -0.0130091 -0.0387371 -0.00774177 0.0350818 0.0241313 -0.0154081 -0.0231186 0.00127267 0.0151109 -0.000317825 -0.0114935 -0.0136006 -0.00971232 0.0131985 0.0123626 0.0233086 -0.0265093 -0.0606854 -0.0258504 -0.0165391 0.0251411 0.0470309 0.053574 0.0180307 -0.0502542 -0.0485886 -0.0164236 0.019835 0.0329606 -0.00101179 -0.0302517 -0.0018849 0.0308459 -0.00743693 -0.0159462 0.0094627 0.0539938 0.0554317 0.0208811 -0.0307534 -0.0204858 -0.0821197 -0.181269 -0.37734 1.5857))
+(40.9172 0.0650495 0.0398721 #(-0.0572582 0.0414552 0.0350494 0.0183922 0.00440463 -0.00850967 -0.00613651 -0.0179503 -0.00262387 0.0195232 -0.0131559 -0.00454892 0.00177392 0.0065445 0.00194393 -0.00781929 -0.00616173 -0.00313379 -0.000702812 -0.00178652 -0.014563 -0.0209123 -0.0269462 -0.0162782 0.00491859 0.0228838 0.0258315 0.027738 0.00459301 -0.0176909 -0.0295674 -0.0017052 0.0107792 -0.00448647 -0.00151116 -0.00392171 -0.00643332 0.00597558 0.0150378 0.0149934 0.0222908 0.0451681 0.0323751 0.00353828 -0.0263688 -0.050642 -0.0923144 -0.142247 -0.194605 1.40832))
+(42.9245 0.0380718 0.0297817 #(-0.0619835 0.0538987 0.0254833 0.0191851 0.000713942 -0.00965684 -0.0114323 -0.0178469 0.0175577 0.0131995 -0.0072923 -0.00832834 -0.00811007 0.00959091 0.00557504 -0.00996733 -0.00855112 -0.00974844 0.00913783 0.0117909 -0.0045425 -0.0256592 -0.0292943 -0.0307577 -0.00238131 0.0201101 0.0259082 0.0446931 0.0181626 -0.0452096 -0.0297406 -0.0143662 0.023201 0.0203186 -0.00421108 -0.0211625 -0.00441318 0.019116 0.000645667 -0.00607597 0.0221206 0.0483723 0.0479185 0.015123 -0.02304 -0.0353189 -0.100976 -0.171954 -0.291149 1.51649))
+(35.4435 0.0741689 0.0457449 #(-0.0592469 0.0408393 0.0310192 0.0213087 0.000897261 -0.0097075 -0.0127374 0.00034184 0.00697528 0.00416767 -0.00709337 -0.00543548 -0.00262597 -0.000460251 0.00462508 -0.000103108 -0.00210094 -0.000600998 -0.0064083 -0.00812498 -0.0110879 -0.014929 -0.0210607 -0.0126928 -0.00625044 0.0121755 0.0253735 0.0353037 0.00209597 -0.0177743 -0.0179092 -0.0111032 0.00635534 -0.000694276 -0.00804003 -0.00382186 0.00598897 0.00926817 0.00874331 0.0115986 0.0207321 0.0434171 0.0317387 0.00501884 -0.0295828 -0.0488442 -0.0859817 -0.140721 -0.179372 1.38875))
+(31.5655 0.0508454 0.0401347 #(-0.0590031 0.0481201 0.0415922 0.0145118 -0.00625927 -0.010634 -0.022698 0.00794115 0.0129372 0.011031 -0.00684227 -0.0269145 0.000574552 0.0097944 0.00870401 -0.0154143 -0.00608816 -0.00337432 0.00658044 -0.000562268 -0.0114323 -0.0168882 -0.0267139 -0.0354475 -0.00491647 0.0324642 0.0368173 0.0353376 5.39129e-005 -0.039796 -0.021031 -0.00123375 0.0136188 -0.00348024 -0.00871654 0.00380723 0.0164729 0.0135323 -0.00439517 -0.0080045 0.0109003 0.0528155 0.0444091 0.0206946 -0.0118078 -0.0443984 -0.10415 -0.168437 -0.257971 1.47706))
+(30.9527 0.0382595 0.0351577 #(-0.0677928 0.0651594 0.0430938 0.00356799 -0.0158889 0.000628987 -0.0127898 -0.00558382 0.0158968 -0.00226313 -0.00538957 -0.00778266 0.00155987 0.00443769 0.00375692 -0.0105507 -0.0224075 0.00426307 0.00792974 0.000294564 -0.000787178 -0.0161313 -0.0342735 -0.0403149 -0.00675935 0.0293195 0.0435918 0.0478281 0.00545949 -0.0534773 -0.037442 -0.0111263 0.0321929 0.020819 -0.00755799 -0.00482975 -0.00528935 0.0154923 0.00365394 -0.00549552 0.0121106 0.053678 0.0478409 0.019575 -0.0286409 -0.0335462 -0.0765612 -0.177995 -0.331 1.53233))
+(31.4075 0.0364452 0.0340646 #(-0.0649986 0.0576299 0.0324902 0.00773543 -0.00458665 0.00495247 -0.0191388 0.000145591 0.000613326 0.00395394 0.000636622 -0.0207581 0.00467082 0.0155624 0.0110861 -0.0131649 -0.0232556 -0.00176555 0.00395216 0.00802351 -0.00893858 -0.021152 -0.016588 -0.0283998 -0.0138537 0.0249458 0.0287153 0.0452579 0.0204232 -0.053952 -0.0535749 0.00280977 0.0440965 0.0328232 -0.0150095 -0.0388665 -0.0096805 0.0162576 0.0154429 -0.00290426 0.029801 0.0596534 0.0460045 -0.00865289 -0.0497685 -0.0141297 -0.0805603 -0.160605 -0.335686 1.53526))
+(31.6576 0.0348485 0.0331782 #(-0.0618954 0.0523533 0.0235303 0.0153525 0.00172889 -0.00168407 -0.0110182 -0.0142045 0.0170727 1.99435e-006 0.0017121 -0.0190737 -0.0111033 0.0169703 0.0280168 -0.01063 -0.0322064 0.00426402 -0.00485 0.0146215 -0.00758876 -0.0226077 -0.0252398 -0.0189545 -0.00568113 0.00980641 0.0269183 0.0392206 0.0257317 -0.0475402 -0.0534524 0.00178895 0.0586262 0.0278462 -0.0327184 -0.0414883 -0.0120922 0.029826 0.0131607 0.00598402 0.00931486 0.0642811 0.057244 -0.00679361 -0.0464739 -0.04173 -0.072625 -0.161229 -0.31275 1.52407))
+(34.7383 0.0559897 0.0401467 #(-0.0415582 0.026703 0.0259679 0.0111422 0.00204608 -0.00618647 -0.00950887 0.0120808 0.0102095 -0.00150538 -0.0114168 -0.0193223 -0.00463892 0.0133971 0.0187653 -0.00583736 -0.0127744 -0.0100488 0.0111868 0.0106626 -0.0205418 -0.0312655 -0.0304695 -0.0160161 -0.00137347 0.0194299 0.0309445 0.0366569 0.00705069 -0.0166283 -0.0404884 -0.00764167 0.0169512 0.0132674 -0.00907035 -0.0275286 -0.0054365 0.0307347 0.0158178 0.00474018 0.0264909 0.0460957 0.0291759 -0.00850643 -0.0359522 -0.0586856 -0.0731063 -0.11696 -0.205816 1.40186))
+(36.4119 0.0463771 0.0356887 #(-0.0389951 0.0307876 0.0205879 0.00908905 0.00555359 -0.0121034 -0.00687764 0.00752914 0.0176609 0.00566536 -0.0208413 -0.0229413 0.00156059 0.00543264 0.00694066 0.00249693 -0.00335328 0.000401892 0.0138262 0.00128668 -0.0283111 -0.0256373 -0.0237493 -0.0291584 -0.00703129 0.0152271 0.0393229 0.0452958 0.0231804 -0.0291094 -0.0417306 -0.00489797 0.0160917 0.000583816 -0.0194554 -0.0235409 0.00563181 0.0393978 0.0237208 -0.00447947 0.0171657 0.0551852 0.0282278 -0.022097 -0.0371377 -0.0598215 -0.0687185 -0.118988 -0.195594 1.40087))
+(31.5195 0.0823719 0.0511211 #(-0.0506811 0.032627 0.0260271 0.0133287 0.00707792 -0.00716418 -0.00792555 -0.00164158 4.37169e-005 0.00655899 -0.00403331 -0.00510847 -0.00250636 0.00465444 0.012035 0.0010902 -0.00567664 -0.00723898 -0.00466529 -0.00771452 -0.0268553 -0.0264261 -0.00282889 0.000687852 0.00062155 0.00777579 0.0113666 0.0250398 0.020167 -0.0104087 -0.0261586 -0.0112883 -0.00423545 0.0070317 -0.000811418 -0.0200803 0.00317688 0.0237687 0.0201803 0.0121356 0.0175142 0.033371 0.0253085 -0.00456846 -0.0415392 -0.0596395 -0.0783815 -0.0936876 -0.114877 1.30627))
+(25.4029 0.0602808 0.0487134 #(-0.0551556 0.0394576 0.0270103 0.0236226 0.00186073 -0.00761447 -0.00740441 -0.00712806 0.00591052 -0.00309897 -0.00157216 -0.0120145 -0.00111416 0.0139671 0.00880658 -0.0012513 0.00244409 -0.0133322 -0.00925009 0.00123142 -0.034305 -0.0168858 -0.00914378 -0.0110158 0.000306792 0.0116358 0.0236282 0.0251389 0.00218792 -0.00727665 -0.0207191 -0.00825958 0.00274023 -0.00288428 -0.00666814 -0.0172675 0.00904082 0.0154382 0.0150386 0.0254515 0.0314402 0.0294853 0.0295901 -0.00445611 -0.0469681 -0.0574121 -0.0877862 -0.106583 -0.135491 1.339))
+(22.7468 0.078061 0.0585811 #(-0.04486 0.0298865 0.0293551 0.0157202 0.00558635 -0.00166327 -0.0153884 -0.00699228 0.00676223 0.00247051 -0.00958823 -0.00736895 0.00134663 0.00697311 0.0112086 -0.000206178 -0.00881016 -0.00624388 -0.00932781 -0.0197023 -0.0190608 -0.011131 -0.0120463 0.000508607 0.00205883 0.0130596 0.00678453 0.017637 0.0173591 -0.00929612 -0.0146321 -0.00917131 -0.0076256 0.0010683 -0.00392937 -0.00849227 0.006057 0.0173038 0.0170559 0.0185356 0.0307804 0.0321241 0.0197208 -0.00024348 -0.0379323 -0.0627024 -0.0771216 -0.096205 -0.116027 1.29578))
+(22.8884 0.0716601 0.055954 #(-0.0482403 0.0307585 0.0275873 0.0182651 0.000529184 -0.0022478 -0.00768153 -0.00720601 0.00320312 0.000542559 -0.00613952 -0.00509576 0.000853576 0.00746592 0.00241067 0.00149092 -0.0103518 -0.00548361 0.00260866 -0.00854271 -0.0165325 -0.024049 -0.0159926 -0.0106845 0.00539235 0.0217353 0.013189 0.0138549 0.0113874 -0.00669787 -0.0144154 -0.00952096 -0.00989752 0.000984178 -0.00567269 -0.0075391 0.00597343 0.0157336 0.0231019 0.0212661 0.0260539 0.0267702 0.0234177 -0.00360673 -0.0411499 -0.0479637 -0.0797028 -0.101779 -0.123467 1.30416))
+(25.0679 0.0404904 0.04019 #(-0.0569264 0.0393012 0.0442286 0.0105388 -0.0280166 0.0130403 -0.000293758 0.00097423 0.0019422 -0.0135517 -0.0129558 -0.00137247 0.0176797 0.0111486 -0.00223964 -0.00550807 -0.00602055 -0.00683842 -0.0111893 0.0040559 -0.00320025 -0.0210676 -0.0166252 -0.0273107 -0.00925243 0.0352852 0.0153395 0.028238 0.0100151 -0.0296035 -0.0250562 0.00185137 0.0255143 0.00681541 -0.0269629 -0.0225865 0.00339151 0.0176583 0.0135256 0.0128693 0.0308694 0.0396139 0.0268478 -0.00453411 -0.0321182 -0.0411832 -0.0894552 -0.13549 -0.18868 1.40068))
+(26.172 0.0414675 0.0398048 #(-0.0630411 0.0445934 0.0340673 0.0179641 -0.0126086 -0.000847251 0.000227371 0.00106207 0.0131494 -0.0118745 -0.0160848 -0.00908814 0.00502605 0.0118554 0.0134411 0.006348 -0.0203072 1.60219e-005 -0.0092216 -0.0131313 0.00614179 -0.023434 -0.0225044 -0.0205765 -0.00759216 0.0190882 0.0216325 0.0341826 0.0139076 -0.0241181 -0.0163891 -0.0082327 0.0124357 -0.00390939 -0.0224453 -0.0154005 0.00127452 0.0147405 0.0170827 0.0260113 0.0421892 0.0303767 0.0235349 -0.0138023 -0.0474366 -0.0434775 -0.0753137 -0.111706 -0.172436 1.36862))
+(24.9425 0.0127896 0.0226443 #(-0.0733194 0.0354206 0.0577736 0.0308347 -0.0289842 -0.00604918 -0.014531 -0.0101977 0.0240066 0.0242339 -0.0217081 -0.0255996 0.00547605 0.0210583 0.0282309 -0.0144568 -0.0284572 -0.0338683 0.0165173 0.0371958 0.00744609 0.00585112 -0.0600074 -0.0549116 0.000340121 0.0385451 -0.00124994 0.0513382 0.0555081 -0.0592178 -0.0733577 -0.0170409 0.0586459 0.0553344 -0.0225186 -0.0556362 -0.0233135 0.0506938 -0.00436045 -0.0332437 0.00902178 0.0879455 0.0599741 -0.000640262 -0.0442607 -0.0220114 -0.0610923 -0.165358 -0.458725 1.64915))
+(22.7641 0.0174743 0.027706 #(-0.0584102 0.0459445 0.031618 0.0172284 -0.0102017 -0.00307119 -0.0147159 -0.0128069 0.0192186 0.0263737 -0.0162587 -0.0214138 -0.00164627 0.0164729 0.0190751 -0.00745766 -0.0243652 -0.0185078 -0.0136905 0.043886 0.0129518 -0.0298972 -0.0265289 -0.0403765 -0.00958069 0.0232809 0.0161453 0.044125 0.0361099 -0.0522329 -0.0619475 -0.000899218 0.0508566 0.0368301 -0.0180012 -0.0430501 -0.00970191 0.00226846 0.0163143 0.00440859 0.00654716 0.0745107 0.0559268 -0.0237278 -0.0297872 -0.0202482 -0.0711893 -0.150335 -0.394529 1.58051))
+(19.5777 0.0125371 0.0253057 #(-0.0826795 0.0683275 0.0428367 0.02936 -0.021953 -0.0169267 -0.0348315 -0.00679442 0.025703 0.045118 -0.00592805 -0.0419876 -0.00936561 0.0199536 0.035517 -0.0131276 -0.0408877 -0.0219309 0.0500002 -0.0214081 0.0310525 -0.0126166 -0.046124 -0.0345309 -0.027267 0.0407647 0.00779675 0.0551954 0.0525408 -0.0538993 -0.0680158 -0.0475148 0.0549138 0.0610506 0.00643009 -0.0500036 -0.0294172 0.0234389 0.0124404 -0.0212963 0.0223014 0.0563873 0.0415865 0.0218463 -0.0398211 0.00419091 -0.103894 -0.150699 -0.43171 1.62141))
+(18.2418 0.0253117 0.0372501 #(-0.0607523 0.0562677 0.0384613 0.00424439 -0.0162383 -0.00801906 -0.00889723 -0.00153158 0.0178735 0.00687857 -0.00841403 -0.0109761 -0.000752748 0.0188549 0.0145737 -0.0116472 -0.0244779 -0.0102738 0.00684694 -0.00289441 -0.0144796 -0.0119951 -0.0216497 -0.0176858 0.000835 0.00693356 0.0142641 0.0338318 0.0169442 -0.0304174 -0.03766 -0.00345847 0.0310024 0.00119207 -0.0121249 -0.0113758 -0.00784907 0.0241519 0.0161341 0.0165755 0.0178807 0.0323894 0.0223039 0.0113459 -0.0211709 -0.0354951 -0.0753201 -0.130449 -0.212926 1.39061))
+(18.2633 0.0252861 0.0372093 #(-0.045203 0.0314978 0.0349495 0.00211169 -0.00893727 0.00352343 -0.0123056 -0.00291805 0.0126091 0.00904179 -0.00646769 -0.0145041 -0.00502528 0.0120276 0.0164997 -0.0114284 -0.0165834 -0.00612101 0.0129625 0.0025109 -0.0220033 -0.00506117 -0.0341916 -0.0253116 0.0116913 0.0206707 0.00947406 0.0215501 0.018648 -0.0253815 -0.0210033 -0.00128285 0.00803003 0.00165846 -0.00961188 -0.0112029 -0.00390969 0.018762 0.0176612 0.0141336 0.0162613 0.0423988 0.0169786 0.00664183 -0.0149723 -0.0514017 -0.0758318 -0.125953 -0.214712 1.39864))
+(17.5015 0.0281862 0.0401311 #(-0.0467037 0.0285618 0.0290192 0.00889659 0.00523947 -0.0106185 -0.00584188 0.00343646 0.0078645 0.00378798 -0.0136156 -0.012084 0.00284047 0.0112584 0.00930852 -0.0112164 -0.00383024 -0.00982824 0.0153711 -0.00475254 -0.018373 -0.0203009 -0.0232701 -0.0175478 0.00286289 0.0183034 0.0126237 0.036949 0.00550275 -0.0201175 -0.0171514 0.000764537 0.00264071 -0.0167697 -0.00575089 -0.00377642 -0.00121029 0.0205625 0.019458 0.00863159 0.025104 0.0386815 0.0262647 -0.00411803 -0.0406888 -0.0471502 -0.083648 -0.103756 -0.174039 1.36212))
+(17.2526 0.0295366 0.0413764 #(-0.0459645 0.0347026 0.0174516 0.0140821 0.00442935 -0.00595253 0.000786888 -0.00770935 0.00586936 0.00240675 0.00201615 -0.0114029 -0.00715992 0.0219725 0.00668619 -0.00508303 -0.0104611 -0.00929612 -0.00120529 -0.00989537 -0.0169932 -0.0133932 -0.0188951 -0.000876892 -0.000297876 0.000200907 0.0129674 0.0262989 0.00787067 -0.0241803 -0.0115058 -0.000143185 0.0150916 0.0138443 -0.0335769 -0.0206819 -0.00174932 0.0245576 0.0198266 0.017498 0.020447 0.0325335 0.0246589 0.00835593 -0.033657 -0.0520807 -0.0742558 -0.105502 -0.158577 1.3385))
+(17.7939 0.0194564 0.0330671 #(-0.0393023 0.0249954 0.0281254 0.00881808 -0.0170303 -0.000254086 -0.0238422 0.0104953 0.0267727 0.0218212 -0.00832039 -0.0378733 -0.00966003 0.0208957 0.0258569 0.00523595 -0.0125616 -0.0198685 -0.00261361 0.0267587 -0.00756953 -0.0295961 -0.0220904 -0.0216108 -0.022352 0.010996 0.018242 0.0477541 0.0378138 -0.0342758 -0.0460006 -0.0110206 0.0200271 0.0216202 -0.0010694 -0.0481358 -0.00989713 0.0183853 0.0178495 0.0123016 0.00932306 0.0462944 0.0355045 0.00738312 -0.0433972 -0.0431022 -0.0752448 -0.111662 -0.22808 1.41783))
+(16.2645 0.0198753 0.0349571 #(-0.0444276 0.0359794 0.0176339 0.0166024 -0.00509977 -0.00228653 -0.0161215 0.0145134 0.0174299 0.000749843 -0.00504707 -0.026946 -0.00241593 0.0172678 0.024325 -0.00596551 -0.0248575 -0.0135324 0.0111395 0.00225044 -0.0129778 -0.0134113 -0.0270257 -0.0234719 -0.000202711 0.0218519 0.00693315 0.0315688 0.0147574 -0.0374582 -0.0197909 -0.0087806 0.0357156 0.00379843 -0.0129535 -0.0288524 -0.0066429 0.02112 0.00394448 0.0222445 0.0191879 0.0458149 0.0290641 0.00188522 -0.0291704 -0.0394177 -0.0755161 -0.123621 -0.231673 1.41693))
+(13.9843 0.0203448 0.0381422 #(-0.0406508 0.0247845 0.0280528 0.016247 -0.00667394 0.00575473 -0.00883099 -0.00538796 0.0124414 0.00246849 -0.0144231 -0.0122821 5.65498e-006 0.0240839 0.00861459 -0.00217033 -0.0235125 -0.0168742 0.0055966 -0.00328378 -0.00988276 -0.0124962 -0.0202922 -0.0046567 0.00286656 0.0025336 0.000137633 0.0296567 0.0200221 -0.0189908 -0.0237597 -0.000666055 0.0173422 0.0148898 -0.028545 -0.0280338 -0.00862389 0.0107104 0.0292579 0.0223673 0.0356336 0.027171 0.0365469 -0.00876548 -0.0413912 -0.0440555 -0.0862704 -0.0992445 -0.175119 1.36053))
+(13.7519 0.0318418 0.0481192 #(-0.0439203 0.0286811 0.019099 0.0131209 0.00116507 0.00239283 -0.00349781 -0.00764389 0.00731754 0.00111961 -0.0119648 -0.0166307 0.0112826 0.0209392 0.00437699 0.00510248 -0.00768695 -0.0223086 -0.0103192 -0.00707175 -0.0131623 -0.0187769 0.00250121 -0.00532104 -0.0114664 0.00451569 0.0158921 0.0267952 0.00829616 -0.0112708 -0.0156018 -0.00644018 0.00364066 -0.00682353 -0.0102232 -0.0152849 -0.00104906 0.0131723 0.0312335 0.0306407 0.0224566 0.0393104 0.00734389 -0.0167909 -0.0521184 -0.0325935 -0.0547162 -0.0785076 -0.107318 1.25643))
+(14.1001 0.036371 0.0507887 #(-0.0416909 0.0311513 0.0216856 0.010757 0.0023053 -0.00539498 -0.0122303 -0.00307753 0.0143497 -0.0013006 -0.00140553 -0.0114054 0.00277976 0.0180154 0.00290372 -0.000693336 -0.0231679 -0.00686742 -0.00978564 -0.00577415 -0.00821437 -0.0128852 -0.00872088 -0.0119665 0.00729519 0.00605096 0.00574081 0.0229577 0.00811213 -0.0167 -0.00908976 0.00335362 -0.00364028 -0.00150706 -0.00937789 -0.0185555 -0.000902989 0.0273121 0.0204276 0.0180267 0.0271863 0.0347298 0.0131781 -0.0189297 -0.042958 -0.0488664 -0.0552135 -0.0687342 -0.0978135 1.24792))
+(14.2751 0.0340747 0.048857 #(-0.0375261 0.024581 0.0173357 0.0105803 0.00152478 5.81223e-005 -0.0049663 0.000233414 -0.0059578 0.0172982 -0.0123975 -0.0121001 0.00817213 0.00614464 0.0063125 0.00277281 -0.0072908 -0.00298882 -0.00532286 -0.0151193 -0.0130224 -0.0190079 -0.00477871 -0.00682809 -0.00484661 0.0136435 0.0106479 0.0201277 0.016766 -0.0148155 -0.0230016 0.0010569 0.00368719 -0.00836747 -0.0108471 -0.0115598 -0.000523546 0.020508 0.0238148 0.0105346 0.0278912 0.030346 0.015747 -0.00584426 -0.0429999 -0.0557868 -0.0671162 -0.0745447 -0.115248 1.28424))
+(15.2833 0.022009 0.0379483 #(-0.0444502 0.0319226 0.0206898 0.00408402 0.0038444 0.00518289 -0.0102187 0.00644884 0.0154201 0.00243678 -0.0155881 -0.0226183 -0.00535144 0.0143481 0.0263679 -0.00816404 -0.00439294 -0.00726711 0.00245852 -0.0075432 -0.0210695 -0.022927 -0.0121272 -0.00257655 -0.0142863 0.0116892 0.0195945 0.0314798 0.0171628 -0.026222 -0.0236029 -0.00279915 0.0139127 -0.00411994 -0.0220793 -0.0223499 0.0130053 0.0163297 0.014851 0.0168635 0.030113 0.0393203 0.0185481 -0.0032677 -0.0508295 -0.049786 -0.0681459 -0.100596 -0.141854 1.3324))
+(16.2369 0.0167683 0.0321361 #(-0.0461453 0.0336128 0.0171639 0.00638196 0.00304988 0.00700732 -0.0124934 -0.0014443 0.0229149 0.00812651 -0.0156464 -0.027978 0.00155632 0.0148617 0.0236262 -0.0053183 -0.0306435 0.0156539 0.00576177 -0.00936416 -0.019092 -0.0214782 -0.0106117 -0.0139679 -0.00487678 0.0153928 -0.000839796 0.0328364 0.0370444 -0.0267438 -0.0258321 -0.0084227 0.00140206 0.0170352 -0.0249207 -0.0137748 0.00622318 0.00877071 0.0176743 0.0140944 0.0160371 0.0299227 0.0280204 0.00486572 -0.0471303 -0.0549004 -0.0792787 -0.0862093 -0.156202 1.34944))
+(15.8715 0.00862119 0.0233064 #(-0.0416665 0.0196847 0.0351245 0.00540738 0.000268711 0.000455022 -0.00585776 -0.00906765 0.019069 0.0231938 -0.0242396 -0.0320143 0.00375507 0.0115636 0.0160781 -0.00497688 0.0104297 -0.0136434 0.0112971 0.000516813 -0.0335269 -0.00981996 -0.0165414 -0.0128344 -0.00386654 0.0142686 -0.0124378 0.0254652 0.0577827 -0.0404511 -0.0399016 0.00257038 0.0284287 0.00205934 -0.00698707 -0.0282862 -0.0129552 0.0375839 -0.00052652 -0.00139833 0.010455 0.0601005 0.027725 0.00917528 -0.0452916 -0.0495308 -0.114218 -0.0824053 -0.228428 1.43507))
+(14.8358 0.0137405 0.030433 #(-0.035238 0.0325776 0.00811017 0.00564153 0.00956963 0.00160376 -0.00735718 -0.0106363 0.00927161 0.0156551 -0.014077 -0.0256614 0.00892661 0.0141185 0.0219964 0.00497017 -0.0213388 -0.00393183 0.00307147 -0.00527207 -0.00932004 -0.0149748 -0.0293915 -0.0137217 0.0110029 0.00820573 -0.00731358 0.0228706 0.0342061 -0.0270083 -0.0231551 -0.00456665 0.0112681 -0.00073322 -0.00608638 -0.0299522 0.00616215 0.0218085 0.0147894 0.01267 0.0171617 0.0382049 0.0155666 0.00222878 -0.0301421 -0.0626113 -0.101723 -0.0618076 -0.14028 1.33014))
+(12.9037 0.0170322 0.0363311 #(-0.0361427 0.0205666 0.0172627 0.017552 -0.00678439 0.00380304 -0.00573859 0.00913126 0.0155822 -0.00543546 -0.00759378 -0.0190302 -0.00357661 0.0192382 0.00804061 0.000652122 0.000361389 -0.0179953 -0.00446666 0.00560995 -0.0184849 -0.0113776 -0.0232038 -0.00865374 -0.000620224 0.00406897 0.00305195 0.0334702 0.0202773 -0.0270967 -0.0247178 0.00910172 -0.000104248 0.000138012 -0.0102208 -0.0169238 0.00120545 0.0203969 0.0133169 0.0181668 0.0202681 0.0266863 0.021128 -0.0131285 -0.0365628 -0.0378504 -0.0756192 -0.0782206 -0.137483 1.31255))
+(10.7606 0.0176641 0.0405161 #(-0.0483414 0.0247989 0.0315676 0.00585319 -0.00234617 0.009571 0.00527321 -0.010687 0.0163059 0.00885164 -0.0125577 -0.0134762 -0.00967633 0.0164184 0.00952228 -0.00630756 -0.0123339 0.00271924 -0.00671046 -0.0020015 -0.00886391 -0.0281787 -0.0135787 -0.0134191 0.00144693 0.00931767 0.000242524 0.0183011 0.0329657 -0.0164957 -0.0380229 0.00540505 0.0215291 -0.00189809 -0.0201857 -0.0100815 0.00201447 0.0118938 0.00726428 0.0202927 0.0107608 0.0392477 0.0177106 -0.00825438 -0.0278289 -0.0360925 -0.0803767 -0.0690058 -0.118693 1.27992))
+(9.692 0.0163592 0.0410842 #(-0.0435487 0.0238735 0.0221766 0.0130095 -0.0102838 0.0102648 -0.00263138 0.00405493 0.0139175 0.00368894 -0.0144828 -0.0187693 0.000191167 0.0191079 0.0188621 -0.00391941 -0.0163057 -0.0108496 0.0112138 -0.0054916 -0.0242603 -0.0107545 -0.03524 -0.00986785 0.00436468 0.0159444 0.00288566 0.0280451 0.0177601 -0.0226378 -0.0232638 -0.00458616 0.0132367 -0.00669003 -0.00879428 -0.0174804 -0.00444567 0.0183938 0.0174463 0.0192643 0.0206223 0.0364433 0.00547454 0.00493223 -0.0256411 -0.0374557 -0.0770796 -0.0699102 -0.107736 1.2591))
+(10.6083 0.0116637 0.0331585 #(-0.0339536 0.0239064 0.0193139 -0.00206308 -0.00420809 0.0162964 -0.00446401 -0.00723342 0.032238 0.00872946 -0.0187994 -0.0242643 -0.0134408 0.0259891 0.0161434 0.00132369 -0.0197008 -0.00519451 0.00655926 -0.00738285 -0.0172127 -0.0237242 -0.0212511 -0.0206254 0.0103538 0.0122223 -0.00456432 0.0447003 0.0352811 -0.0406705 -0.0316736 0.00797188 0.00656864 -0.0115901 -0.0027629 -0.0128048 -0.00570429 0.0118761 0.0188073 0.0222462 0.0124456 0.0410702 0.00791332 -0.00379496 -0.0170523 -0.0476136 -0.0781826 -0.0542285 -0.143112 1.28919))
+(13.6333 0.00775797 0.0238547 #(-0.0364152 0.0291058 0.0227928 0.00502204 -0.0253292 0.048831 -0.0291211 -0.014896 0.0320535 0.00774532 0.000503408 -0.0316866 -0.00546139 0.0360913 0.00840064 -0.0208066 -0.0145649 0.000116066 0.00307052 -0.0122648 -0.0118387 -0.0277435 -0.0112472 -0.0110968 0.0148855 -0.00123177 -0.021587 0.0284518 0.0631961 -0.0358807 -0.0443364 0.00976814 0.00940558 0.00815862 -0.0182798 -0.0167586 0.0109045 0.0136983 0.0074112 0.00384714 0.0165089 0.0481128 0.0182451 0.00169633 -0.0279793 -0.0379538 -0.093019 -0.0760834 -0.15798 1.33196))
+(14.9529 0.0090799 0.0246421 #(-0.0173912 0.0117589 0.0215592 -0.000100125 -0.00958332 0.0178238 -0.0220747 0.00944662 0.0241577 0.0100921 -0.0118245 -0.0308733 -0.0111011 0.0260419 0.0364623 -0.0174218 -0.0250652 -0.02109 0.0203074 0.00684312 -0.0399599 -0.0207732 -0.0171705 -0.0007063 0.00839398 0.0148383 -0.0116208 0.0395184 0.0320917 -0.0477367 -0.0288544 -0.013006 0.0343035 0.0151606 -0.0250012 -0.0238014 0.010687 0.0287551 0.00443121 -0.00885899 0.0187292 0.0305535 0.0398672 0.0256628 -0.0622547 -0.0391768 -0.0803045 -0.063373 -0.174028 1.33167))
+(15.4713 0.0103036 0.0258065 #(-0.0317778 0.0220012 0.023046 0.0107401 -0.00700271 0.0157947 -0.0168062 -0.0275037 0.0367403 0.0183112 -0.0155777 -0.0184876 0.00537082 0.00657688 0.00920857 -0.00738122 -0.0258576 -0.00495231 0.0158989 0.0138713 -0.0316929 -0.0372503 -0.00456503 0.00398878 -8.80907e-005 0.00931697 -0.0254795 0.0441872 0.0447222 -0.0413425 -0.0365677 -0.00544457 0.0244433 0.0112955 -0.0182531 -0.0124006 0.00266321 0.0168735 0.014526 -0.0109792 0.0141278 0.0440501 0.000770168 0.0424379 -0.0278247 -0.0526684 -0.0777227 -0.0873046 -0.175866 1.34552))
+(14.1187 0.00916422 0.0254771 #(-0.045858 0.0400202 0.0205128 0.00743514 -0.00145771 0.00837235 -0.0248272 -0.00172827 0.0233621 0.0100241 -0.0135858 -0.0126684 -0.00336266 0.0149539 0.0171219 -0.016675 -0.0227132 -0.000102549 0.020379 0.00582718 -0.016864 -0.0320013 -0.0340711 0.00940389 -0.00660789 0.0171697 -0.029894 0.0563412 0.0606243 -0.07549 -0.0483998 -0.000330146 0.0359239 0.0257492 -0.00142432 -0.0289091 -0.0018749 0.012466 0.00260386 -0.0152575 0.00862908 0.053457 0.03697 0.0345913 -0.0435553 -0.039316 -0.0996627 -0.0778146 -0.205904 1.3743))
+(12.5142 0.0109789 0.0296196 #(-0.0372881 0.0196089 0.0233113 0.000903561 -0.0047855 0.0192033 -0.00402685 -0.00304796 0.0072131 0.000961789 -0.00506267 -0.0118756 0.00342084 0.015397 0.00417627 0.00558174 -0.014547 -0.00178372 -0.00917506 0.0153024 -0.021183 -0.0321192 -0.0190146 -0.0116695 0.0083767 0.00252157 0.0031781 0.03148 0.0255226 -0.0305256 -0.0148153 0.00160903 0.010152 0.00196973 -0.0133266 -0.0138634 -0.0111339 0.0246016 0.00657759 0.0046415 0.0102237 0.0405588 0.0267124 -0.0205946 -0.0262742 -0.0302408 -0.0733365 -0.0751875 -0.141942 1.30887))
+(13.1881 0.0149057 0.033619 #(-0.0392646 0.0235916 0.0113109 0.0165674 0.000356377 0.0096727 -0.00454504 -0.0118521 0.0189847 5.30982e-006 -0.00576891 -0.00829558 -0.00267612 0.0116296 0.0180062 -0.00463104 -0.015852 -0.0119515 0.00220159 0.00224108 -0.027798 -0.0126524 -0.0149994 -0.00157439 -0.00384594 0.00016854 0.00338744 0.0262442 0.0138858 -0.0262235 -0.0060537 -0.000456936 0.0188089 0.00153812 -0.0108762 -0.0196819 -0.00571758 0.0244648 0.0111209 0.00558558 0.0127132 0.0348169 0.015571 -0.0175171 -0.0217261 -0.045869 -0.0708379 -0.0505154 -0.114525 1.26721))
+(12.7999 0.015072 0.0343149 #(-0.0333835 0.0122214 0.0259325 -0.000845576 -0.00411607 0.0249855 -0.00362802 -0.00123161 0.00374519 0.00881159 -0.00779002 -0.0221836 -0.00150112 0.0259934 0.00794084 -0.00206094 -0.0134564 -0.00876726 -0.00201227 -0.0224425 0.00930002 -0.0259136 -0.0165928 -0.00342897 -0.00262414 0.00704048 -0.00242533 0.0235934 0.0114056 -0.0151016 -0.0109616 0.00159531 0.0111167 -0.000793585 -0.00855475 -0.0193289 0.00818316 0.0173823 0.00418687 0.0104691 0.0231481 0.0104235 0.0158543 -0.00351913 -0.0424822 -0.0357488 -0.0522538 -0.0381995 -0.0936292 1.22602))
+(12.2473 0.0193377 0.0397359 #(-0.0208312 0.0113622 0.0107963 0.0102407 -0.0113957 0.00688707 0.00914879 -0.00983215 0.00520417 0.00334524 -0.0068846 -0.004754 -0.00291994 0.0137996 0.0146112 -0.00155131 -0.0176285 0.00365784 -0.0104858 -0.0192718 -0.000923549 -0.0131308 -0.0111267 -0.00719019 0.000579761 0.0111471 -0.00676168 0.0234209 0.0115352 -0.0168934 0.0025673 -0.00926516 0.00685466 -0.00665536 -0.00981694 0.000390394 0.00485606 0.00488992 0.00723448 0.0167406 0.00949511 0.00968203 0.0148381 -0.0192989 -0.0238238 -0.0274632 -0.0505583 -0.0318813 -0.0690697 1.18902))
+(12.5963 0.016594 0.0362957 #(-0.022897 0.0164408 0.00922307 0.00712825 0.00029965 0.0126678 -0.00781488 -0.00903336 0.00276701 0.00841422 -0.00438664 -0.00758085 0.00516114 0.00530365 0.00871018 -0.00177273 -0.00100205 -0.00497492 -0.00829477 -0.00643409 -0.0175788 -0.016037 -0.0116676 -0.00203718 -0.000523905 0.0101769 -0.00147634 0.0081845 0.0146411 -0.0119274 -0.00436797 -0.000224399 -0.00513704 -0.00984378 0.0115129 -0.0102507 0.00516442 0.00549147 0.00572397 0.0118901 0.0113157 0.0218897 0.00945389 -0.0113134 -0.0298536 -0.0302538 -0.053088 -0.0372686 -0.0642578 1.19366))
+(13.5525 0.01008 0.0272723 #(-0.0123657 0.0053427 0.019458 -0.0176663 -0.0176549 0.0404966 -0.00390325 -0.00579765 0.00887555 0.00317001 0.00172718 -0.00829583 0.010417 0.0153962 -0.00556122 -0.00680748 -0.00745445 -0.00852993 -0.00462103 -0.0159715 -0.000628177 -0.0183191 -0.0147015 -0.00193298 -0.00415885 0.0236506 -0.0098982 0.015603 0.0132994 -0.0134173 -0.00543716 0.00140853 -0.000410987 -0.0155814 -0.00399504 -0.000352762 -0.00284362 0.0100352 0.0139833 0.0156556 0.00280102 0.00782334 -5.04827e-005 -0.0182239 -0.0189623 -0.0239327 -0.0540221 -0.0168124 -0.0578101 1.18215))
+(12.068 0.00596845 0.0222389 #(-0.00770466 -0.00247063 0.020446 -0.00341433 -0.0175267 0.0299728 -0.00334073 -0.021708 0.0222189 0.00349176 -0.00219307 0.000507939 -0.000906229 0.0251413 -0.00347692 -0.0193672 -0.008356 0.0107288 -0.00522202 -0.0373399 0.0110019 0.00334983 -0.0260176 -0.00508717 0.0076833 0.0123874 -0.0218113 0.0217126 0.0137616 -0.0343426 0.00107652 -0.0108971 0.00723602 -0.0140256 0.00945629 0.008111 -0.013161 0.0263409 0.00322294 0.0169951 0.0125402 0.00634017 -0.0281478 0.00833678 -0.0210252 -0.0480639 -0.0657505 0.00962592 -0.0670183 1.193))
+(8.95623 0.00286173 0.0178752 #(-0.0299596 -0.00271054 0.0316405 0.00830122 -0.0430843 0.052154 0.00778072 -0.0218403 0.015222 0.00900955 0.000450335 -0.0294424 0.0109118 0.0305165 0.0185617 -0.0211344 -0.00754338 0.000348268 -0.015125 0.000259483 -0.00953378 0.00744751 -0.0392438 -0.0133562 -0.0140394 0.0473366 -0.0574915 0.0274957 0.0739216 -0.0633229 -0.00625577 -0.00332914 0.0318236 -0.039495 -0.0259531 0.0239393 -0.0180297 0.0156937 0.0245471 0.0241233 0.00445331 0.0143366 -0.0112595 0.0136985 -0.0568217 -0.0400073 -0.106216 0.040655 -0.0915969 1.22924))
+(6.49921 0.00445611 0.0261847 #(-0.0170517 -0.0101715 0.0184278 0.00588615 -0.0192503 0.0377397 -0.00414877 -0.0237132 0.0261238 0.0049736 -0.00638682 0.00527185 -0.00923617 0.0111306 0.0255296 -0.0039067 -0.0151077 0.00377979 7.06266e-005 -0.0208127 0.00467839 -0.022734 -0.0168833 -0.00336075 -0.01055 0.033853 -0.0379811 0.010155 0.0492233 -0.0412482 -0.00933746 -0.0204949 0.0208357 0.00125835 -0.0115378 -0.000968487 0.00445165 0.00835097 0.00622662 0.0115168 0.000545416 0.00342692 -0.00927968 0.0260598 -0.0528268 -0.0332704 -0.0524391 0.0325668 -0.0789734 1.17526))
+(5.25729 0.00395311 0.0274213 #(-0.0240403 0.0205123 0.0153895 -0.0123595 -0.0220413 0.0554869 -0.00704868 -0.0433425 0.0501927 -0.00331648 -0.0181042 -0.0055328 -0.0079657 0.0218988 0.0184512 0.000216515 -0.0131423 -0.00679136 0.0172376 -0.0200239 0.00385909 -0.0187232 -0.0339574 -0.0205053 0.00639417 0.0217717 -0.022982 0.0227078 0.0735146 -0.0648862 -0.0373938 0.00153798 0.00527095 0.0142592 -0.0107342 -0.0298141 0.00548001 0.0163492 -0.00212356 0.00278833 0.0101466 0.0397622 0.0149 0.023642 -0.01529 -0.0428728 -0.0909119 0.00412615 -0.130688 1.23334))
+(4.64889 0.00405787 0.0295443 #(-0.0083154 0.00615811 0.0229795 -0.0118895 -0.011159 0.0234972 -0.00391371 -0.0106054 0.0152195 0.0045161 -0.0309345 -0.0133451 0.0142733 0.0022754 0.0224104 0.00053866 -0.0105869 0.014126 -0.00594441 -0.016928 0.000217074 -0.00374499 -0.0370543 -0.0101543 -0.0131152 0.0467066 -0.0290259 0.0361985 0.048131 -0.0712857 -0.010248 0.0200725 -0.00527912 -0.033853 0.00625684 -0.0132771 -0.00059062 0.00807303 0.0207666 -0.005388 0.00403096 0.0390784 0.0263475 0.00420176 -0.0247701 -0.0169901 -0.0981137 0.00202813 -0.122794 1.22287))
+(4.2687 0.00527028 0.0351374 #(0.0119431 0.000370011 0.00297805 -0.0086345 -0.00619318 0.0209268 -0.0214211 -0.00264095 0.000795118 0.0018904 0.00504403 -0.00221174 0.000734628 0.0115394 0.00269348 0.00862158 -0.0112626 0.0128954 -0.0100209 -0.0261409 -0.00341844 -0.00612675 -0.023003 0.0109423 -0.00282099 0.0203828 -0.0265252 0.0270202 0.0322998 -0.0362086 -0.00119129 -0.0153138 -0.00350063 0.00240223 -0.0210972 -0.00135233 -0.00711855 0.000712969 0.0123906 -0.00078104 0.000209776 0.0312843 -0.00727613 0.0274143 -0.0141633 -0.0350039 -0.0442454 0.0167168 -0.0482093 1.11671))
+(5.08667 0.00434494 0.0292264 #(-0.00272251 0.00941567 0.00822995 -0.014127 -0.00472909 0.0256388 -0.0205545 -0.00637778 -0.0112651 0.0378657 -0.0158337 -0.00984417 0.00216444 0.030978 -0.00207667 -0.00625094 -0.00241573 0.000887676 -0.0113091 -0.0167408 -0.00726853 -0.00532588 -0.0106122 0.000375745 -0.00057362 0.0254724 -0.018358 0.0306097 0.0326059 -0.0225176 -0.0471872 0.00568396 -0.0101327 -0.0167238 -0.0112461 -0.0017848 -0.00424018 0.0120333 0.0037898 0.0135469 0.0227388 0.0193921 -0.0318962 0.0246949 -0.0262602 -0.0227707 -0.0672516 0.0572928 -0.0571018 1.11738))
+(5.64243 0.00660276 0.0342082 #(0.00180166 0.00187813 0.00574493 -0.000219231 -0.0214208 0.0292124 -0.0171232 -0.0116133 0.0143524 -0.0080191 0.00040181 -0.000264368 0.00500117 0.0156718 0.00494422 0.00107104 -0.0174182 0.00156305 -0.00116767 -0.0143132 -0.00873124 0.00879861 -0.0235025 -0.00555377 0.0159542 0.0120798 -0.00968709 0.0101018 0.0241207 -0.0283285 -0.00464771 0.00488285 -0.0317064 0.000691314 -0.0122031 -0.0076785 0.00264264 0.00947001 0.0122303 0.00967777 0.0183964 0.00361356 -0.0121287 0.0116267 -0.0186891 -0.0143781 -0.0485434 0.0242676 -0.0335089 1.09521))
+(4.34906 0.00506972 0.0341424 #(0.0023974 -0.00279862 0.0120042 -0.00157989 -0.0157521 0.0239786 -0.0126398 -0.0135926 -0.0020871 0.00151955 -0.00174203 -0.00773394 0.0159697 0.00780768 0.021657 0.00663021 -0.0142795 0.00149963 -0.00494957 -0.00158777 -0.0254905 -0.0117564 -0.017529 -0.00628616 0.00849666 0.00422017 -0.0116558 0.0310608 0.0345892 -0.0316539 -0.0132967 -0.00584913 0.00354922 -0.0173338 -0.0110622 -0.0096414 0.00859083 -0.0039589 0.0226801 0.0154026 0.00896204 0.0230092 0.00481482 0.00292927 -0.0234833 -0.0254714 -0.0981472 0.0441442 -0.0688532 1.14897))
+(2.61565 0.00474862 0.0426083 #(0.00879548 -0.00707132 0.0105265 0.00589761 -0.0181165 0.0122799 0.000610275 -0.0196829 -0.011157 0.0120507 -0.0115164 -0.0105635 0.0167566 0.0110644 0.0208706 0.00165262 0.00444448 -0.00889109 -0.00448973 -0.00204069 -0.0176097 -0.0204983 -0.00444134 -0.0102928 -0.000729621 0.00828533 -0.0156112 0.0249824 0.046813 -0.034427 -0.0110774 -0.0109798 -0.00690826 -0.00195731 -0.0157386 -0.00195138 0.00642795 -0.00283065 0.0119922 0.0211103 0.0124749 0.0247881 0.0132657 -0.00455936 -0.0371286 -0.0106291 -0.0739445 0.0263266 -0.0843839 1.15059))
+(2.02703 0.00255318 0.0354904 #(0.0134249 -0.00506588 0.00680395 0.0105582 -0.0323818 0.0493337 -0.0217674 -0.0241798 0.00928927 -0.023553 0.0104105 -0.0160771 0.00235487 0.00839372 0.0312377 0.00805041 0.000414273 -0.0136668 -0.0141831 0.0145558 -0.01835 -0.0176581 0.00780919 -0.0178566 -0.00798348 0.0228851 -0.0520132 0.0414188 0.066511 -0.0612651 0.00654983 -0.0331677 0.0129804 -0.0240143 0.0167766 -0.000209965 -0.0232557 0.0166038 0.0163538 0.0123617 -0.00410349 0.0241719 -0.00992855 0.0157116 -0.0186285 -0.0253129 -0.0767908 0.0521641 -0.0693304 1.12793))
+(2.64432 0.00171959 0.0255009 #(-0.0191815 0.0127539 0.0107323 0.00105373 -0.0253985 0.0548691 -0.00350344 -0.0407332 0.00805417 -0.00516293 0.0269923 -0.0481122 0.045745 -0.00949443 0.029402 0.00253762 -0.0224486 0.00621702 -0.0126075 -0.000360755 -0.0107886 -0.00802914 -0.0263488 -0.00418882 0.00777657 0.0122917 -0.0655835 0.0318259 0.0745041 -0.046913 -0.0178272 -0.014913 0.00287156 -0.0266232 0.016267 0.00797917 0.00580041 0.0114133 0.00738462 0.0441676 -0.0136994 0.0335519 -0.0324743 0.0188773 -0.0348701 -0.0234333 -0.174669 0.177908 -0.0964444 1.12857))
+(3.49525 0.0028907 0.0287582 #(-0.022997 0.00390569 0.0195987 -0.00368246 -0.0249804 0.0205793 -0.000749982 -0.0146779 0.0253093 -0.027436 -0.00506964 0.0229678 0.0122114 -0.00660955 0.0289347 0.00446956 -0.0240813 0.0124458 -0.000533498 -0.0357979 -0.00426894 0.00482643 -0.0216519 0.00376066 -0.0166858 0.0254196 -0.047756 0.0296842 0.05304 -0.053725 0.0233847 -0.00627376 -0.0327575 0.0242391 -0.00986949 0.0018908 0.0199183 -0.001377 0.00140167 0.0246927 0.00391399 0.00494078 -0.0242442 0.0174991 -0.0272264 -0.0343578 -0.0611368 0.0862893 -0.0566336 1.08269))
+(3.59173 0.00241115 0.0259096 #(-0.0280463 0.00239539 0.0275002 -0.0139323 -0.0348279 0.0607939 -0.0263654 -0.0111383 0.00125177 0.0134574 -0.0201514 0.0256755 0.0152298 -0.0129894 0.040595 -0.0242227 0.0223003 -0.0198948 -0.00945686 -0.0104881 -0.0149074 0.000106048 -0.0155021 0.00164234 -0.0275243 0.0334275 -0.0597113 0.0490029 0.0458835 -0.0406038 -0.00296535 0.00162114 0.00027736 -0.0194494 0.0124248 -0.00222679 0.0104655 -0.00167292 0.00815926 0.0283748 -0.0225562 0.0143205 -0.0188394 0.00579293 -0.0147764 -0.0167599 -0.050156 0.0847534 -0.0659405 1.07315))
+(2.26719 0.00255288 0.0335561 #(-0.0136514 -0.00925972 0.0167188 -0.00485284 -0.0336646 0.0412232 -0.000246899 -0.0298077 0.00712888 0.0134616 0.0103107 -0.00485241 -0.00127703 0.0164119 0.0132654 -0.019095 0.00456902 -0.00259853 -0.000275873 -0.0127027 -0.00593184 0.0101047 -0.0413224 0.018843 -0.0107773 0.0150738 -0.0289957 0.0254439 0.0380609 -0.0406301 -0.00392326 0.0172783 -0.00857435 -0.0223009 0.00749708 -0.0165367 0.0238457 0.018136 -0.00458933 0.00245699 0.00172918 0.00670983 -0.024566 0.00660529 -0.0205404 0.00950086 -0.0578217 0.0939725 -0.0510117 1.04425))
+(0.609353 0.00163717 0.0518337 #(0.00316256 -0.0122567 0.00518264 0.0126123 -0.0397706 0.0392831 0.0116002 -0.0471934 0.00805918 -0.00560564 0.000558784 -0.00409364 -0.00452707 -0.00113856 0.0257756 -0.00932488 0.00381936 -0.00247659 0.00301922 0.00335715 -0.00619763 0.0345422 -0.0321831 0.00519092 -0.00104381 -0.021393 -0.028818 0.0308446 0.0615516 -0.0569711 -0.0213437 0.00541473 0.00891156 -0.00345845 -0.00526036 -0.0140875 0.0217332 0.0150425 0.00302012 0.000750344 -0.0227373 0.0355403 -0.0606219 0.0543924 -0.0197096 0.0106198 -0.0761164 0.133679 -0.0540805 1.00403))
+(0.116473 0.000738204 0.0796116 #(-0.0020667 -0.00708028 0.00649903 0.00525495 -0.0577545 0.0708488 0.0241519 -0.0957537 0.0444855 0.00816514 -0.0260424 -0.00887706 0.0161092 -0.00643925 0.0365329 -0.0114855 -0.0214506 0.00323551 4.06337e-005 0.00984418 0.00579543 0.0340158 -0.0244511 -0.00303321 -0.0329481 0.0117391 -0.0672089 0.0657941 0.120411 -0.0823802 -0.0449917 0.00125354 0.00608117 -0.0209081 -0.0254859 0.0413741 -0.00546445 0.0228035 -0.0102555 0.0282721 -0.0411615 0.0264412 -0.0625765 0.0651369 -0.0960416 0.0914793 -0.12826 0.244372 -0.0968032 0.978677))
+(0.0472545 0.000482073 0.101003 #(-0.0132409 -0.00177229 -0.00651967 0.0181785 -0.057867 0.0886454 -0.0060562 -0.0415304 -0.00604645 0.00809692 -0.0261498 0.0308232 -0.0207518 0.039377 0.0286866 -0.00414628 -0.101779 0.0925687 -0.0566329 0.0285281 -0.0124488 0.0429751 -0.0231868 0.00492606 -0.0382182 0.0353667 -0.0854897 0.072105 0.138783 -0.152908 0.0118608 -0.0236536 0.0280545 -0.0358662 -0.00158007 0.0410328 -0.0307116 0.0351427 -0.0487812 0.0650863 -0.105127 0.0931477 -0.118991 0.157664 -0.204664 0.186411 -0.180145 0.351459 -0.130844 0.92427))
+(0.0200657 0.000490229 0.156305 #(-0.0167117 0.0226238 -0.0290179 0.0310399 -0.05596 0.0754746 -0.00102182 -0.0240663 -0.00557826 -0.00226293 0.00760277 0.00121096 -0.0371931 0.0368175 0.00439128 -0.00121828 -0.0701961 0.0851828 -0.0429475 0.0221135 -0.0202851 0.0294757 0.0173632 -0.014941 0.0101552 -0.0156045 -0.0714142 0.0373879 0.140392 -0.155288 0.0474913 -0.015392 0.010226 -0.0506144 0.00775825 0.0425248 -0.0111819 0.0198418 -0.0465491 0.0473969 -0.0958641 0.069069 -0.0800155 0.135248 -0.167486 0.159519 -0.163318 0.341011 -0.122999 0.899713))
+(0.0189561 0.000463645 0.156394 #(0.0136824 -0.010146 -0.00340101 0.00501791 -0.052312 0.0825702 -0.0198587 -0.00941267 0.00742931 -0.00822124 -0.00559287 0.0070671 -0.0295775 0.0163785 -0.000200317 -0.0124918 -0.0388802 0.0517694 -0.0148913 -0.0019372 0.0130002 0.0529274 -0.051331 0.0468511 -0.0493757 0.0488883 -0.0877978 0.0390208 0.120372 -0.130924 0.00454228 0.0284801 -0.0370236 -0.0207961 0.00413483 0.0556726 -0.0461664 0.043992 -0.0572133 0.0680651 -0.129146 0.0933036 -0.0903923 0.0963898 -0.115223 0.173486 -0.16108 0.327376 -0.109485 0.877362))
+(0.0157623 0.000457797 0.170422 #(0.00679172 0.0179331 -0.0180012 0.00985177 -0.0710897 0.0804711 -0.0138887 -0.00160079 -0.0130131 -0.0116605 -0.00195402 0.0102408 0.00544203 -0.00882841 -0.00664669 -0.000185585 -0.0333044 0.0571107 -0.0324269 0.00482369 0.00173713 0.0817342 -0.0689869 0.0314419 -0.0416472 0.0452527 -0.104628 0.0733021 0.109757 -0.112525 -0.040671 0.0457447 -0.033124 0.0189072 -0.0182032 0.0382207 -0.0430175 0.0633007 -0.0880582 0.0891837 -0.145313 0.126151 -0.130188 0.133809 -0.156576 0.210072 -0.192572 0.343954 -0.102867 0.867452))
+(0.0193939 0.000457706 0.153625 #(-0.00460792 0.0355563 -0.0550596 0.043009 -0.0897849 0.0978742 -0.0187992 0.00582897 -0.0109002 0.000631806 -0.0163601 0.0133513 -0.0165699 0.0221935 -0.0312557 0.04581 -0.0629084 0.0434437 -0.0167021 0.0323193 -0.0250667 0.0627469 -0.0306966 -0.00490861 -0.0368386 0.0217197 -0.0728413 0.0668549 0.145474 -0.169416 0.0122649 0.00448438 0.013949 -0.0353851 0.020688 0.00875267 -0.0340474 0.0569403 -0.0747049 0.0865628 -0.127027 0.0997718 -0.118786 0.172951 -0.208013 0.216935 -0.215728 0.401293 -0.19069 0.923122))
+(0.0267348 0.000456167 0.130624 #(0.0221721 0.012707 -0.0342673 0.0498141 -0.125798 0.0945948 -0.009383 -0.0118047 -0.00833615 0.0354772 -0.041698 0.0220065 -0.043747 0.0427328 -0.0334768 0.0279624 -0.0268537 0.00968139 0.00111546 0.0377293 -0.0348329 0.0808209 -0.0457136 0.00457449 -0.0453242 -0.0107467 -0.0188348 0.0300905 0.173791 -0.194862 0.0537233 -0.0419804 0.0496971 -0.0701674 0.0499813 -0.00747099 -0.0222291 0.0273433 -0.0549461 0.0661543 -0.122178 0.0944649 -0.101576 0.17229 -0.189446 0.207714 -0.21558 0.418696 -0.215629 0.931565))
+(0.0200745 0.000471228 0.153212 #(0.0163527 0.00660207 -0.0143944 0.046632 -0.126296 0.118434 -0.0369965 -0.00451566 -0.0201182 0.0417401 -0.0308534 -0.00543496 -0.0172945 0.0438493 -0.0319897 -0.0176332 -0.00909391 0.00684448 0.00776292 0.0226499 -0.00129345 0.0597638 -0.057499 0.0439582 -0.0376084 -0.009205 -0.0282326 0.0349981 0.136497 -0.137021 0.0108061 -0.0220325 0.0138336 -0.0341895 0.00554748 0.0125278 -0.0174402 0.0430164 -0.0595981 0.048263 -0.112704 0.102835 -0.101221 0.15651 -0.167554 0.189205 -0.200076 0.383302 -0.1668 0.902884))
+(0.0178948 0.000884452 0.222317 #(-0.00627428 0.017076 -0.0217517 0.0596357 -0.115011 0.137658 -0.140797 0.0413646 -0.025147 0.0409271 -0.0298679 0.0230878 -0.00804102 0.0133819 -0.0343905 0.081481 -0.0160831 0.031044 -0.0362416 0.0814956 -0.0892642 -0.0230409 -0.0232022 0.112084 -0.0729296 -0.0349948 0.00901226 -0.0373362 0.140441 -0.0702999 -0.00257567 -0.0348515 -0.00258082 0.0140751 -0.0718087 0.0880132 -0.061838 0.0690842 -0.118292 0.142831 -0.185955 0.190591 -0.155962 0.45873 -0.106312 0.127302 -0.523777 0.419269 -0.501987 1.22411))
+(0.014956 0.000914502 0.247278 #(-0.023965 0.0260125 -0.0174047 0.0515138 -0.0830966 0.07056 -0.0839288 -0.00253678 0.0274258 -0.000953763 -0.00370321 0.0051892 0.0273904 -0.020619 -0.0100326 0.0564985 0.00785514 0.0225726 -0.0248022 0.0636671 -0.0849298 -0.0493795 0.0247842 0.0783257 -0.054683 -0.0485245 0.00161631 -0.0165824 0.139226 -0.0743001 -0.00122059 -0.0566757 0.0247024 0.00172735 -0.0647441 0.0783151 -0.0575751 0.0609131 -0.105484 0.127889 -0.170536 0.193175 -0.164876 0.462587 -0.105663 0.112055 -0.495609 0.396188 -0.497893 1.21815))
+(0.00871568 0.000567858 0.255252 #(-0.0124666 0.0309579 -0.00109739 0.0135459 -0.057433 0.0477187 -0.0502651 0.00271826 0.0372547 0.0164188 -0.0446111 -0.0127535 -0.0377459 0.05085 -0.0332468 0.0648767 -0.0421368 0.0453716 -0.00560286 0.010505 -0.0502685 0.0272348 -0.0168195 0.0334298 -0.045445 0.0609193 -0.0939262 0.0603289 0.127758 -0.127759 -0.0161537 -0.0241133 0.0220789 0.0501327 -0.0297039 0.0276074 -0.0749799 0.0195223 -0.134458 0.0784379 -0.103965 0.143044 -0.0238226 0.243323 -0.14168 0.124602 -0.245754 0.281028 -0.225522 0.993662))
+(0.0086891 0.000454286 0.228653 #(0.000182833 -0.00254678 0.0082363 -0.0153415 -0.0299224 0.0849131 -0.0489407 0.00623273 0.00330074 0.015936 -0.0400408 -0.020401 -0.0247914 0.0710104 -0.015902 0.00164445 -0.0397469 0.0223963 0.0144133 0.00597068 -0.0101367 0.0517253 -0.0400181 0.0204692 -0.0703128 0.0792271 -0.0877888 0.0647522 0.100521 -0.114483 -0.00566729 -0.0255629 0.0314529 0.0182582 -0.0152464 0.0337968 -0.0685177 0.0350596 -0.0735331 0.0771414 -0.107742 0.0609778 -0.0612328 0.122617 -0.132552 0.162598 -0.143835 0.327107 -0.115002 0.855719))
diff --git a/demos/lpc_tutorial.htm b/demos/lpc_tutorial.htm
new file mode 100644
index 0000000..a6af640
--- /dev/null
+++ b/demos/lpc_tutorial.htm
@@ -0,0 +1,186 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Nyquist FFT and Inverse FFT Tutorial</title>
+</head>
+<body>
+
+<h1>
+Nyquist LPC Analysis and Synthesis</h1>
+Nyquist provides functions for LPC analysis and synthesis on streams of
+audio data. For analysis, the audio stream is broken into successive frames,
+each of which is analyzed, resulting in a small set of coefficients. For
+synthesis, these frames control a time-varying filter which can be applied
+to an audio signal.
+<p>As with FFT frames, Nyquist does not have a special data type corresponding
+to a sequence of LPC frames. Instead, a sequence of frames is represented
+by an XLISP object. Whenever you send the selector <tt>:next</tt> to the
+object, you get back either NIL, indicating the end of the sequence, or
+you get an LPC frame. (Note that FFT frames and LPC frames are not compatible.)
+<p>This tutorial is based on the file <tt>lpcdemo.lsp</tt> in the <tt>demos</tt>
+folder fo the Nyquist release. Not every line is covered, but this tutorial
+should give you a pretty full explanation of how to use LPC in Nyquist.
+<h2>
+Preliminaries</h2>
+Before using LPC functions, you must load the LPC library:
+<pre>(load "lpc")</pre>
+At the top of <tt>lpcdemo.lsp</tt>, you see the following lines:
+<pre>(setf *lpc-path* (current-path))
+(setf *lpc-data* (strcat *lpc-path* "lpc-exmpl.dat"))</pre>
+The <tt>(current-path)</tt> function call returns the full file system
+path to the file being loaded (<tt>lpcdemo.lsp</tt>). We save this into
+<tt>*lpc-path*</tt>
+so we can find other related files later, even if the current directory
+is changed. <tt>*lpc-data*</tt> is one of the file names we will use later.
+<h2>
+LPC Analysis</h2>
+Another file we want is <tt>a-snd-file.snd</tt>, a very short vocal sound
+that is part of the Nyquist release (it is also used by <tt>examples.lsp)</tt>.
+To get this file, we concatenate it with the path we obtained above. The
+resulting full path can be passed to <tt>s-read </tt>to read the sound.
+Find the expressions in the following function that build a file name and
+read the file as a sound:
+<pre>(defun do-lpc-analysis ()
+&nbsp; (let ((myfile (strcat *lpc-path* "a-snd-file.snd")))
+&nbsp;&nbsp;&nbsp; (save-lpc-file (make-lpanal-iterator (s-read *myfile*) 0.08 0.04 50)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "temp.dat")))</pre>
+You can analyze a sound using <tt>make-lpanal-iterator</tt>. This function
+takes a sound, a frame size, a step size, and the number of poles. In <tt>do-lpc-analysis</tt>
+(above), we used 0.08 seconds, 0.04 seconds, and 50 poles for these parameters.
+The result of <tt>make-lpanal-iterator</tt> is an object that will deliver
+LPC frames on demand. In this function, we will grab all of the frames
+and write them to a file using <tt>save-lpc-file</tt>. The data is written
+to <tt>"temp.dat"</tt>. You should run this function and look at the file,
+which contains ASCII data. Later, we will use this data to filter a sound.
+<p>Since <tt>a-snd-file.snd</tt> is a very short and uninteresting sound,
+we will use a different set of LPC frames in the following synthesis examples.
+The data is in <tt>lpc-exmpl.dat</tt>, and the full path for this file
+was computed earlier and stored in <tt>*lpc-data*</tt>.
+<p>The first example will just show how to read the LPC data file using
+<tt>make-lpc-file-iterator</tt>,
+which takes the file name as a parameter. You can print some frame data
+using <tt>show-lpc-data</tt> as shown in the following:
+<pre>(defun ex-1 ()&nbsp;
+&nbsp; (show-lpc-data (make-lpc-file-iterator *lpc-data*) 100 120 NIL))</pre>
+The additional parameters to <tt>show-lpc-data</tt> are the starting frame
+(100), the ending frame (120), and a flag (<tt>NIL</tt>)&nbsp; indicating
+whether to print filter coefficients. If you want to look a little closer
+at the inner workings of this code, you can send a <tt>:next</tt> message
+to an LPC iterator object as follows:
+<pre>(setf iterator (make-lpc-file-iterator *lpc-data*))
+(send iterator :next)</pre>
+This will return the first frame of the LPC analysis. Send <tt>:next</tt>
+again&nbsp; to get the next frame.
+<h2>
+LPC Synthesis With Fixed All-Pole Filter</h2>
+The next example creates a sequence of vowel sounds. The vowel filters
+are based on the
+<br>30th, 60th, and 100th frames taken from the file <tt>lpc-exmpl.dat</tt>.
+We use <tt>make-lpc-file-iterator</tt> as before to read the LPC frames
+from the file, but we use <tt>nth-frame</tt> to get the desired frames.
+<p>The function <tt>allpoles-from-lpc</tt> constructs a filter from the
+frame and applies it to a sound. In this case, the source sound is created
+by <tt>buzz</tt> with a little vibrato provided by <tt>lfo</tt>:
+<br>&nbsp;
+<pre>(defun ex-4 ()&nbsp;
+&nbsp; (play (seq
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (allpoles-from-lpc (buzz 12 f2 (lfo 5.0 4.0))&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (nth-frame (make-lpc-file-iterator *lpc-data*)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 30))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (allpoles-from-lpc (buzz 12 f2 (lfo 5.1 4.0))&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (nth-frame (make-lpc-file-iterator *lpc-data*)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 60))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (allpoles-from-lpc (buzz 12 g2 (lfo 5.3 4.0))&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (nth-frame (make-lpc-file-iterator *lpc-data*)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100)) )))</pre>
+Rather than iterate through a file to find the desired frame, you can also
+just store the desired frames as in the following:
+<pre>(setf a-lpcdata
+&nbsp; '(63.2144 0.674387 0.103287
+&nbsp;&nbsp;&nbsp; #(-0.0381026 0.00804115 0.0109905 0.0145117 0.00199174&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.00129314 0.0171826 0.0181176 0.00179391 -0.0114089&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0120949 -0.000410595 -0.0122539 -0.0209354 -0.00804976&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.00345041 -0.00409532 -0.00227011 0.014224 0.0135451
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0056023 -0.00651142 -0.00564953 -0.0168921 -0.0377939
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0449506 -0.0355592 -0.0339316 -0.0454434 1.19336)))</pre>
+
+<pre>(setf e-lpcdata
+&nbsp; '(40.7157 0.149753 0.0606467
+&nbsp;&nbsp;&nbsp; #(0.0244574 -0.0225545 -0.0172724 -0.0122709 -0.0042946
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00886974 0.0121516 0.0120936 0.00197545 -0.00582163
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.018367 -0.0201546 -0.00440599 0.00638936 0.0166275
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0185066 0.00890464 -0.00158013 -0.00494974 -0.00479037
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0130814 0.0138648 -0.0022018 -0.021368 -0.0343532&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0312712 -0.0574975 -0.0918824 -0.112016 1.31398)))</pre>
+
+<pre>(setf i-lpcdata
+&nbsp; '(5.5391 0.0321825 0.0762238&nbsp;
+&nbsp;&nbsp;&nbsp; #(-0.0341124 -0.0149688 -0.00585657 -0.0111572 0.00769712
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0190367 0.00885366 0.0112762 0.0118286 -0.00059044&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0140864 -0.0123688 -0.0151128 0.00214354 -0.00810219&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.00538188 0.00631382 0.020771 0.0356498 0.0295531
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0242797 0.0124296 0.00445127 -0.013062 -0.0387178&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -0.0527783 -0.0685511 -0.076575 -0.0846335 1.24521)))</pre>
+The following function applies a filter to noise:
+<pre>(defun noise-vocal (lpcdata dur)
+&nbsp; (allpoles-from-lpc (noise dur) lpcdata))</pre>
+Combining this with our definitions of different frames, we can write a
+little sequence
+<br>of vowel sounds:
+<pre>(defun ex-5 ()
+&nbsp; (play
+&nbsp;&nbsp;&nbsp; (seq (noise-vocal a-lpcdata 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (noise-vocal e-lpcdata 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (noise-vocal i-lpcdata 1))))</pre>
+We can do the same thing using a buzz sound rather than noise:
+<pre>(defun buzz-vocal (lpcdata dur)
+&nbsp; (allpoles-from-lpc (buzz 16 e2 (const 0.0 dur))
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpcdata))</pre>
+
+<pre>(defun ex-6 ()
+&nbsp; (play
+&nbsp;&nbsp;&nbsp;&nbsp; (seq (buzz-vocal a-lpcdata 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (buzz-vocal e-lpcdata 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (buzz-vocal i-lpcdata 1))))</pre>
+
+<h2>
+Time-Varying LPC Filter</h2>
+The most interesting LPC effect is to use a sequence of frames to drive
+a time-varying all-pole filter. If the frames were analyzed from a vocal
+source, then the resulting filter will transfer the speech articulation
+(or at least some of it) to another sound. The time-varying LPC filter
+is called <tt>lpreson</tt>.
+<p>Here, the LPC data from <tt>*lpc-data*</tt> is used to modulate noise:
+<pre>(defun ex-7a ()
+&nbsp; ;; parameters are sound, lpc-iterator, skiptime
+&nbsp; (lpreson (noise 6.5) (make-lpc-file-iterator *lpc-data*) 0.04))</pre>
+
+<pre>(defun ex-7 ()
+&nbsp; (play (ex-7a)))</pre>
+The same thing can be done to filter a buzz sound. This example generates
+some vocal-like sounds in two-part harmony:
+<br>(defun ex-8a (p dur)<br>
+&nbsp; (lpreson (buzz 16 p (scale 1.5 (lfo 3.0 dur)))&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (make-lpc-file-iterator
+*lpc-data*)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.04))<br>
+<br>
+(defun ex-8 ()<br>
+&nbsp; (play<br>
+&nbsp;&nbsp;&nbsp; (sim (seq (ex-8a c4 1) (ex-8a g3 1) (ex-8a a3 1) (ex-8a
+b3 1) (ex-8a c4 1))<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (seq (ex-8a c2 2) (ex-8a
+f2 1) (ex-8a g2 1) (ex-8a e2 1)))))<br>
+<br>
+Note that you can change the <i>skiptime</i> parameter to <tt>lpreson</tt>
+to change the rate at which the filter moves through the frames. The result
+is to caues the speech articulations to go faster or slower.
+<p>More examples can be found in <tt>lpcdemo.lsp</tt>.
+<h2>
+Acknowledgments</h2>
+Pedro J. Morales created the LPC functions for Nyquist and wrote <tt>lpcdemo.lsp</tt>
+on which this tutorial is based.
+</body>
+</html>
diff --git a/demos/lpcdemo.lsp b/demos/lpcdemo.lsp
new file mode 100644
index 0000000..b78c0f9
--- /dev/null
+++ b/demos/lpcdemo.lsp
@@ -0,0 +1,263 @@
+;;; LPC demo 1
+;;; Pedro J. Morales.
+;;; February, 04
+;;; Roger B. Dannenberg
+;;; July, 04
+
+; where is the file lpc-exmpl.dat
+(setf *lpc-path* (current-path))
+(setf *lpc-data* (strcat *lpc-path* "lpc-exmpl.dat"))
+
+
+; this file generated by Nyquist will be loaded by Octave (or Matlab)
+(setf *default-octave-file* (strcat *lpc-path* "nyquist.dat"))
+
+; make sure lpc.lsp is loaded
+(if (not (fboundp 'lpreson)) (load "lpc.lsp"))
+
+; file-io tools ========================================================
+
+
+(defun octave-1 (outf data varname datatype &optional (n 1000))
+ (prog ((points (case datatype
+ (SND (snd-samples data (1+ n)))
+ (ARR data)))
+ len)
+ (setf len (length points))
+ (cond ((> len n)
+ (setf len n)
+ (format t "WARNING: DATA TRUNCATED TO ~A POINTS~%" len)))
+ (format outf "# name: ~A\n" varname)
+ (format outf "# type: matrix\n# rows: 1\n# columns: ~A\n " len)
+ (dotimes (i len)
+ (format outf "~A " (aref points i)))
+ (format outf "\n")))
+
+(defun octave (data-lists) ; (data varname datatype &optional (n 1000))
+ (prog ((filename *default-octave-file*)
+ outf)
+ (setf outf (open filename :direction :output))
+ (cond ((null outf)
+ (format t "octave: could not open ~A!~%" filename)
+ (return nil)))
+ (format t "octave: writing ~A ... ~%" filename)
+ (cond ((null outf)
+ (format t "octave: could not open ~A!~%" filename)
+ (return nil)))
+ ;(format t "octave: writing ~A ... ~%" filename)
+ (dolist (l data-lists)
+ (apply #'octave-1 (cons outf l)))
+ (close outf)))
+
+
+; LPANAL ======================================================
+
+; get lpc data ---------------------------------------------------
+
+
+(defun do-lpc-analysis ()
+ (let ((myfile (strcat *lpc-path* "a-snd-file.snd")))
+ (save-lpc-file (make-lpanal-iterator (s-read *myfile*) 0.08 0.04 50)
+ "temp.dat")))
+
+
+; SHOW-LPC-DATA ------------------------------------------------
+; show values of LPC analysis frames ----------------------------
+
+
+(defun ex-1 ()
+ ; do not show filter coefs
+ (show-lpc-data (make-lpc-file-iterator *lpc-data*) 100 120 NIL))
+
+
+; ------- SAVE-FILE-DATA ---------------------------------------
+(defun ex-2 ()
+ (save-lpc-file (make-lpc-file-iterator *lpc-data*) "temp2.dat"))
+
+
+;----------- LPC-FREQ ------------------------------------------
+; LPC-FREQ. Show frequency response of ALLPOLES filter.
+; NEEDS MATLAB or OCTAVE
+;
+
+(defun ex-3 ()
+ (lpc-freq "frm70" (make-lpc-file-iterator *lpc-data*) 70))
+
+
+; in MATLAB/OCTAVE:
+; >> load -force nyquist.dat
+; >> [H,W] = freqz(1, frm70, 512);
+; >> plot(W,20*log10(abs(H)));
+
+
+;-------------------------------------------------------------------------
+; LPC-STABILITY Check for Stability of LPC filters
+; NEEDS MATLAB/OCTAVE
+
+; EXAMPLE
+
+; (ex-3)
+
+; in MATLAB/OCTAVE:
+; >> load -force nyquist.dat
+; >> find(abs(roots(frm70)) > 1)
+; if any abs root is > 1.0 then UNSTABLE
+
+;--------------------------------------------------------------------------
+; ALLPOLES LPC allpoles filter
+; WARNING: this is a static filter
+; for LPC resynthesis a dynamic LPC filter is needed
+
+
+; EXAMPLE
+
+(defun ex-4 ()
+ (play (seq
+ (allpoles-from-lpc (buzz 12 f2 (lfo 5.0 4.0))
+ (nth-frame (make-lpc-file-iterator *lpc-data*)
+ 30))
+ (allpoles-from-lpc (buzz 12 f2 (lfo 5.1 4.0))
+ (nth-frame (make-lpc-file-iterator *lpc-data*)
+ 60))
+ (allpoles-from-lpc (buzz 12 g2 (lfo 5.3 4.0))
+ (nth-frame (make-lpc-file-iterator *lpc-data*)
+ 100)) )))
+
+
+(setf a-lpcdata
+'(63.2144 0.674387 0.103287
+ #(-0.0381026 0.00804115 0.0109905 0.0145117 0.00199174 -0.00129314 0.0171826
+ 0.0181176 0.00179391 -0.0114089 -0.0120949 -0.000410595 -0.0122539
+ -0.0209354 -0.00804976 -0.00345041 -0.00409532 -0.00227011 0.014224 0.0135451
+ 0.0056023 -0.00651142 -0.00564953 -0.0168921 -0.0377939 -0.0449506 -0.0355592
+ -0.0339316 -0.0454434 1.19336)))
+
+(setf e-lpcdata
+'(40.7157 0.149753 0.0606467
+ #(0.0244574 -0.0225545 -0.0172724 -0.0122709 -0.0042946 0.00886974 0.0121516 0.0120936
+ 0.00197545 -0.00582163 -0.018367 -0.0201546 -0.00440599 0.00638936 0.0166275 0.0185066
+ 0.00890464 -0.00158013 -0.00494974 -0.00479037 0.0130814 0.0138648 -0.0022018 -0.021368
+ -0.0343532 -0.0312712 -0.0574975 -0.0918824 -0.112016 1.31398)))
+
+
+(setf i-lpcdata
+'(5.5391 0.0321825 0.0762238 #(-0.0341124 -0.0149688 -0.00585657 -0.0111572
+ 0.00769712 0.0190367 0.00885366 0.0112762 0.0118286 -0.00059044 -0.0140864 -0.0123688
+ -0.0151128 0.00214354 -0.00810219 -0.00538188 0.00631382 0.020771 0.0356498 0.0295531
+ 0.0242797 0.0124296 0.00445127 -0.013062 -0.0387178 -0.0527783 -0.0685511 -0.076575
+ -0.0846335 1.24521)))
+
+(defun noise-vocal (lpcdata dur)
+ (allpoles-from-lpc (noise dur) lpcdata))
+
+(defun ex-5 ()
+ (play
+ (seq (noise-vocal a-lpcdata 1)
+ (noise-vocal e-lpcdata 1)
+ (noise-vocal i-lpcdata 1))))
+
+(defun buzz-vocal (lpcdata dur)
+ (allpoles-from-lpc (buzz 16 e2 (const 0.0 dur))
+ lpcdata))
+
+(defun ex-6 ()
+ (play
+ (seq (buzz-vocal a-lpcdata 1)
+ (buzz-vocal e-lpcdata 1)
+ (buzz-vocal i-lpcdata 1))))
+
+
+; ---- LPRESON ------------------------------------------------------------
+;
+(defun ex-7a ()
+ ;; parameters are sound, lpc-iterator, skiptime
+ (lpreson (noise 6.5) (make-lpc-file-iterator *lpc-data*) 0.04))
+
+(defun ex-7 ()
+ (play (ex-7a)))
+
+(defun ex-8a (p dur)
+ (lpreson (buzz 16 p (scale 1.5 (lfo 3.0 dur)))
+ (make-lpc-file-iterator *lpc-data*)
+ 0.04))
+
+(defun ex-8 ()
+ (play
+ (sim (seq (ex-8a c4 1) (ex-8a g3 1) (ex-8a a3 1) (ex-8a b3 1) (ex-8a c4 1))
+ (seq (ex-8a c2 2) (ex-8a f2 1) (ex-8a g2 1) (ex-8a e2 1)))))
+
+(defun noalias-buzz (p nmax)
+ (min
+ (round (/ *sound-srate* (* 2.0 (step-to-hz p))))
+ nmax))
+
+(defun ex-9a (p dur skiptime)
+ (mult (env 0.01 0.01 0.1 1.0 1.0 1.0 dur)
+ (lpreson (buzz (noalias-buzz p 16) p (scale 1.5 (lfo 3.0 dur)))
+ (make-lpc-file-iterator *lpc-data*)
+ skiptime)))
+
+
+(defun ex-9b (stretch skiptime)
+ (play
+ (sim (seq (ex-9a c4 (* 1 stretch) skiptime)
+ (ex-9a g3 (* 1 stretch) skiptime)
+ (ex-9a a3 (* 1 stretch) skiptime)
+ (ex-9a b3 (* 1 stretch) skiptime)
+ (ex-9a c4 (* 1 stretch) skiptime))
+ (seq (ex-9a c2 (* 2 stretch) skiptime)
+ (ex-9a f2 (* 1 stretch) skiptime)
+ (ex-9a g2 (* 1 stretch) skiptime)
+ (ex-9a e2 (* 1 stretch) skiptime)))))
+
+
+(defun ex-9 ()
+ (ex-9b 1.0 0.04))
+
+(defun ex-10 ()
+ (ex-9b 1.0 0.02))
+
+(defun ex-11 ()
+ (ex-9b 2.0 0.04))
+
+(defun ex-12 ()
+ (ex-9b 0.5 0.02))
+
+(defun ex-13 ()
+ (ex-9b 4 0.02))
+
+(defun ex-14a (p dur skiptime)
+ (mult (env 0.01 0.01 0.1 1.0 1.0 1.0 dur)
+ (lpreson (osc-saw (sim (step-to-hz (+ p 0)) (scale 1.5 (lfo 3.0 dur))))
+ (make-lpc-file-iterator *lpc-data*)
+ skiptime)))
+
+(defun ex-14b (stretch skiptime)
+ (play
+ (sim (seq (ex-14a c4 (* 1 stretch) skiptime)
+ (ex-14a g3 (* 1 stretch) skiptime)
+ (ex-14a a3 (* 1 stretch) skiptime)
+ (ex-14a b3 (* 1 stretch) skiptime)
+ (ex-14a c4 (* 1 stretch) skiptime))
+ (seq (ex-14a c2 (* 2 stretch) skiptime)
+ (ex-14a f2 (* 1 stretch) skiptime)
+ (ex-14a g2 (* 1 stretch) skiptime)
+ (ex-14a e2 (* 1 stretch) skiptime)))))
+
+
+(defun ex-14 ()
+ (ex-14b 1 0.04))
+
+(defun ex-15 ()
+ (ex-14b 4 0.02))
+
+(defun ex-16 ()
+ (ex-14b 8 0.08))
+
+
+
+
+
+
+
+
diff --git a/demos/mateos/bell.lsp b/demos/mateos/bell.lsp
new file mode 100644
index 0000000..ead4aa5
--- /dev/null
+++ b/demos/mateos/bell.lsp
@@ -0,0 +1,33 @@
+;; BELL INSTRUMENT
+;; Daniel Mateos - danielma@andrew.cmu.edu
+;; Instrument by Hans Mikelson, imported from CSOUND
+;; Website: http://www.adp-gmbh.ch/csound/instruments/
+;; Modified by Roger Dannenberg, Nov. 2005
+;; see also: demos/pmorales/b3.lsp,
+;; demos/pmorales/e2.lsp, and
+;; demos/pmoraels/partial.lsp
+;; This bell is closely related to FM-BELL in e2.lsp
+
+;; DMHM-BELL -- an FM bell sound
+;;
+;; so named to avoid naming conflicts with other bells
+;;
+(defun dmhm-bell (pitch)
+ (let ((imax 10) ; max amplitude
+ (ifq1 (hz-to-step (* (step-to-hz pitch) 5))) ; partials
+ (ifq2 (hz-to-step (* (step-to-hz pitch) 7)))
+ (aenv (pwevr 1 1 0.0001)) ; amplitude envelope
+ (adyn (mult (* imax ifq2) (pwevr 1 1 0.001)))) ; dynamics envelope
+ (mult aenv ; create a carrier modulated signal
+ (fmosc ifq1 (mult adyn (osc ifq2))))))
+
+
+;; Let's play this bell!!
+;;
+;; type (dmhm-bell-test) to play an example
+;;
+(defun dmhm-bell-test ()
+ (play (stretch 10 (dmhm-bell g1))))
+
+
+
diff --git a/demos/mateos/gong.lsp b/demos/mateos/gong.lsp
new file mode 100644
index 0000000..103c8eb
--- /dev/null
+++ b/demos/mateos/gong.lsp
@@ -0,0 +1,64 @@
+;; GONG INSTRUMENT (TAM TAM)
+;; Daniel Mateos - danielma@andrew.cmu.edu
+;; Instrument by Hans Mikelson, imported from CSOUND
+;; Website: http://www.adp-gmbh.ch/csound/instruments/
+;; Modified by Roger Dannenberg, Nov. 2005
+;; See also: demos/pmorales/b1.lsp
+
+
+;; DMHM-GONG -- an additive synthesis gong sound
+;;
+;; so named to avoid naming conflicts with other gongs
+;;
+(defun dmhm-gong (pitch)
+ (let* ((ifrq (step-to-hz pitch))
+ ;; frequencies of partials
+ (ifrq1 (* 1.0000 ifrq))
+ (ifrq2 (* 1.1541 ifrq))
+ (ifrq3 (* 1.6041 ifrq))
+ (ifrq4 (* 1.5208 ifrq))
+ (ifrq5 (* 1.4166 ifrq))
+ (ifrq6 (* 2.7916 ifrq))
+ (ifrq7 (* 3.3833 ifrq))
+
+ ;; amplitude of partials
+ (iamp1 1.0000)
+ (iamp2 0.8333)
+ (iamp3 0.6667)
+ (iamp4 1.0000)
+ (iamp5 0.3333)
+ (iamp6 0.3333)
+ (iamp7 0.3333)
+
+ ;; main envelope
+ (envelope (pwevr 1 1 0.001))
+
+ ;; partial envelopes
+ (aenv1 (mult iamp1 envelope))
+ (aenv2 (mult iamp2 envelope))
+ (aenv3 (mult iamp3 envelope))
+ (aenv4 (mult iamp4 envelope))
+ (aenv5 (mult iamp5 envelope))
+ (aenv6 (mult iamp6 envelope))
+ (aenv7 (mult iamp7 envelope)))
+
+ ;; sum the partials
+ (scale 0.25 ; normalize to about 1.0
+ (sim
+ (partial (hz-to-step ifrq1) aenv1)
+ (partial (hz-to-step ifrq2) aenv2)
+ (partial (hz-to-step ifrq3) aenv3)
+ (partial (hz-to-step ifrq4) aenv4)
+ (partial (hz-to-step ifrq5) aenv5)
+ (partial (hz-to-step ifrq6) aenv6)
+ (partial (hz-to-step ifrq7) aenv7)
+ ))))
+
+;; Let's play something!
+;;
+;; type (dmhm-gong-test) to play an example
+;;
+(defun dmhm-gong-test
+ (autonorm-off)
+ (play (stretch 10 (dmhm-gong a3))))
+
diff --git a/demos/mateos/organ.lsp b/demos/mateos/organ.lsp
new file mode 100644
index 0000000..fea0b7e
--- /dev/null
+++ b/demos/mateos/organ.lsp
@@ -0,0 +1,58 @@
+;; Daniel Mateos - danielma@andrew.cmu.edu
+;; Instrument by Hans Mikelson,
+;; imported from CSOUND
+;; Website: http://www.adp-gmbh.ch/csound/instruments/organ01.html
+;; This instrument really sounds as a real organ!!
+;; Modified by Roger Dannenberg, Nov. 2005
+
+
+;; Sound overtones
+(defun dmhm-overtones (freq)
+ (sim
+ (scale 0.8 (hzosc freq))
+ (scale 0.8 (hzosc (* freq 2)))
+ (scale 0.8 (hzosc (* freq 2.9966)))
+ (scale 0.8 (hzosc (* freq 4)))
+ (scale 0.3 (hzosc (* freq 5.9932)))
+ (scale 0.2 (hzosc (* freq 8)))
+ (scale 0.1 (hzosc (* freq 10.0794)))
+ (scale 0.1 (hzosc (* freq 11.9864)))
+ (scale 0.4 (hzosc (* freq 16)))))
+
+
+(defun dmhm-organ (pitch)
+ (mult 0.1 ;; normalize to about 1
+ (env 0.1 0 0.1 1 1 1)
+ (dmhm-overtones (step-to-hz pitch))))
+
+
+;; DMHM-ORGAN-TEST -- a small test program/demo
+;;
+;; The same score used by the CSOUND example.
+;;
+(defun dmhm-organ-test ()
+ (autonorm-off)
+ (play
+ (sim
+ (at 0
+ (stretch 1.98
+ (sim
+ (dmhm-organ c3)
+ (dmhm-organ e3)
+ (dmhm-organ g3)
+ (dmhm-organ as3))))
+
+ (at 2
+ (stretch 1.98
+ (sim
+ (dmhm-organ c3)
+ (dmhm-organ ds3)
+ (dmhm-organ f3)
+ (dmhm-organ a3))))
+
+ (at 4 (stretch 1.98 (dmhm-organ c3)))
+ (at 4 (stretch 0.1 (dmhm-organ ds3)))
+ (at 4.1 (stretch 1.88 (dmhm-organ e3)))
+ (at 4 (stretch 1.98 (dmhm-organ g3))))))
+
+
diff --git a/demos/mateos/tuba.lsp b/demos/mateos/tuba.lsp
new file mode 100644
index 0000000..51b44cb
--- /dev/null
+++ b/demos/mateos/tuba.lsp
@@ -0,0 +1,94 @@
+;; By Daniel Mateos - Feb 2005
+;; This FM sound is similar to that of the tuba.
+;; Therefore, intended mainly for low register.
+;; It is built upon a FM 8 parallel oscillator circuit.
+;; The attack will remain constant whatever the enviroment.
+;; Also, it is properly prepared for transposition.
+;; Modified by Roger Dannenberg, Nov 2005
+
+;; Variable amplitude & frequency oscillator
+(defun tuba-osc (amp freq)
+ (mult amp (hzosc freq)))
+
+
+;; Parallel 8 oscillators FM
+(defun tuba-eight-osc (acar fcar amod1 fmod1 amod2 fmod2 amod3 fmod3
+ amod4 fmod4 amod5 fmod5 amod6 fmod6 amod7 fmod7 amod8 fmod8)
+ (tuba-osc acar (sim fcar
+ (tuba-osc amod1 fmod1)
+ (tuba-osc amod2 fmod2)
+ (tuba-osc amod3 fmod3)
+ (tuba-osc amod4 fmod4)
+ (tuba-osc amod5 fmod5)
+ (tuba-osc amod6 fmod6)
+ (tuba-osc amod7 fmod7)
+ (tuba-osc amod8 fmod8))))
+
+
+;; Define amplitude envelope of each modulator
+(defun tuba-amod (numb)
+ (seq
+ (stretch-abs 1 (pwl (/ numb 10) 100))
+ (pwl 0 100 (- 1 (/ numb 10)))))
+
+
+;; Defines Amplitud envelope of carrier
+(defun tuba-acar ()
+ (seq
+ (stretch-abs 1 (pwl 0.1 0.8))
+ (pwl 0 0.8 0.7 0.8 0.9)))
+
+
+;; Defines frequency of each modulator
+(defun tuba-fmod (numb fcar)
+ (case numb
+ (1 (- fcar 2))
+ (2 (- (* fcar 4) 3))
+ (3 (- (* fcar 3) 2))
+ (4 (- (* fcar 5) 2))
+ (5 (- (* fcar 6) 2))
+ (6 (- (* fcar 7) 2))
+ (7 (- (* fcar 8) 2))
+ (8 (- (* fcar 9) 2))))
+
+
+;; DMHM-TUBA -- a tuba-like FM sound
+;;
+;; named dmhm-tuba to avoid name conflicts with other (possible) tubas
+;;
+(defun dmhm-tuba (fcar)
+ (setf transp (float (get-transpose)))
+ (cond ((> transp 0.0)
+ (setf fcar (float fcar))
+ (setf fcar (* fcar (expt 2.0 (/ transp 12.0)))) ))
+ (cond ((< transp 0.0)
+ (setf transp (* -1.0 transp))
+ (setf fcar (float fcar))
+ (setf fcar (/ fcar (expt 2.0 (/ transp 12.0)))) ))
+ (scale 0.8 ; normalize
+ (lp
+ (hp
+ (transpose-abs 0
+ (tuba-eight-osc (tuba-acar) fcar
+ (tuba-amod 1) (tuba-fmod 1 fcar)
+ (tuba-amod 2) (tuba-fmod 2 fcar)
+ (tuba-amod 3) (tuba-fmod 3 fcar)
+ (tuba-amod 4) (tuba-fmod 4 fcar)
+ (tuba-amod 5) (tuba-fmod 5 fcar)
+ (tuba-amod 6) (tuba-fmod 6 fcar)
+ (tuba-amod 7) (tuba-fmod 7 fcar)
+ (tuba-amod 8) (tuba-fmod 8 fcar)) )
+ 10)
+ 22000)))
+
+;; DMHM-TUBA-TEST -- play a sample of dm-tuba instrument
+;;
+(defun dmhm-tuba-test ()
+ (autonorm-off)
+ (play
+ (seq
+ (dm-tuba 70 )
+ (stretch 5 (dm-tuba 70))
+ (loud -10 (dm-tuba 70))
+ (transpose -10 (stretch 3 (dm-tuba 70))))))
+
diff --git a/demos/midi_tutorial.htm b/demos/midi_tutorial.htm
new file mode 100644
index 0000000..3f0f4a8
--- /dev/null
+++ b/demos/midi_tutorial.htm
@@ -0,0 +1,2 @@
+<html>
+ <head> <meta name="GENERATOR" content="Microsoft FrontPage 3.0"> <title>Midi Tutorial</title> </head> <body> <h1>Midi Tutorial</h1> <p>Nyquist can read and write midi files. Midi files are read into and written from a special XLisp data type called a <code>SEQ</code>, which is short for &quot;sequence&quot;. (This is not part of standard XLisp, but rather part of Nyquist.) Nyquist can examine the contents of a <code>SEQ</code> type, modify the <code>SEQ</code> by adding or deleting Midi notes and other messages. Finally, and perhaps most importantly, Nyquist can use the data in a <code>SEQ</code> type along with a sound behavior to generate sound. In other words, Nyquist can become a Midi synthesizer.</p> <h2>The <code>SEQ</code> Type</h2> <p>To create a <code>SEQ</code> data object:</p> <pre><strong>&gt; </strong>(setf my-seq (seq-create)) <strong>#&lt;SEQ:0x7a6f60&gt; &gt; </strong>(type-of my-seq) <strong>SEQ &gt;</strong></pre> <h2>Reading a Midi File</h2> <p>Once you have a sequence, you can read Midi data into it from a file. You do this in three steps. First, you open the file in binary mode (using <code>open-binary</code>, a Nyquist extension to XLisp). Then you read from the file. Finally, you (normally) close the file.</p> <pre>(setf midi-file (open-binary &quot;demo.mid&quot;)) (seq-read-smf my-seq midi-file) (close midi-file)</pre> <h2>Writing a Midi File</h2> <p>A sequence can be written to a file. First you open the file as a binary output file; then you write it; then you close it.</p> <pre>(setf midi-file (open-binary &quot;copy.mid&quot; :direction :output)) (seq-write-smf my-seq midi-file t) (close midi-file)</pre> <p>The result will not be a bit-for-bit copy of the original Midi file because the <code>SEQ</code> representation is not a complete representation of the Midi data. For example, the Midi file can contain headers and meta-data that is not captured by Nyquist. Nevertheless, the resulting Midi file should sound the same if you play it with a sequencer or Midi file player.</p> <h2>Writing a Text Representation</h2> <p>One very handy feature of the <code>SEQ</code> datatype is that it was originally developed for a text-based representation of files called the Adagio Score Language, or just &quot;Adagio.&quot; You can write an Adagio file from a sequence by opening a text file and calling <code>seq-write</code>.</p> <pre>(setf gio-file (open &quot;copy.gio&quot; :direction :output)) (seq-write my-seq gio-file) (close gio-file)</pre> <p>The basic format of the Adagio file is pretty intuitive, but you can find the full description in the CMU Midi Toolkit manual or in a chapter of the Nyquist manual, including the online version in HTML.</p> <h2>Reading an Adagio File</h2> <p>Because Adagio is text, you can easily edit them or compose your own Adagio file. You should be aware that Adagio supports numerical parameters, where pitch and duration are just numbers, <em>and symbolic parameter, </em>where a pitch might be <code>Bf4</code> (for B-flat above middle-C) and a duration might be <code>QT</code> (for a quarter note triplet). Symbolic parameters are especially convenient for manual entry of data. Once you have an Adagio file, you can create a sequence from it in Nyquist:</p> <pre>(setf seq-2 (seq-create)) (setf gio-file (open &quot;demo.gio&quot;)) (seq-read seq-2 gio-file) (close gio-file)</pre> <h2>Adding Notes to a <code>SEQ</code> Type</h2> <p>Although not originally intended for this purpose, XLisp and Nyquist form a powerful language for generating Midi files. These can then be played using a Midi synthesizer or using Nyquist, as will be illustrated later.</p> <p>To add notes to a sequence, you call <code>seq-insert-note</code> as illustrated in this routine, called <code>midinote</code>. Since <code>seq-insert-note</code> requires integer parameters, with time in milliseconds, <code>midinote</code> performes some conversions and limiting to keep data in range:</p> <font FACE="Courier New" SIZE="2"> <p>(defun midinote (seq time dur voice pitch vel)<br> &nbsp; (setf time (round (* time 1000)))<br> &nbsp; (setf dur (round (* dur 1000)))<br> &nbsp; (setf pitch (round pitch))<br> &nbsp; (setf vel (round vel))<br> &nbsp; (seq-insert-note seq time 0 (1+ voice) pitch dur vel))</p> </font> <p>Now, let's add some notes to a sequence:</p> <pre>(defun test () (setf *seq* (seq-create)) (midinote *seq* 0.0 1.0 1 c4 100) (midinote *seq* 1.0 0.5 1 d4 100) (midinote *seq* 2.0 0.8 1 a4 100) (setf seqfile (open-binary &quot;test.mid&quot; :direction :output)) (seq-write-smf *seq* seqfile) (close seqfile))</pre> <h2>A Larger Example</h2> <p>This example illustrates the creation of random note onset times using the Poisson distribution. One way to generate this distribution, as seen here, is to create uniformly distributed random times, and then sort these. The function that creates times and then quantizes them to 24ths of a beat is shown here. The <code>len</code> parameter is the number of times, and the <code>average-ioi</code> parameter is the average inter-onset-interval, the average time interval between two adjacent times:</p> <pre>;; create list of random times and sort it ;; dur in ms. (defun poisson-gen (len average-ioi) (let ((dur (* len average-ioi)) poisson-list) (dotimes (i len) (push (* dur (random 10000) 0.0001) poisson-list)) (setf poisson-list (sort poisson-list #'&lt;)) (display &quot;initial list&quot; poisson-list) ;; map list to 24ths: (setf poisson-list (quantize-times-to-24ths poisson-list)) ))</pre> <p>We add a few functions to help express time in terms of beats: </p> <pre>(defun set-tempo (tempo) (setf qtr (/ 60.0 tempo)) (setf 8th (* qtr 0.5)) (setf half (* qtr 2)) (setf whole (* qtr 4)) (setf 16th (* qtr 0.25))) (if (not (boundp 'qtr)) (set-tempo 100)) (defun quantize-times-to-24ths (list) (mapcar #'quantize-time-to-24ths list)) (defun quantize-time-to-24ths (time) (* (/ qtr 24.0) (round (* 24 (/ time qtr)))))</pre> <p>Now, let's create Midi notes using Poisson-based onset times: </p> <pre>(defun melody (seq onsets) (dolist (onset onsets) (midinote seq onset 16th 1 (+ 48 (random 24)) 100))) (defun poisson-melody () (setf *seq* (seq-create)) (melody *seq* (poisson-gen 50 8th)) ;; adds notes to *seq* (setf seqfile (open-binary &quot;pois.mid&quot; :direction :output)) (seq-write-smf *seq* seqfile) (close seqfile))</pre> <p>After evaluating <code>(poisson-melody)</code>, you can play the file &quot;pois.mid&quot; to hear the result. The times are quantized to 24th notes at a tempo of 100, so you can even use a notation editor to display the result in common music notation.</p> <h2>Synthesizing a Midi File</h2> <p>To synthesize sound from a Midi file, use the <code>seq-midi</code> control construct. This behavior reads the data in the <code>seq</code> object and for each note, creates an instance of the behavior you provide. You will need an instrument, so let's define a simple FM instrument to play the notes of the Midi data:</p> <pre>(defun fm-note (p) (mult (pwl 0.01 1 .5 1 1) (fmosc p (mult (step-to-hz p) (pwl 0.01 6 0.5 4 1) (osc p))))) </pre> <p>Now let's use <code>fm-note</code> to play the previously defined <code>poisson-melody</code>, which was saved in the variable <code>*seq*</code>: </p> <pre>(play (seq-midi *seq* (note (chan pitch vel) (a-note pitch))))</pre> <p>The <code>seq-midi</code> construct automatically uses time transformations to place notes at the proper time and to stretch them to the indicated duration. In addition, it sets the <code>chan</code>, <code>pitch</code>, and <code>vel</code> parameters according to the Midi data before invoking your behavior. In this simple example, we ignored <code>chan</code> and <code>vel</code>, but we used <code>pitch</code> to get the right pitch. You might write a more complicated behavior that uses <code>chan</code> to select different synthesis algorithms according to the Midi channel. </p> <p>The syntax for the <code>seq-midi</code> construct may be a little confusing. The symbol <code>note</code> appears to be a function call, but it is not. It is really there to say that the following parameter list and behavior expression apply to Midi notes. There can be other terms for other Midi messages, e.g. </p> <pre>(seq-midi my-seq (note (chan pitch velocity) (my-note pitch velocity)) (ctrl (chan control value) (...)) (bend (chan value) (...)) (touch (chan value) (...)) (prgm (chan value) (setf (aref my-prgm chan) value))</pre> <h2>Examining <code>SEQ</code> Data</h2> <p>In the lib folder of the standard Nyquist installation, there is a file called <code>midishow.lsp</code>. If you load this, you can call some functions that help you examine <code>SEQ</code> data. Try the following (after running <code>poisson-melody</code> above).</p> <pre>(load &quot;midishow&quot;) (midi-show *seq*)</pre> <p>You will see a printout of the data inside the <code>SEQ</code> data object. Unlike Midi, which stores note-on and note-off messages separately, the <code>SEQ</code> structure saves notes as a single message that includes a duration. This is translated to and from Midi format when you write and read Midi files.</p> <p>You can also examine a Midi file by calling:</p> <pre>(midi-show-file &quot;demo.mid&quot;)</pre> <p>This function can take an optional second argument specifying an opened text file if you want to write the data to a file rather than standard (console) output:</p> <pre>(midi-show-file &quot;demo.mid&quot; (open &quot;dump.txt&quot; :direction :output)) (gc)</pre> <p>What is going on here? I did not save the opened file, but rather passed it directly to <code>midi-show-file</code>. Therefore, I did not have a value to pass to the <code>close</code> function. However, I know that files are closed by the garbage collector when there are no more references to them, so I simply called the garbage collector <code>(gc)</code> to run and close the file.</p> <p><br> <br> </p> </body> </html>
diff --git a/demos/osc-test.lsp b/demos/osc-test.lsp
new file mode 100644
index 0000000..103c5e6
--- /dev/null
+++ b/demos/osc-test.lsp
@@ -0,0 +1,90 @@
+(load "nyinit.lsp")
+(osc-enable t)
+(autonorm-off)
+(snd-set-latency 0.1)
+
+;; TEST 1 -- using hzosc
+(defun hzosc-osc ()
+ (hzosc (sum 500 (mult 500 (lp (snd-slider 0 (local-to-global 0)
+ *default-sound-srate* 10) 2.0)))))
+
+
+; (play (hzosc-osc))
+
+
+;; TEST 2 -- using granular synthesis
+(if (not (boundp '*granfile*))
+ (load "gran.lsp"))
+
+
+;; this is modified from gran.lsp to allow pitch-dev to be continuous
+;;
+(defun sf-granulate (filename grain-dur grain-dev ioi ioi-dev pitch-dev-factor
+ &optional (file-start 0) (file-end 0))
+ (let (orig n env actual-grain-dur step-size
+ (avg-ioi (+ ioi (/ ioi-dev 2.0)))
+ (file-dur (sf-dur filename))
+ (dur (get-duration 1)))
+ (setf n (truncate (/ dur avg-ioi)))
+ (cond ((< file-dur file-start)
+ (error "sf-granulate: file-start is after end of file!"))
+ ((< file-dur file-end)
+ (error "sf-granulate: file-end (offset) exceeds file duration!"))
+ ((< file-dur (+ file-start file-end))
+ (error "sf-granulate: file-start + file-end > file duration!")))
+ (setf file-dur (- file-dur file-start file-end))
+ (setf step-size (/ file-dur n))
+ ;(display "sf-granulate" step-size file-dur n)
+ (stretch-abs 1.0 (let ()
+ (seqrep (i n) (let ()
+ (setf actual-grain-dur (real-random grain-dur (+ grain-dur grain-dev)))
+ (setf env (stretch actual-grain-dur (one-minus-cosine)))
+ (force-srate *sound-srate*
+ (stretch (real-random (+ 0.1 (* pitch-dev-factor (get-slider-value 0)))
+ 1)
+ (sound2
+ (set-logical-stop
+ (mult (cue env)
+ (s-read filename
+ :time-offset (+ file-start (* step-size i))
+ :dur actual-grain-dur))
+ (real-random ioi (+ ioi ioi-dev))))))))))))
+
+
+(defun gran-osc ()
+ (scale 0.8
+ (stretch 4 ; total is stretch * 10 seconds, i.e. 4 -> 40s
+ (simrep (i 4)
+ (sf-granulate *granfile* 0.04 0.0 0.02 0.001 10 0 0)))))
+
+;(play (gran-osc))
+
+;; TEST 3 - piano sequence
+
+(defun piano-osc ()
+ (if (not (fboundp 'piano-note))
+ (load "pianosyn"))
+ (seqrep (i 200) (piano-note (+ 0.05 (* 0.2 (get-slider-value 1)))
+ (round (+ (real-random c1 c2)
+ (* (get-slider-value 0) 60)))
+ 100)))
+
+;; TEST 4 - minimoog filter sweep
+
+(defun moog-osc ()
+ (setf *moog-dur* 10)
+ (let ((cutoff (lp (snd-slider 0 (local-to-global 0)
+ *default-sound-srate* *moog-dur*) 2.0))
+ bandwidth)
+ (setf cutoff (scale 2000 cutoff))
+ (setf cutoff (snd-maxv cutoff (const 20 *moog-dur*)))
+ (mult (pwl 1 1 (- *moog-dur* 1) 1 *moog-dur*)
+ (scale 2 (reson (stretch *moog-dur* (osc-saw 50))
+ cutoff (mult cutoff 0.1) 2)))))
+
+; (scale 1000 (ramp 5)))) ; (* 1000.0 (get-slider-value 0))))
+
+(format t "(play (hzosc-osc)) -- play oscillator controlled by slider 0\n")
+(format t "(play (gran-osc)) -- play granular synthesis controlled by slider 0\n")
+(format t "(play (piano-osc)) -- play piano sequence controlled by slider 0, duration by slider 1\n")
+(format t "(play (moog-osc)) -- play minimoog with filter controlled by slider 0\n") \ No newline at end of file
diff --git a/demos/piano.htm b/demos/piano.htm
new file mode 100644
index 0000000..ca5d72e
--- /dev/null
+++ b/demos/piano.htm
@@ -0,0 +1,2 @@
+<html>
+<head> <title>Untitled Document</title> </head> <body bgcolor="#FFFFFF"> <h1>Piano Synthesizer Tutorial </h1> <p>This page describes how to use the piano synthesizer in Nyquist.</p> <p>First, load the file &quot;pianosyn.lsp&quot; to initialize the synthesizer. The file is in the &quot;lib&quot; directory.</p> <p>&gt;(<b>load</b><i> &quot;pianosyn&quot;</i>)</p> <p>After the piano synthesizer has been initialized and returns, you can use the functions provided by the synthesizer program to generate piano sounds.</p> <p>The functions are shown as below:</p> <h2>Generate a single note</h2> <p>Use the function:</p> <p>(<b>piano_note</b> <i>duration step dynamic</i>) </p> <ul> <li><i>duration</i> represents the duration of the note in seconds.</li> <li> <i> step </i>represents the pitch of note, and uses step values as in all Nyquist functions. For example, value 60 is middle C (C4).</li> <li><i>dynamic</i> means the dynamics of the note, and it ranges from 0 to 127. In a midi file, it is used as the velocity of the note. </li> </ul> This behavior returns a sound. You can use (play (piano_note...)) or (s_save (piano_note...)...) to play or save the sound. <p>Examples:</p> <pre>&gt; (play (piano_note 4 60 100))</pre> The command above will generate and immediately play a C4 note that lasts 4 seconds, velocity at 100. <h2>Synthesize piano music according to a midi file</h2> <p>To convert a midi file to sound, use the function:</p> <p>(<b>piano_midi</b> <i>midi_file_name</i>)</p> <ul> <li><i>midi_file_name</i> is a string representing the name of the midi file. </ul> This behavior will generate sound according to the score of the midi file. It generates stereo sound, and the sample rate is the default sound sample rate. <p></p> <h2>Convert midi file to sound file</h2> <p>To convert a midi file to a sound file using the piano synthesizer, use the function:</p> <p>(<b>piano_midi2file</b> <i>midi_file_name sound_file_ name</i>)</p> <ul> <li><i>midi_file_name</i> is a string representing the name of the midi file. <li><i>sound_file_name </i>is a string representing the name of the sound file. </ul> This command will generate a sound file according to the score of the midi file and play it at the same time. It generates stereo sound, and the sample rate is the default sound sample rate. <h3>Example:</h3> <pre>&gt;(piano_midi2file &quot;demo.mid&quot; &quot;demo.wav&quot;)</pre> <blockquote> &quot;demo.mid&quot; is the name of the midi file. It saves the output sound into &quot;demo.wav&quot;, and plays it when generating the output. </blockquote> <hr> <i>Generated by Ning Hu(ning_hu@cmu.edu) Mar.22, 2001</i> </body> </html>
diff --git a/demos/pitch_change.htm b/demos/pitch_change.htm
new file mode 100644
index 0000000..43852e7
--- /dev/null
+++ b/demos/pitch_change.htm
@@ -0,0 +1,83 @@
+<html>
+
+<head>
+<title>Pitch Change by Resampling Tutorial</title>
+</head>
+
+<body>
+
+<h1>Pitch Change by Resampling Tutorial</h1>
+
+<p><b>Roger Dannenberg</b></p>
+<p>
+This tutorial shows how to change the pitch of a sound using resampling.
+In this example, a source sound is resampled to effectively play the sound
+faster and/or slower. This changes the perceived pitch. It also makes the
+sound play faster and/or slower, so the original duration is not preserved.
+<p>
+To control the playback speed, a control function is used. The function
+specifies the pitch shift in steps, so if the function is zero, there is
+no change. If the signal is 1, the signal is shifted up one half-step.
+If the signal is -2, the signal is shifted down a whole-step, etc.
+<p>
+The control signal can of course change over time. The control signal
+time corresponds to time in the resulting sound. Thus, if the control
+signal jumps from 0 to 5 at time 3, the resulting sound will jump up
+a musical fourth (5 half-steps) at time 3. This may or may not be time
+3 in the source sound.
+
+<p>
+The code implements VARIABLE-RESAMPLE which takes two parameters:
+<ul>
+<li>steps -- the pitch control function
+<li>snd -- the source sound to be resampled
+</ul>
+The function works as follows:
+First, steps is converted to ratio, which is the speed change expressed
+as a ratio. E.g. when steps is 12 (an octave), ratio will be 2 (a 2:1 ratio)
+Second, ratio is integrated to get map. The map is a function from real
+time to the score. Note that the slope of the map at any time determines
+the amount of speedup.
+Finally, SND-COMPOSE is used to map the source sound according to the
+tempo map. Because SND-COMPOSE is defined to output the sample rate
+of the map, we coerce the sample rate of map to *sound-srate*.
+<p>
+This function could be improved by adding code to handle stereo inputs.
+Also, this function should really be implemented using snd-resamplev,
+which uses a high-quality resampling algorithm. Unfortunately, there
+a bug in snd-resamplev, so until the bug is fixed, snd-compose actually
+sounds better.
+<p>
+The resulting sound ends whenever either steps or snd come to an end.
+To control duration, you may want to make sure that the source sound
+is much longer than the control function. That way, even if you speed
+it up, it will still last long enough to exhaust the control function,
+and you know by design how long that is. You can also apply an
+envelope to the result to trim it to a known length.
+<p>
+So, here finally is the implementation:
+<pre>
+(defun variable-resample (steps snd)
+ (let ((p1 (/ (log 2.0) 12)) ; p1 helps convert steps to a ratio
+ ratio map)
+ (setf ratio (s-exp (mult steps p1))) ; pitch ratio
+ (setf map (integrate ratio)) ; map from real-time to sound time
+ (snd-compose snd (force-srate *sound-srate* map))))
+</pre>
+Here is an example: the PWL control function is initially zero (no
+transposition), but starting at time 1.0, it rises to 2.0 in 0.1s
+where it remains until time 3.0. The function ends at time 3.0.
+The sound to be modified in this case is a simple sinusoid with a
+duration of 8. In this case, the PWL function finishes at 3.0s, well
+before the OSC sound comes to an end.
+<pre>
+(play
+ (variable-resample (pwl 1.0 0.0 1.1 2.0 3.0 2.0 3.0) (osc c4 8.0)))
+</pre>
+Note that you can replace (osc c4 8.0) with any sound, including one
+read from a sound file using S-READ.
+
+</body>
+</html>
+
+
diff --git a/demos/pmorales/a4.lsp b/demos/pmorales/a4.lsp
new file mode 100644
index 0000000..6c39f22
--- /dev/null
+++ b/demos/pmorales/a4.lsp
@@ -0,0 +1,25 @@
+;;; SIMPLE SYNTHESIS
+;;; Waveform + Envelope. Modulating the envelope with noise
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun shiver (dur frq noise-percent noise-frq)
+ (mult (osc frq dur)
+ (sum (pwlv 5e-2 300e-3 1.0 (- dur 300e-3) 1.0 dur 2e-3)
+ (mult (/ noise-percent 100.0) (randi1 noise-frq dur)))))
+
+; when noise-percent is too big (> 40), there is a click risk at the
+; beginning and the end of the note
+; this would be avoided if randi function were multiplied by a smooth envelope
+; WARNING: randi1 is defined in PJMG.LSP
+
+(defun shiver-demo ()
+ (ss (seq (shiver 1 c5 20 40)
+ (shiver 1 b4 50 40)
+ (shiver 1 a4 80 40)
+ (shiver 1 g4 20 300)
+ (shiver 1 f4 50 300)
+ (shiver 1 d4 80 300))))
diff --git a/demos/pmorales/a5.lsp b/demos/pmorales/a5.lsp
new file mode 100644
index 0000000..33ef37e
--- /dev/null
+++ b/demos/pmorales/a5.lsp
@@ -0,0 +1,20 @@
+;;; SIMPLE SYNTHESIS
+;;; Waveform + Envelope. Modulating the frequency
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun whiny (dur frq)
+ (let ((lfo-f (step-to-hz frq)))
+ (mult (pwl 0.1 1 (- dur 0.1) 1 dur)
+ (fmosc frq (pwl (* 0.1 dur) (/ lfo-f -2.0)
+ (* 0.25 dur) (* lfo-f 2.0)
+ (* 0.3 dur) (* lfo-f 1.5)
+ (* 0.7 dur) (* lfo-f -7.0 (/ 8.0))
+ dur (* lfo-f -15.0 (/ 16.0))
+ )))))
+
+(defun whiny-demo () (ss (whiny 10 a5)))
+
diff --git a/demos/pmorales/a6.lsp b/demos/pmorales/a6.lsp
new file mode 100644
index 0000000..a50334f
--- /dev/null
+++ b/demos/pmorales/a6.lsp
@@ -0,0 +1,33 @@
+;;; SIMPLE SYNTHESIS
+;;; Waveform + Envelope. Modulating the frequency, 2
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun saw-table ()
+ (setf *saw-table* (pwlv 1.0 1.0 0.0))
+ (setf *saw-table* (list *saw-table* (hz-to-step 1) T)))
+
+(if (not (boundp '*saw-table*)) (saw-table))
+
+(defun cheap (frq-randi frq dur lfor lfoi)
+ (mult (randi1 frq-randi dur)
+ (fmosc frq (mult (const lfoi dur)
+ (osc (hz-to-step lfor) dur *saw-table*)))))
+
+
+(defun callas (dur frq vib-r vib-w)
+ (mult (pwl 0.1 1.0 (- dur 0.1) 1.0 dur)
+ (fmosc frq (mult (const vib-w dur)
+ (sine (hz-to-step vib-r) dur)))))
+
+(defun callas-demo ()
+ (ss (seq (sim (at 0.0 (cheap 80 a4 6.5 3 1000))
+ (at 2.5 (cheap 150 a5 6.5 3 750)))
+ (callas 1 a4 5 24)
+ (callas 0.5 e5 5 24) (callas 0.5 f5 5 24) (callas 1 a5 5 24)
+ (callas 1 c6 5 24) (callas 1 e6 5 24)
+ (callas 1 g4 5 24) (callas 1 f4 5 24)
+ (callas 3 e4 5 24))))
diff --git a/demos/pmorales/b1.lsp b/demos/pmorales/b1.lsp
new file mode 100644
index 0000000..1938ad5
--- /dev/null
+++ b/demos/pmorales/b1.lsp
@@ -0,0 +1,60 @@
+;;; ADDITIVE SYNTHESIS
+;;; Gong like sounds
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+
+(defun add-partial (dur frq scal)
+ (amosc (hz-to-step frq) (pwev scal dur (* scal 1e-2))))
+
+(defun gong-1 ()
+ (sim (add-partial 4 240 3.0)
+ (add-partial 4 277 2.5)
+ (add-partial 4 385 2.0)
+ (add-partial 4 605 3.0)
+ (add-partial 4 340 1.0)
+ (add-partial 4 670 1.0)
+ (add-partial 4 812 1.0)))
+
+(defun add-partial-2 (frq scal)
+ (amosc (hz-to-step frq) (pwev scal (/ (* 6 240) frq) (* scal 1e-2))))
+
+(defun gong-2 ()
+ (sim (add-partial-2 240 3.0)
+ (add-partial-2 277 2.5)
+ (add-partial-2 385 2.0)
+ (add-partial-2 605 3.0)
+ (add-partial-2 340 1.0)
+ (add-partial-2 670 1.0)
+ (add-partial-2 812 1.0)))
+
+(defun add-partial-3 (frq fratio dur amp)
+ (amosc (hz-to-step (* frq fratio)) (pwev amp (/ dur fratio) (* amp 1e-2))))
+
+(defun gong-3 (frq dur)
+ (sim (add-partial-3 frq 1.0 dur 2.0)
+ (add-partial-3 frq 2.0 dur 2.0)
+ (add-partial-3 frq 2.4 dur 2.0)
+ (add-partial-3 frq 3.0 dur 2.0)
+ (add-partial-3 frq 4.5 dur 3.0)
+ (add-partial-3 frq 5.33 dur 3.0)
+ (add-partial-3 frq 6.0 dur 3.0)))
+
+
+(defun gong-3-melody ()
+ (sim (at 0.0 (gong-3 329 5))
+ (at 0.2 (gong-3 360 6))
+ (at 0.4 (gong-3 380 5))
+ (at 0.6 (gong-3 300 8))
+ (at 0.8 (gong-3 430 4))
+ (at 2.0 (gong-3 640 4))
+ (at 2.2 (gong-3 610 5))
+ (at 2.4 (gong-3 580 4))
+ (at 2.6 (gong-3 660 5))))
+
+(defun gong-3-demo () (ss (gong-3-melody)))
+
+
diff --git a/demos/pmorales/b10.lsp b/demos/pmorales/b10.lsp
new file mode 100644
index 0000000..70a6941
--- /dev/null
+++ b/demos/pmorales/b10.lsp
@@ -0,0 +1,63 @@
+;;; ADDITIVE SYNTHESIS
+;;; Sinus Chaos
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun env31 ()
+ (pwlv 0.99 25e-3 0.99 225e-3 0.318 275e-3 0.318 475e-3 0.99 500e-3 0.99))
+
+(defun env32 ()
+ (pwlv 0.377 250e-3 0.99 500e-3 0.377))
+
+(defun env33 ()
+ (pwlv 0.5 20e-3 0.5 225e-3 0.99 250e-3 0.99 480e-3 0.5 500e-3 0.5))
+
+(defun env34 ()
+ (pwlv 0.333 25e-3 0.333 225e-3 0.999 275e-3 0.999 475e-3 0.333 500e-3 0.333))
+
+(defun make-env31 ()
+ (setf *env31* (list (env31) (hz-to-step 2) T)))
+
+(defun make-env32 ()
+ (setf *env32* (list (env32) (hz-to-step 2) T)))
+
+(defun make-env33 ()
+ (setf *env33* (list (env33) (hz-to-step 2) T)))
+
+(defun make-env34 ()
+ (setf *env34* (list (env34) (hz-to-step 2) T)))
+
+(if (not (boundp '*env31*)) (make-env31))
+(if (not (boundp '*env32*)) (make-env32))
+(if (not (boundp '*env33*)) (make-env33))
+(if (not (boundp '*env34*)) (make-env34))
+
+(defun make-table12 ()
+ (setf *table12* (sim (build-harmonic 21.0 2048)
+ (build-harmonic 29.0 2048)
+ (build-harmonic 39.0 2048)))
+ (setf *table12* (list *table12* (hz-to-step 1) T)))
+
+(if (not (boundp '*table12*)) (make-table12))
+
+
+(defun chaos-partial (amp rate frq dur env &optional (table *table*))
+ (scale amp (fmosc (hz-to-step 1e-3)
+ (scale frq (osc (hz-to-step rate) dur env)) table)))
+
+(defun partial2 (amp frandi rate frq dur env)
+ (mult (randi1 frandi dur)
+ (scale amp (fmosc (hz-to-step 1e-3)
+ (scale frq (osc (hz-to-step rate) dur env))))))
+
+(ss
+ (sim
+ (chaos-partial 4.5 0.12 880.0 24 *env31*)
+ (partial2 4.0 200.0 0.17 1660.0 24 *env32*)
+ (chaos-partial 1.2 0.05 200.0 24 *env33*)
+ (chaos-partial 0.7 0.33 2400.0 24 *env34*)
+
+ ))
diff --git a/demos/pmorales/b2.lsp b/demos/pmorales/b2.lsp
new file mode 100644
index 0000000..c529cd1
--- /dev/null
+++ b/demos/pmorales/b2.lsp
@@ -0,0 +1,45 @@
+;;; ADDITIVE SYNTHESIS
+;;; Risset's Spectral Analysis of a Chord
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+; Probar con las dos envolventes
+;(defun sac-env (dur)
+; (let ((xx (pwl (/ dur 2) 1.0 dur)))
+; (mult xx xx)))
+
+(defun sac-env (dur)
+ (pwev 1.0 dur 5e-2))
+
+(defun attk-list (offset num-harms &optional (out-list (list 0.0)))
+ (if (= num-harms 0) (reverse out-list)
+ (attk-list offset (1- num-harms) (cons (+ offset (car out-list)) out-list))))
+
+
+(defun sac (frq dur offset-entry num-harm)
+ (mapcar #'(lambda (xhrm xoff)
+ (at xoff (amosc (hz-to-step (* (step-to-hz frq) xhrm)) (sac-env dur))))
+ (attk-list -1 (1- num-harm) (list num-harm))
+ (attk-list offset-entry (1- num-harm))))
+
+(defun sac-left-right (l)
+ (do* ((i 0 (1+ i))
+ (left () (if (evenp i) (cons (nth i l) left) left))
+ (right () (if (oddp i) (cons (nth i l) right) right)))
+ ((= i (1- (length l))) (vector (apply #'sim left) (apply #'sim right)))))
+
+(defun st-sac (frq dur offset-entry num-harm)
+ (sac-left-right (sac frq dur offset-entry (1+ num-harm))))
+
+(defun st-sac-sequence ()
+ (scale 0.17 (sim (at 0.0 (st-sac as6 7.5 2.5 5))
+ (at 0.01 (st-sac b5 7.5 2.5 5))
+ (at 3.75 (st-sac e5 3.75 1.25 9))
+ (at 3.76 (st-sac g5 3.75 1.25 9))
+ (at 5.5 (st-sac d4 2 1.0 11))
+ (at 5.51 (st-sac gs3 2 1.0 11)))))
+
+(defun st-sac-demo () (ss (st-sac-sequence)))
diff --git a/demos/pmorales/b3.lsp b/demos/pmorales/b3.lsp
new file mode 100644
index 0000000..c4c7b33
--- /dev/null
+++ b/demos/pmorales/b3.lsp
@@ -0,0 +1,40 @@
+;;; ADDITIVE SYNTHESIS
+;;; Risset Bell
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun bell-partial (amp dur frq)
+ (amosc (hz-to-step frq) (pwev amp dur (* amp 12e-5))))
+
+(defun risset-bell (amp dur frq)
+ (sim
+ (bell-partial amp dur (* frq .56))
+ (bell-partial (* amp .67) (* dur .9) (+ (* frq .56) 1))
+ (bell-partial (* amp 1.35) (* dur .65) (* frq .92))
+ (bell-partial (* amp 1.8) (* dur .55) (+ (* frq .92) 1.7))
+ (bell-partial (* amp 2.67) (* dur .325) (* frq 1.19))
+ (bell-partial (* amp 1.67) (* dur .35) (* frq 1.7))
+ (bell-partial (* amp 1.46) (* dur .25) (* frq 2.0))
+ (bell-partial (* amp 1.33) (* dur .2) (* frq 2.74))
+ (bell-partial (* amp 1.33) (* dur .15) (* frq 3.0))
+ (bell-partial amp (* dur .1) (* frq 3.76))
+ (bell-partial (* amp 1.33) (* dur .075) (* frq 4.07))))
+
+
+(defun risset-bell-sequence ()
+ (sim (at 0.0 (risset-bell 1.0 4.0 999.0))
+ (at 2.0 (risset-bell 1.0 4.0 633.0))
+ (at 4.0 (risset-bell 1.0 4.0 211.0))
+ (at 6.0 (risset-bell 1.0 4.0 999.0))
+ (at 8.0 (risset-bell 0.7 20.0 633.0))
+ (at 10.0 (risset-bell 0.7 20.0 211.0))
+ (at 12.0 (risset-bell 0.7 20.0 999.0))
+ (at 14.0 (risset-bell 0.7 20.0 80.0))))
+
+(defun risset-bell-demo () (ss (m)))
+
+
+
diff --git a/demos/pmorales/b5.lsp b/demos/pmorales/b5.lsp
new file mode 100644
index 0000000..30e568d
--- /dev/null
+++ b/demos/pmorales/b5.lsp
@@ -0,0 +1,19 @@
+;;; ADDITIVE SYNTHESIS
+;;; Continuous pitch control by LFO
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun lfo-pitch-control ()
+ (pwlv 0.25 0.6 0.25 1.4 0.5 2.0 0.25 2.2 0.25 3.4 0.5 3.8 0.75 7.0 -0.2))
+
+(defun starship (frq scl)
+ (apply #'sim
+ (mapcar #'(lambda (offset)
+ (fmosc (hz-to-step (+ frq offset))
+ (scale scl (lfo-pitch-control))))
+ '(0.0 4.5 9.4 23.0 39.0 84.0))))
+
+(defun starship-demo () (ss (starship 200.0 1000.0)) )
diff --git a/demos/pmorales/b7.lsp b/demos/pmorales/b7.lsp
new file mode 100644
index 0000000..4a0a2fe
--- /dev/null
+++ b/demos/pmorales/b7.lsp
@@ -0,0 +1,40 @@
+;;; ADDITIVE SYNTHESIS
+;;; Risset Tibetan
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun tibetan-wave ()
+ (setf *tibetan-table*
+ (sim (scale 0.3 (build-harmonic 1 2048))
+ (scale 0.1 (build-harmonic 5 2048))
+ (scale 0.1 (build-harmonic 6 2048))
+ (scale 0.1 (build-harmonic 7 2048))
+ (scale 0.1 (build-harmonic 6 2048))
+ (scale 0.1 (build-harmonic 8 2048))
+ (scale 0.1 (build-harmonic 9 2048))))
+ (setf *tibetan-table* (list *tibetan-table* (hz-to-step 1) T)))
+
+(if (not (boundp '*tibetan-table*)) (tibetan-wave))
+
+(defun tibetan (frq offset dur rise dec)
+ (mult (pwl rise 1.0 (- dur dec) 1.0 dur)
+ (apply #'sim
+ (mapcar #'(lambda (off)
+ (osc (hz-to-step (+ frq (* off offset))) dur *tibetan-table*))
+ '(0 1 2 3 4 -1 -2 -3 -4)))))
+
+(defun tibetan-sequence ()
+ (scale 0.1 (vector (sim (at 0.0 (tibetan 110 0.03 35 0.07 21))
+ (at 20.0 (tibetan 110 0.04 20 2 4))
+ (at 28.0 (tibetan 220 0.04 30 3 6))
+ (at 32.1 (tibetan 110 0.03 23 2.3 4.6)))
+ (sim (at 5.0 (tibetan 55 0.02 20 0.04 12))
+ (at 20.0 (tibetan 220 0.05 15 1.5 3))
+ (at 32.0 (tibetan 110 0.025 26 2.6 5.2))
+ (at 36.0 (tibetan 55 0.01 22 0.04 13))))))
+
+(defun tibetan-demo () (play (tibetan-sequence)))
+
diff --git a/demos/pmorales/b8.lsp b/demos/pmorales/b8.lsp
new file mode 100644
index 0000000..f4536a6
--- /dev/null
+++ b/demos/pmorales/b8.lsp
@@ -0,0 +1,51 @@
+;;; ADDITIVE SYNTHESIS
+;;; Risset Drum
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(defun drum-env (amp dur)
+ (pwev amp dur (* 12e-5 amp)))
+
+(defun noise-component (amp dur central-frq noise-frq)
+ (amosc (hz-to-step central-frq)
+ (mult (drum-env (/ amp 2) dur)
+ (randi1 noise-frq dur))))
+
+(defun fund-component (amp dur frq)
+ (amosc (hz-to-step frq)
+ (drum-env (/ amp 2.5) dur)))
+
+(defun drum-inh-wave ()
+ (setf *drum-inh-table*
+ (sim (build-harmonic 10 2048)
+ (scale 1.5 (build-harmonic 16 2048))
+ (scale 2.0 (build-harmonic 22 2048))
+ (scale 1.5 (build-harmonic 23 2048))))
+ (setf *drum-inh-table* (list *drum-inh-table* (hz-to-step 1) T)))
+
+(if (not (boundp '*drum-inh-table*)) (drum-inh-wave))
+
+(defun inh-component (amp dur frq)
+ (amosc (hz-to-step (/ frq 10))
+ (drum-env (/ amp 6.0) dur)
+ *drum-inh-table*))
+
+(defun risset-drum (amp dur frq)
+ (sim (noise-component amp dur 500 400)
+ (inh-component amp dur frq)
+ (fund-component amp dur frq)))
+
+(defun risset-drum-sequence ()
+ (sim
+ (at 0.0 (risset-drum 1.0 3.0 100.0))
+ (at 0.5 (risset-drum 1.0 1.0 50.0))
+ (at 1.0 (risset-drum 1.0 1.0 75.0))
+ (at 1.2 (risset-drum 1.0 1.0 200.0))
+ (at 1.4 (risset-drum 1.0 3.0 300.0))
+ (at 1.8 (risset-drum 1.0 6.0 500.0))))
+
+(defun risset-drum-demo () (ss (risset-drum-sequence)))
+
diff --git a/demos/pmorales/b9.lsp b/demos/pmorales/b9.lsp
new file mode 100644
index 0000000..908ffaa
--- /dev/null
+++ b/demos/pmorales/b9.lsp
@@ -0,0 +1,42 @@
+;;; ADDITIVE SYNTHESIS
+;;; Risset Endless
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+(setf *twopi* (* 2 pi))
+
+(defun bell-table ()
+ (setf *bell-table* (make-array 512))
+ (dotimes (i 512)
+ (setf (aref *bell-table* i)
+ (exp (* -4.8283 (- 1 (cos (* *twopi* (- i 255.5) (/ 511.0))))))))
+ (setf *bell-table* (snd-from-array 0.0 512 *bell-table*))
+ (setf *bell-table* (list *bell-table* (hz-to-step 1.0) T)))
+
+(if (not (boundp '*bell-table*)) (bell-table))
+
+(defun frq-table ()
+ (setf *frq-table*
+ (list (sim (pwe 1.0 16e-4) (const -1.0 1.0)) (hz-to-step 1.0) T)))
+
+(if (not (boundp '*frq-table*)) (frq-table))
+
+(defun endless-partial ()
+ (mult (osc (hz-to-step 0.025) 40 *bell-table*)
+ (fmosc (hz-to-step 16000) (scale 16000
+ (osc (hz-to-step 0.025) 40 *frq-table*)))))
+
+(setf *endless-partial* (endless-partial))
+
+(defun risset-endless ()
+ (scale 0.25 (apply #'sim (mapcar #'(lambda (x)
+ (at x (cue *endless-partial*)))
+ '(0.0 2.0 4.0 6.0 8.0 10.0 12.0
+ 14.0 16.0 18.0 20.0)))))
+
+(defun risset-endless-demo () (ss (risset-endless)))
+
+
diff --git a/demos/pmorales/buzz.lsp b/demos/pmorales/buzz.lsp
new file mode 100644
index 0000000..90b8b96
--- /dev/null
+++ b/demos/pmorales/buzz.lsp
@@ -0,0 +1,88 @@
+;;; BUZZ generator for Nyquist
+;;; Pedro J. Morales. Albacete, Spain. Jule, 2001
+;;; pmorales@iele-ab.uclm.es
+
+; tested on Nyquist IDE 3.0 under Windows
+
+
+; Summation formula taken from F. Richard Moore "Elements of Computer Music"
+; section 3.4 page 273
+(defun buzz-aux (harm len)
+ (let ((frq (/ *sound-srate* len)))
+ (scale (/ 1.0 harm)
+ (mult (osc (hz-to-step (* (+ 1 harm) 0.5 frq)) (/ 1.0 frq))
+ (osc (hz-to-step (* harm 0.5 frq))(/ 1.0 frq))
+ (clip (recip (osc (hz-to-step (* 0.5 frq)) (/ 1.0 frq)))
+ 10000)))))
+
+; A table implies a constant spectrum.
+; If you need another spectrum try to change the number of harmonics
+(defun make-buzz-table (harm &optional (len 2047))
+ (list (buzz-aux harm len)
+ (hz-to-step (/ *sound-srate* len))
+ T))
+
+; This function calculates de maximun number of harmonics
+; without aliasing
+(defun num-harm (pitch)
+ (truncate (/ *sound-srate* 2.0 (step-to-hz pitch))))
+
+; Constant frequency buzz oscillator
+; Number of harmonics is optional. If it is not
+; specified then the waveform is calculated with maximum
+; number of harmonics without aliasing
+(defun buzz (pitch dur &optional harm)
+ (unless harm (setf harm (num-harm pitch)))
+ (osc pitch dur (make-buzz-table harm)))
+
+; vibrato buzz
+(defun vib-buzz (pitch dur &optional harm)
+ (unless harm (setf harm (num-harm pitch)))
+ (fmosc pitch (scale 10 (lfo 6 dur)) (make-buzz-table harm)))
+
+; buzz in fm oscillator form
+(defun fmbuzz (pitch modulator harm)
+ (fmosc pitch modulator (make-buzz-table harm)))
+
+; filter with three formants intended for vowel synthesis
+; (this synthesis algorithm may be improved by means of finer
+; control of parameters)
+
+(defun formants (beh f1 f2 f3)
+ (sim (reson beh f1 100 2)
+ (reson beh f2 100 2)
+ (reson beh f3 100 2)))
+
+; vowels formants data taken from John R. Pierce "Los sonidos de la Musica"
+; (Scientific American, spanish edition)
+(defun ah (pitch dur) ; Hawed foneme
+ (mult (pwl 0.2 1 (- dur 0.4) 1 dur)
+ (formants (vib-buzz pitch dur) 570 840 2410)))
+
+(defun eh (pitch dur) ; Head foneme
+ (mult (pwl 0.2 1 (- dur 0.4) 1 dur)
+ (formants (vib-buzz pitch dur) 530 1840 2480)))
+
+(defun eeh (pitch dur) ; Heed foneme
+ (mult (pwl 0.2 1 (- dur 0.4) 1 dur)
+ (formants (vib-buzz pitch dur) 270 2290 3010)))
+
+(defun ooh (pitch dur) ; Who'd foneme
+ (mult (pwl 0.2 1 (- dur 0.4) 1 dur)
+ (formants (vib-buzz pitch dur) 300 870 2240)))
+
+(defun buzz-demo ()
+ (seq (ah c3 1)(eeh c3 1)(ooh c3 1)
+ (ah c2 1)(eeh c2 1)(ooh c2 1)
+ (ah c4 1)(eeh c4 1)(ooh c4 1)
+ (ah d4 1)(eeh d4 1)(ooh d4 1)
+ (ah g4 1)(eeh g4 1)(ooh g4 1)
+ (ah c5 1)(eeh c5 1)(ooh c5 1)
+ (ah c4 1)(eh b3 0.5)(ah c4 0.5)
+ (eeh e4 1)(eeh d4 1)(ah c4 3)))
+
+; TEST
+(defun buzz-test () (play (buzz-demo)))
+
+; (buzz-test)
+
diff --git a/demos/pmorales/c1.lsp b/demos/pmorales/c1.lsp
new file mode 100644
index 0000000..68177e8
--- /dev/null
+++ b/demos/pmorales/c1.lsp
@@ -0,0 +1,32 @@
+;;; ADDITIVE SYNTHESIS
+;;; Random Signals
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+
+(defun simple-noise ()
+ (mult (noise 4.0)
+ (pwl 0.4 1.0 3.6 1.0 4.0)))
+
+(defun simple-randi (frandi)
+ (mult (randi1 frandi 4.0)
+ (pwl 0.4 1.0 3.6 1.0 4.0)))
+
+(defun tenney (frandi frq dur)
+ (amosc (hz-to-step frq)
+ (mult (randi1 frandi dur) (pwl 0.4 1.0 (- dur 0.4) 1.0 dur))))
+
+
+
+;(ss (seq (simple-noise) (simple-randi 200) (simple-randi 400)))
+
+(defun tenny-sequence ()
+ (seq (tenney 200.0 400.0 4.0)
+ (tenney 800.0 300.0 2.0)
+ (tenney 400.0 1600.0 4.0)))
+
+(defun tenny-demo () (ss (tenny-sequence)))
+
diff --git a/demos/pmorales/d1.lsp b/demos/pmorales/d1.lsp
new file mode 100644
index 0000000..50ab42c
--- /dev/null
+++ b/demos/pmorales/d1.lsp
@@ -0,0 +1,43 @@
+;;; Simple KARPLUS-STRONG
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+
+; NYQUIST code for simple Karplus-Strong algorithm
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+
+(setf ks-class
+ (send class :new '(cnt total-cnt z-1output output delay-line len total-len)))
+
+(send ks-class :answer :isnew '(pitch dur)
+ '((setf len (round (/ *sound-srate* (step-to-hz pitch))))
+ (setf total-len (* *sound-srate* dur))
+ (setf delay-line (snd-samples (noise (/ (step-to-hz pitch))) len))
+ (setf cnt 0)
+ (setf total-cnt 0)
+ (setf z-1output 0.0)
+ (setf output 0.0)))
+
+(send ks-class :answer :next '()
+ '((setf output (aref delay-line cnt))
+ (setf (aref delay-line cnt) (/ (+ output z-1output) 2.0))
+ (setf z-1output output)
+ (setf cnt (if (= (1- len) cnt) 0 (1+ cnt)))
+ (setf total-cnt (1+ total-cnt))
+ (if (= total-cnt total-len) NIL output)))
+
+(defun ks (pitch dur)
+ (let (obj (d (get-duration dur)))
+ (setf obj (send ks-class :new pitch d))
+ (snd-fromobject *rslt* *sound-srate* obj)))
+
+(defun ks-env (pitch dur)
+ (mult (pwe dur 0.064)
+ (ks pitch dur)))
+
+;(ss (seq (ks a4 1.0) (ks b4 1.0) (ks c5 3.0)))
+
+(ss (seq (ks-env a3 1.0) (ks-env b3 1.0)))
diff --git a/demos/pmorales/e2.lsp b/demos/pmorales/e2.lsp
new file mode 100644
index 0000000..48c0dfa
--- /dev/null
+++ b/demos/pmorales/e2.lsp
@@ -0,0 +1,157 @@
+;;; FM
+;;; Chowning Dynamic Spectral Evolution
+;;; coded by Pedro Jose Morales
+;;; pmorales@iele-ab.uclm.es
+
+;;; WARNING: needs REVERB.LSP
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+(if (not (fboundp 'reverb)) (load "reverb"))
+
+
+; Chowning BELL -----------------------------------------------------
+(defun exp-env (amp dur)
+ (scale amp (pwe dur 64e-4)))
+
+(defun fm-bell (frq cm-ratio imax dur amp)
+ (mult (exp-env amp dur)
+ (fmosc (hz-to-step frq)
+ (mult (exp-env (* imax (/ frq cm-ratio)) dur)
+ (osc (hz-to-step (/ frq cm-ratio)) dur)))))
+
+; Chowning WOOD-DRUM ------------------------------------------------
+(defun wood-env (amp dur)
+ (scale amp (pwev 0.8 (* dur 0.2) 1.0 (* dur 0.25) 1.0 dur 64e-4)))
+
+(defun wood-mod-env (amp dur)
+ (scale amp (pwlv 1.0 (* 0.2 dur) 0.0 dur)))
+
+(defun fm-wood-drum (frq cm-ratio imax dur amp)
+ (mult (wood-env amp dur)
+ (fmosc (hz-to-step frq)
+ (mult (wood-mod-env (* imax (/ frq cm-ratio)) dur)
+ (osc (hz-to-step (/ frq cm-ratio)) dur)))))
+
+; Chowning BRASS ----------------------------------------------------
+(defun brass-env (amp dur)
+ (scale amp (pwl 0.1 1.0 0.2 0.8 (- dur 0.1) 0.7 dur)))
+
+(defun fm-brass (pitch cm-ratio imax dur amp)
+ (let ((frq (step-to-hz pitch)))
+ (mult (brass-env amp dur)
+ (fmosc pitch
+ (mult (brass-env (* imax (/ frq cm-ratio)) dur)
+ (osc (hz-to-step (/ frq cm-ratio)) dur))))))
+
+; Chowning CLARINET -------------------------------------------------
+(defun clar-env (amp dur)
+ (scale amp (pwev 64e-4 0.1 1.0 (- dur 0.1) 1.0 dur 64e-4)))
+
+(defun clar-mod-env (vmax vmin dur)
+ (pwev vmax (* dur 0.3) vmin dur vmin))
+
+(defun fm-clar (pitch cm-ratio imax imin dur amp)
+ (let ((frq (step-to-hz pitch)))
+ (mult (clar-env amp dur)
+ (fmosc pitch
+ (mult (scale (/ frq cm-ratio) (clar-mod-env imax imin dur))
+ (osc (hz-to-step (/ frq cm-ratio)) dur))))))
+
+; Chowning VARIABLE FM INSTRUMENT -----------------------------------
+; este instrumento hay que mejorarlo
+
+(defun variable-fm-env (amp break mid dur)
+ (scale amp (pwev (* mid 64e-4) break mid dur (* mid 64e-4))))
+
+(defun variable-mod-osc (index frq kdyn mid break dur)
+ (amosc (hz-to-step frq)
+ (scale (* index frq) (pwlv kdyn break mid dur))))
+
+(defun variable-fm-inst (amp break mid dur kdyn index frq cm-ratio)
+ (mult (variable-fm-env amp break mid dur)
+ (fmosc (hz-to-step frq)
+ (variable-mod-osc index (/ frq cm-ratio) kdyn mid break dur))))
+
+
+(defun variable-fm-rev-st (amp break mid dur kdyn index frq cm-ratio coefrev)
+ (let ((snd (variable-fm-inst amp break mid dur kdyn index frq cm-ratio)))
+ (sim (cue snd) (scale coefrev (reverb snd dur)))))
+
+;(ss (seq (fm-bell 100.0 (/ 5.0 7.0) 10 10 1.0)
+; (fm-bell 150.0 (/ 5.0 7.0) 7 10 1.0)
+; (fm-bell 200.0 (/ 5.0 7.0) 15 7 1.0)))
+
+(defun fm-w-d (pitch)
+ (fm-wood-drum (step-to-hz pitch) (/ 16.0 11.0) 25 0.2 1.0))
+
+;(ss (seq (fm-w-d a2) (fm-w-d b2) (fm-w-d c3) (fm-w-d d3) (fm-w-d e3)
+; (fm-w-d f3) (fm-w-d g3) (fm-w-d a3)
+; (fm-w-d a1) (fm-w-d b1) (fm-w-d c2) (fm-w-d d2) (fm-w-d e2)
+; (fm-w-d f2) (fm-w-d g2) (fm-w-d a2)))
+
+(defun fm-br (pitch)
+ (fm-brass pitch 1.0 5 0.6 1.0))
+
+;(ss (seq (fm-br c4) (fm-br d4) (fm-br e4) (fm-br f4) (fm-br g4)
+; (fm-br a4) (fm-br b4) (fm-br c5)))
+
+(defun fm-c (pitch)
+ (fm-clar pitch (/ 3.0 2.0) 5 2 0.5 1.0))
+
+;(ss (seq (fm-c c5) (fm-c d5) (fm-c e5) (fm-c f5) (fm-c g5)
+; (fm-c a5) (fm-c b5) (fm-c c6)))
+
+(defun v-fm (pitch break mid dur rev)
+ (variable-fm-rev-st 1.0 break mid dur 0.8 20.0 (step-to-hz pitch) (/ 7.0 5.0) rev))
+
+;(ss (sim (at 0.0 (v-fm a4 0.7 0.2 3.0 0.5))
+; (at 1.5 (v-fm e6 0.2 0.3 3.0 0.4))
+; (at 3.0 (v-fm d5 2.0 0.6 4.0 0.4))
+; (at 6.0 (v-fm d6 0.01 0.7 3.0 0.5))))
+
+; Double Carrier Brass ----------------------------------------------
+
+(defun dc-env (dur)
+ (pwl (* dur 0.1) 1.0 (* dur 0.2) 0.8 (* dur 0.9) 0.7 dur))
+
+(defun dc-modulator (frq dur imax imin)
+ (amosc (hz-to-step frq)
+ (sim (scale (* frq (- imax imin)) (dc-env dur))
+ (const (* frq imin) dur))))
+
+(defun dc-fm1 (frq1 dur amp modulator)
+ (scale amp
+ (mult (dc-env dur)
+ (fmosc (hz-to-step frq1) modulator))))
+
+(defun dc-fm2 (frq1 dur cm-ratio index-ratio amp amp-ratio modulator)
+ (scale (* amp amp-ratio)
+ (mult (dc-env dur)
+ (fmosc (hz-to-step (/ frq1 cm-ratio))
+ (scale index-ratio modulator)))))
+
+(defun double-carrier (dur frq cm-ratio amp amp-ratio imax imin index-ratio)
+ (let ((modulator (dc-modulator (/ frq cm-ratio) dur imax imin)))
+ (sim (dc-fm1 frq dur amp modulator)
+ (dc-fm2 frq dur cm-ratio index-ratio amp amp-ratio modulator))))
+
+;(ss (double-carrier 0.6 440.0 1.0 1.0 0.5 3 1 (/ 3.0 1.5)))
+
+; Double Carrier Trumpet --------------------------------------------
+
+(defun port-env (dur)
+ (pwlv -1.0 (* 0.25 dur) 0.1 (* 0.5 dur) 0.0 dur))
+
+
+(defun chowning-fm-demo ()
+ (ss (seq (fm-bell 100.0 (/ 5.0 7.0) 10 10 1.0)
+ (fm-bell 150.0 (/ 5.0 7.0) 7 10 1.0)
+ (fm-bell 200.0 (/ 5.0 7.0) 15 7 1.0)
+ (fm-w-d a2) (fm-w-d b2) (fm-w-d c3) (fm-w-d d3) (fm-w-d e3)
+ (fm-w-d f3) (fm-w-d g3) (fm-w-d a3)
+ (fm-w-d a1) (fm-w-d b1) (fm-w-d c2) (fm-w-d d2) (fm-w-d e2)
+ (fm-w-d f2) (fm-w-d g2) (fm-w-d a2)
+ (fm-br c4) (fm-br d4) (fm-br e4) (fm-br f4) (fm-br g4)
+ (fm-br a4) (fm-br b4) (fm-br c5)
+ (double-carrier 0.6 440.0 1.0 1.0 0.5 3 1 (/ 3.0 1.5)))))
diff --git a/demos/pmorales/ks.lsp b/demos/pmorales/ks.lsp
new file mode 100644
index 0000000..8000f32
--- /dev/null
+++ b/demos/pmorales/ks.lsp
@@ -0,0 +1,33 @@
+;;; DSP in Nyquist
+;;; Karplus-Strong Algorithm
+;;; Coded by Pedro J. Morales.
+;;; e-mail: pmorales@iele-ab.uclm.es
+
+(load "pjmg.lsp")
+
+(setf ks-class (send class :new
+ '(cnt total-cnt last-output current-output string len total-len)))
+
+(send ks-class :answer :isnew '(pitch dur)
+ '((setf len (round (/ *sound-srate* (step-to-hz pitch))))
+ (setf total-len (* *sound-srate* dur))
+ (setf string (snd-samples (noise (/ (step-to-hz pitch))) len))
+ (setf cnt 0)
+ (setf total-cnt 0)
+ (setf last-output 0.0)
+ (setf current-output 0.0)))
+
+(send ks-class :answer :next '()
+ '((setf current-output (aref string cnt))
+ (setf (aref string cnt) (/ (+ current-output last-output) 2.0))
+ (setf last-output current-output)
+ (setf cnt (if (= (1- len) cnt) 0 (1+ cnt)))
+ (setf total-cnt (1+ total-cnt))
+ (if (= total-cnt total-len) NIL current-output)))
+
+(defun ks (pitch dur)
+ (let (obj)
+ (setf obj (send ks-class :new pitch dur))
+ (snd-fromobject 0.0 *sound-srate* obj)))
+
+(ss (seq (ks e2 2)(ks a2 2)(ks d3 2)(ks g3 2)(ks b3 2)(ks e4 2)))
diff --git a/demos/pmorales/partial.lsp b/demos/pmorales/partial.lsp
new file mode 100644
index 0000000..8619f8c
--- /dev/null
+++ b/demos/pmorales/partial.lsp
@@ -0,0 +1,30 @@
+;;; PARTIAL
+
+(setf *pmorales-path* (current-path))
+(load (strcat *pmorales-path* "pjmg.lsp"))
+
+
+(defun klin (fr coef)
+ (mult (sine (hz-to-step (* 300.0 fr coef)) 2.0) (pwev 3.0 3.0 1e-2)))
+
+(defun klines (coef)
+ (sim (at 0.0 (klin 6.0 coef))
+ (at 0.3 (klin 7.0 coef))
+ (at 0.5 (klin 5.5 coef))
+ (at 0.7 (klin 6.5 coef))))
+
+(defun bell-sequence ()
+ (sim (mult (sine (hz-to-step (* 300.0 (/ 3.14 5))) 6.0) (scale 4.0 (pwe 6.0 1e-2)))
+ (mult (sine (hz-to-step 300.0) 6.0) (pwl 2.0 0.75 3.0 1.0 4.0 0.75 5.0 0.2 6.0))
+ (mult (sine (hz-to-step (* 300.0 1.57)) 6.0) (pwl 3.0 0.75 4.0 0.5 5.0))
+ (mult (sine (hz-to-step (* 300.0 3.14)) 6.0) (pwl 2.5 0.5 4.0))
+ (at 0.5 (scale 2.0 (mult (sine (hz-to-step (* 300.0 6.3)) 6.0) (pwe 3.0 5e-3))))
+ (at 2.0 (scale 2.0 (mult (sine (hz-to-step (* 300.0 9.12)) 6.0) (pwe 3.0 1e-2))))
+ (at 0.7 (scale 2.0 (mult (sine (hz-to-step (* 300.0 15.7)) 6.0) (pwe 4.0 2e-2))))
+ (at 3.0 (klines 1.0))
+ (at 4.0 (klines 1.5))
+ (at 1.0 (mult (sine (hz-to-step (+ (* 300.0 6.3) 20.0)) 6.0)
+ (scale 5e-3 (pwe 2.0 1000.0 4.0))))
+))
+
+(defun bell-demo () (ss (scale 0.1 (bell-sequence))))
diff --git a/demos/pmorales/phm.lsp b/demos/pmorales/phm.lsp
new file mode 100644
index 0000000..bd206d0
--- /dev/null
+++ b/demos/pmorales/phm.lsp
@@ -0,0 +1,79 @@
+;;; DSP in Nyquist
+;;; Flute Physical Modelling
+;;; Based on Nicky Hind CLM Tutorial
+;;; (Based on Perry Cook Flute Physical Modelling)
+;;; Coded by Pedro J. Morales
+;;; e-mail: pmorales @iele-ab.uclm.es
+
+(load "pjmg.lsp")
+
+;; DELAY LINE
+
+(setf dl-class (send class :new '(cnt line len output)))
+
+(send dl-class :answer :isnew '(init-len)
+ '((setf cnt 0)
+ (setf len init-len)
+ (setf line (make-array len))
+ (dotimes (i len) (setf (aref line i) 0.0))))
+
+(send dl-class :answer :next '(val)
+ '((setf output (aref line cnt))
+ (setf (aref line cnt) val)
+ (setf cnt (if (= cnt (1- len)) 0 (1+ cnt)))
+ output))
+
+(defun make-delay-line (len)
+ (send dl-class :new len))
+
+(defun delay-line (dl-obj val)
+ (send dl-obj :next val))
+
+; UNA EXCITACION
+
+(defun flute-exc (noise-lev vib-amount vib-rate atk dec dur)
+ (let ((current-flow (sim (pwl atk 0.55 (- dur dec) 0.55 dur) ;puede variar 0.5 .. 0.8
+ (scale vib-amount (lfo vib-rate dur)))))
+ (sim current-flow
+ (scale noise-lev (mult current-flow (lp (noise dur) (/ *sound-srate* 2.0)))))))
+
+;; FLUTE PHYSICAL MODELLING
+(setf flute-class (send class :new '(sum1 sum1-output freq dur bore-delay emb-delay
+ period-samples out-sig last-sig current-bore)))
+
+(defun cubic-polynomial (x) (- x (expt x 3.0)))
+
+(send flute-class :answer :isnew '(exc emb-size ifreq idur)
+ '((setf sum1 exc)
+ (setf freq (step-to-hz ifreq))
+ (setf period-samples (round (/ *sound-srate* freq)))
+ (setf bore-delay (make-delay-line period-samples))
+ (setf emb-delay (make-delay-line (round (* emb-size period-samples))))
+ (setf last-sig 0.0)))
+
+(send flute-class :answer :next '()
+ '((setf sum1-output (snd-fetch sum1))
+ (when sum1-output
+ (progn
+ (setf current-bore (delay-line bore-delay last-sig))
+ (setf out-sig
+ (+ (* 0.7 (+ (* 0.55 current-bore)
+ (cubic-polynomial (delay-line emb-delay (+ sum1-output
+ (* 0.5 current-bore))))))
+ (* 0.3 last-sig)))
+ (setf last-sig out-sig)))))
+
+
+(defun flute (freq dur &key (noise-lev 0.0356) (atk 0.05) (dec 0.1) (emb-size 0.5)
+ (vib-amount 0.015) (vib-rate 5))
+ (let (obj)
+ (setf obj (send flute-class :new
+ (flute-exc noise-lev vib-amount vib-rate atk dec dur) emb-size freq dur))
+ (hp (snd-fromobject 0.0 *sound-srate* obj) 20.0)))
+
+(ss (seq (flute a4 0.5 :dec 0.01)
+ (flute b4 0.5 :dec 0.01)
+ (flute c5 0.5 :dec 0.01)
+ (flute gs4 1.0)))
+
+
diff --git a/demos/pmorales/pjmg.lsp b/demos/pmorales/pjmg.lsp
new file mode 100644
index 0000000..b949dd6
--- /dev/null
+++ b/demos/pmorales/pjmg.lsp
@@ -0,0 +1,40 @@
+;;; PJMG.LSP
+;;; Rutinas para Nyquist
+
+; Some utilities and functions not defined in
+; the released version of Nyquist
+
+
+(defun set-current-file (cf)
+ (setf *CURRENT-FILE* cf))
+
+(defun l () (load *CURRENT-FILE*))
+
+;; A comment by Dannenberg on the following function:
+;; This function takes an expression for a sound and
+;; finds its peak value. This forces a computation of all
+;; samples, which are saved in memory (4 bytes per sample).
+;; The samples are then normalized and written to a file.
+;; This should be fine for short examples, but is not
+;; recommended for general use because you may run out
+;; of memory. See the manual for more notes on normalization.
+;;
+(defun ss (m)
+ (let ((m-max (peak m NY:ALL)))
+ (s-save (scale (/ 1.0 m-max) m) NY:ALL *default-sound-file*
+ :play *soundenable*)))
+
+(defun randi1 (fr dur)
+ (let ((d (get-duration dur)))
+ (snd-white *rslt* fr d)))
+
+(defun randi2 (fr dur)
+ (at 0.0 (snd-white 0.0 fr dur)))
+
+(defun randh1 (fr dur)
+ (let ((d (get-duration dur)))
+ (snd-compose (noise d) (quantize (ramp d) (round (* fr d))))))
+
+(defun rndh2 (fr dur)
+ (at 0.0 (snd-compose (noise dur)
+ (quantize (ramp dur) (round (* fr dur))))))
diff --git a/demos/pmorales/readme.txt b/demos/pmorales/readme.txt
new file mode 100644
index 0000000..fc662f0
--- /dev/null
+++ b/demos/pmorales/readme.txt
@@ -0,0 +1,27 @@
+Here there are a few sounds for Nyquist that
+I have coded for learning. Mostly are based
+on examples from Amsterdam Catalogue of
+CSound Computer Instruments,and some others
+are based on Computer Music Journal
+articles, Dodge & Jerse and F. R. Moore
+books.
+
+Karplus-Strong and Physical Modelling are
+implemented in Lisp.
+
+Albacete, Spain, 2 June 2.000
+
+Pedro J. Morales.
+pmorales@iele-ab.uclm.es
+
+----------------------------------------
+
+Please see examples_home.htm in the parent
+folder for an index to these files.
+
+Note that there are "helper" functions in
+pjmg.lsp that you may need to load before
+you run the code in these other files.
+
+Roger B. Dannenberg
+rbd@cs.cmu.edu
diff --git a/demos/probability_distributions.htm b/demos/probability_distributions.htm
new file mode 100644
index 0000000..6ba06c7
--- /dev/null
+++ b/demos/probability_distributions.htm
@@ -0,0 +1,137 @@
+<html>
+<head>
+ <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Probability Distributions</title>
+</head>
+<body>
+<h1>Probability Distribution Generators</h1>
+<h2>
+
+<p><b>Andreas Pfenning and Roger B. Dannenberg</b></p></h2>
+
+<p>This page describes some uses of probability distribution
+functions that are defined in <tt>lib/distributions.lsp</tt>, so
+be sure to <tt>(load "distributions")</tt> before trying these
+examples. See the manual for more details.
+
+<p>A probability distribution generator outputs a single
+number based the particular distribution and the input parameters. These
+functions were created to supplement the uniform random generator <tt>(real-random)</tt>.
+There are two types of distributions: continuous
+and discrete. For either distribution,
+looking at the diagrams will show you the likely range of outputs. In
+a continuous distribution, the likelihood of returning a value between
+two points on the x-axis is equal to the area under the curve between those
+two points. Every continuous distribution
+has the property that the total area under the curve = 1. In
+a discrete distribution, only integers >= 0 are allowed as output. Each
+one of these numbers has a probability of being returned which is equal
+to the height of the bar in the diagram. For
+the user's convenience, many distributions have optional bounds that come
+in useful for certain applications.
+
+<p><h3>Example 1 – Varying time with a continuous
+distribution generator</h3>
+
+<p>One of the most common distributions found in algorithmic
+composition is known as the Poisson process. This
+consists of a sequence of notes or events separated by an amount
+of time determined by an exponential distribution. The resulting
+sequence of events has the following property: every
+point in time is equally likely to be that start of a note. Another
+property is that, the probability of an event happening in the next
+unit of time is completely independent of how long it has been since
+the previous event. These distributions are naturally occuring when
+events happen randomly without any coordination.
+
+<p>The following
+is just one example how to use the exponential distribution. The
+first input parameter, .25, spreads the distribution out so that higher
+values are more likely. The second
+input is optional and is an upper bound on the output.
+
+<pre>(play (seqrep (i 20)
+ (pluck c4 (* 0.5 (exponential-dist .25 2.0)))))
+</pre>
+
+<p><h3>Example 2 – Varying pitch with a discrete distribution
+generator</h3>
+
+<p>Discrete distribution generators are useful for changing
+pitch (to integer values). Constraining the output to
+a whole number means that every pitch is going to be in the chromatic scale. In
+the case of the binomial distribution, both parameters together determine
+the mean. One way to get feel for
+how the different parameters affect the distribution is to print values
+as you generate them. Distribution
+parameters may require some tweaking to produce a desired affect. In
+some cases, altering the parameters can yield unexpected and interesting
+sounds.
+
+<pre>(defun try-binomial ()
+ (play (seqrep (i 20)
+ (pluck (+ (binomial-dist 6 .5) c4) 0.1))))
+</pre>
+
+
+<p><h3>Example 3 – Using granular synthesis with pitch
+distribution</h3>
+
+<p>In granular synthesis, interesting sounds can be made
+by having a pitch vary according to some distribution other than
+the simple uniform distribution. In <tt>lib/dist-test.lsp</tt>,
+there is a a granular synthesis function that can take in any distribution
+(within the bounds of granular synthesis) and vary the pitch of the tone
+based on that distribution. To do
+this, you pass in a parameterless function as a parameter. Since most
+distribution functions take parameters, it is necessary to create
+a <i>continuation</i> as shown below using a <tt>lambda</tt> expression.
+
+<pre>(defun make-gamma (nu high)
+ (lambda () (gamma-dist nu high)))
+</pre>
+
+<p>Here, <tt>make-gamma</tt> takes two parameters and returns a
+<i>function</i> with no parameters. This no-parameter function
+remembers the values of <tt>nu</tt> and <tt>high</tt> and
+will call <tt>gamma-dist</tt> with these. For example, try
+<pre>(apply (make-gamma 2 5.0) nil)</pre>
+(The <tt>apply</tt> function applies a function to a list of
+arguments; in this case the list is nil, so there are no arguments.)
+This example just makes the function and uses it once, so there's
+not much point, but in the granular synthesis example, the
+function will be called many times. Unlike passing a number as
+a parameter, passing a function means that the granular synthesis
+function can call the function for every grain, resulting in a
+new value for each grain. (Be sure to load <tt>dist-test.lsp</tt>
+before running this example.)
+
+<pre>(defun try-pitch-dist ()
+ (play (stretch 4
+ (simrep (i 4)
+ (pitch-dist-granulate "demos/demo-snd.aiff" 0.04 0.0 0.02 0.001
+ (make-gamma 2 5.0) 0 0)))))
+</pre>
+
+<p><h3>Example 4 – Using granular synthesis with grain
+length distribution</h3>
+
+<p>The length of grains can also be made to vary by a
+distribution passed in as a continuation. Here
+is an example.
+<pre>
+(defun make-gauss (xmu sigma low high)
+ (lambda ()(gaussian-dist xmu sigma low high)))
+
+(defun try-len-dist ()
+ (play (stretch 4
+ (simrep (i 2)
+ (len-dist-granulate "demos/demo-snd.aiff"
+ (make-gauss 0.0 1.0 0.1 .5) 0.02 0.001 2.0 0 0)))))
+</pre>
+
+<h3>A Challenge</h3>
+Can you come up with a set of examples that clearly illustrates different distributions through sound? (I would love to add more examples here. -RBD)
+
+</body>
+</html>
diff --git a/demos/rhythm_tutorial.htm b/demos/rhythm_tutorial.htm
new file mode 100644
index 0000000..d6c6313
--- /dev/null
+++ b/demos/rhythm_tutorial.htm
@@ -0,0 +1,2 @@
+<html>
+ <head> <meta name="GENERATOR" content="Microsoft FrontPage 3.0"> <title>Rhythmic Pattern Tutorial</title> </head> <body> <h1>Rhythmic Pattern Tutorial</h1> <p>This example illustrates a very simple percussion sound created with noise and using the sound to generate a rhythm.</p> <p>The sound is created by filtering noise. The filter is controlled using the piece-wise linear function (<code>pwl</code>):</p> <pre>(defun pulse (dur) (stretch dur (hp (noise) (pwl 0 15 0.2 6000 0.6 15000 0.75 7))))</pre> <p>A sequence of sounds is constructed and repeated in the following code. Notice that each time through the pattern,<br> the scale factor is increased by 0.1, giving the whole sequence a crescendo:</p> <pre>(defun pulsepat (&amp;optional (rep 16)) (seqrep (i rep) (stretch 0.2 (scale (* i 0.1) (seq (pulse 1) (pulse 1) (pulse 2) (pulse 2)))))) (play (pulsepat 17))</pre> <h2>Pitched Patterns</h2> <p>This example uses the <code>ring</code> function from the <a href="scratch_tutorial.htm">Vinal Scratch Tutorial</a>. When the pitch parameter is increased, we hear a kind of electronic bass sound. Try this:</p> <pre>(play (ring 0.4 30 1.2))</pre> <p>These notes can be combined to create a pattern. The <code>techno</code> function creates a short pattern of 3 notes repeated any number of times:</p> <pre>(defun techno (rep) (seqrep (i rep) (scale 0.8 (sim (scale 0.8 (at 0.0 (ring 0.4 30 1.2))) (scale 0.6 (at 0.2 (ring 0.2 30 0.9))) (scale 0.7 (at 0.3 (ring 0.1 30 1.1))) ))))</pre> <p>Try this:</p> <pre>(play (techno 3))</pre> <p>The following combines and transposes rhythmic segments to create a bass line:</p> <pre>(play (seqrep (i 2) (seq (techno 2) (transpose 5 (techno 2)) (transpose -2 (techno 1)) (transpose 3 (techno 1)) (techno 2))))</pre> <h3>Layers for Richer Texture</h3> <p>Sounds can often be combined with time and pitch offsets to create richer textures. The following layers two sequences based on the same <code>techno</code> function:</p> <pre>(play (sim (scale 0.4 (at 0.0 (seqrep (i 2) (seq (techno 2) (transpose 5 (techno 2)) (transpose -2 (techno 1)) (transpose 3 (techno 1)) (techno 2))))) (scale 0.2 (at 0.1 (seqrep (i 2) (seq (transpose 2 (techno 2)) (transpose 7 (techno 2)) (transpose -4 (techno 1)) (transpose 5 (techno 1)) (transpose -2 (techno 2)))) ))))</pre> <p>Note that the second layer is almost but not exactly a transposition of the first layer. If it were an exact transposition, it would make sense to encapsulate the first layer in a function and call it twice. The following variation is much more concise, but it does not compute exactly the same sound:</p> <pre>(defun bass-line () (seqrep (i 2) (seq (techno 2) (transpose 5 (techno 2)) (transpose -2 (techno 1)) (transpose 3 (techno 1)) (techno 2))))</pre> <pre>(play (sim (scale 0.4 (bass-line)) (scale 0.2 (at 0.1 (transpose 2 (bass-line))))))</pre> <h2>Another Example</h2> <p>This example also uses the <code>ring</code> function from the <a href="scratch_tutorial.htm">Vinal Scratch Tutorial</a>. </p> <pre>(play (seqrep (i 17) (lp (scale (+ (* i 0.05 ) 0.3) (seq (transpose -4 (ring 0.1 32 0.6)) (transpose -5 (ring 0.05 20 0.2)) (transpose (* 2 i) (ring 0.1 27 0.5)) (transpose -3 (ring 0.05 22 0.1)) (transpose (* i 3) (ring 0.1 28 0.4)) (ring 0.05 31 0.7))) (* 100 i))))</pre> <p>This play 17 repetitions of a sound. Each time, the sound is a bit louder, the low-pass frequency is raised by 100 Hz, and two of the transpositions are increased. This creates a rhythmic and evolving sound.</p> <p><br> </p> <p>&nbsp;</p> </body> </html>
diff --git a/demos/scratch_tutorial.htm b/demos/scratch_tutorial.htm
new file mode 100644
index 0000000..c26c22e
--- /dev/null
+++ b/demos/scratch_tutorial.htm
@@ -0,0 +1,93 @@
+<html>
+
+
+<head>
+<title>Vinal Scratch Tutorial</title>
+<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
+</head>
+
+<body>
+
+<h1>Vinal Scratch Tutorial</h1>
+
+<p>This sound reminds me of the effect of dragging a needle across a vinal record.</p>
+
+<pre>(defun ring (dur pch scl)
+ (let ((modstep1 (hz-to-step (* (step-to-hz pch) (sqrt 2.0))))
+ (modstep2 (hz-to-step (* (step-to-hz pch) (sqrt 11.0)))))
+ (stretch dur
+ (mult
+ (env 0.05 0.1 0.2 1 0.6 0.24 1)
+ (fmosc pch (mult
+ (pwl 0.07 1800 0.15 1000 0.4 680 0.8 240 1 100 1)
+ scl
+ (osc modstep1)
+ (osc modstep2) ))) )))</pre>
+
+<p>The following plays an example sound from this function:</p>
+
+<pre>(play (ring 7.1 (hz-to-step 1) 1.2))</pre>
+
+<p>Here is a brief description of how this function works: The sound is created by an FM
+oscillator. The modulation comes from two sinusoids operating at low frequencies
+multiplied together. The sinusoids are not harmonically related, so an irregular pulse is
+generated by their product. This is scaled further by a piece-wise linear envelope that
+adds more variation. To make the sinusoids inharmonically related, their frequencies are
+scaled by the square root of 2 and the square root of 11. The variables <code>modstep1</code>
+and <code>modstep2</code> are initialized to these computed frequencies.</p>
+
+<p>The following example combines several instances of <code>ring</code> with different
+parameters:</p>
+
+<pre>(play (sim (scale 0.15 (at 2.9 (ring 7.1 (hz-to-step 1) 1.2)))
+ (scale 0.175 (at 4.9 (ring 5.1 (hz-to-step 2) 1.414)))
+ (scale 0.2 (at 6.9 (ring 3.1 (hz-to-step 4) 1.8)))))
+</pre>
+
+<h2>Other Sounds Using Ring</h2>
+
+<p>The same <code>ring</code> function can be used to achieve other sounds. Listen to
+these examples:</p>
+
+<pre>(play (sim
+ (scale 0.35 (at 1.5 (ring 4 1 1)))
+ (scale 0.325 (at 4 (ring 4 4 2)))
+ (scale 0.3 (at 7.5 (ring 4 10 4))) ))</pre>
+
+<p>These instances use a higher pitch parameter than the previous ones.<br>
+</p>
+
+<h2>Another Related Sound</h2>
+
+<p>The following creates a sound using FM and a wave table derived from a vocal sound.</p>
+
+<pre>(defun vocrap (&amp;optional (pch 16) (dur 1))
+ (if (not (boundp '*voc-table1*)) (mk-voc1-table))
+ (fmosc pch (stretch dur (pwl 0 3 0.1 -20 0.2 20 0.3 30
+ 0.4 -10 0.5 15 0.6 0
+ 0.8 -30 1 60 1)) *voc-table1*))</pre>
+
+<p>This function uses a special test to make sure that <code>*voc-table1*</code> is
+initialized. If it is not, it would be an error to read or test it, but you can query to
+find out if the variable is bound or unbound. (Global variables become bound when you
+assign a value to them.) The <code>boundp</code> function takes an atom (note the use of
+the single quote to denote an atom, the name of the variable, rather then the variable's
+value) and returns true if the variable is bound.</p>
+
+<p>Here is the definition for <code>mk-voc1-table</code>. You might have to replace the
+filename depending upon how your system is configured.:</p>
+
+<pre>(defun mk-voc1-table ()
+ (if (not (boundp 'voc-snd1))
+ (setf voc-snd1 (s-read &quot;./test/voc1.snd&quot;)))
+ (setf *voc-table1* (list voc-snd1 16 T)))</pre>
+
+<p>The following shows one way to invoke <code>vocrap</code>: </p>
+
+<pre>(play (seqrep (i 4) (vocrap)))</pre>
+
+<pre>
+</pre>
+</body>
+</html>
+
diff --git a/demos/sdl/ej2.lsp b/demos/sdl/ej2.lsp
new file mode 100755
index 0000000..630a41f
--- /dev/null
+++ b/demos/sdl/ej2.lsp
@@ -0,0 +1,66 @@
+;; SDL. ejemplo
+;; BWV 1069
+;; pmorales. Junio, 2007
+
+
+(setf *autonorm-type* 'previous)
+
+(load "sdl")
+
+(defun analog-saw (pitch dur atk rel det reson-freq)
+ (let ((hz (step-to-hz pitch)))
+ (reson
+ (mult 0.5
+ (sum -0.1 (pwev 0.1 atk 1 dur 0.8 (+ dur rel) 0.1))
+ (sum (stretch (+ dur rel) (osc-saw hz))
+ (stretch (+ dur rel) (osc-saw (+ hz det)))))
+ (sum (* 3 hz) (mult (* 8 hz) (sum -0.1 (pwev 1.1 (+ dur rel) 0.1))))
+ reson-freq 1)))
+
+(defun sint1 (&key pitch (idur 1) (din 1) (reson 1000))
+ (scale din (analog-saw pitch idur 0.002 .3 3 reson)))
+
+(setf voz-1
+ '((TF 1)
+ (INIT-INSTR "i1" sint1) (INSTRUMENT "i1") (ATTR :mm 100)
+ (ATTR :idur 0.1)(PWL-POINT :reson 1000)
+ 2 (:c4 1) :d4 (:e4 2) :c4 :g4 :e4 :a4 (:g4 1) :f4
+ (ATTR :idur 0.5)(:g4 4)(ATTR :idur 0.15)
+ (:a4 1) :c5 :f4 :a4 :g4 :f4 :e4 :g4 :f4 :a4 :d4 :f4 :e4 :d4 :c4 :d4 :e4 :f4 (:g4 2)
+ :a3 :c4 :d4 :f4
+ :g3 :b3 :c4 :e4 (:f3 1) :e4 :d4 :c4 :g3 :d4 :c4 :b3
+ (ATTR :idur 0.5) (LABEL :t1)(:c4 4) 2
+ (PWL-POINT :reson 2000)
+ (ATTR :idur 0.1) (:g3 1) :f3 :e3 :f3 :d3 :e3 (:c3 2) (:c4 3)
+ (:b3 1) :a3 :b3 (:c4 2) :a4 :b3 :g4 :a3 :f#4
+ (:g3 1) :c4 :b3 :a3 :g3 :f3 :e3 :d3 :c3 :b3 :a3 :g3 :f#3 :e3 :d3 :c3 :b2 :a3 :g3 :f#3
+ :e3 :d3 :c3 :b2 :a2 :g3 :f#3 :e3 :d3 :c3 :b2 :a2 :g2 :g3 :b3 :d4
+ (ATTR :idur 0.5) (:e4 4) 1
+ (ATTR :idur 0.2)(:f3 1) :a3 :c4 (ATTR :idur 2)(:d4 4)
+ (PWL-POINT :reson 4000)
+))
+
+(setf voz-2
+ '((TF 1)
+ (INIT-INSTR "i1" sint1) (INSTRUMENT "i1") (ATTR :mm 100)
+ (ATTR :idur 0.15) (PWL-POINT :reson 1000)
+ (AT-LABEL :t1)2 (:g4 1) :a4 (:b4 2) :g4
+ :c5 :b4 :e5 (:d5 1) :c5
+ (ATTR :idur 2)(:d5 4)
+ (PWL-POINT :reson 1000)
+ (ATTR :idur 0.1) (:e5 1) :g5 :c5 :e5 :d5 :c5 :b4 :d5 :c5 :e5 :a4 :c5
+ :b4 :a4 :g4 :a4 :b4 :c5 (:d5 2) :e4 :g4 :a4 :c5 :d4 :f#4 :g4 :b4
+ (:c4 1) :b4 :a4 :g4 :d4 :a4 :g4 :f#4 (:g4 4)
+ 1 (:c5 1) :e5 :g5
+ (ATTR :idur 1)(:a5 5)
+ (PWL-POINT :reson 4000)
+ (ATTR :idur 0.8)(:b4 1) :d5 :f5
+ (ATTR :idur 1)(:g5 5)))
+
+(setf *my-time-labels* (sdl->timelabels voz-1))
+
+(defun vox-1 () (timed-seq (sdl:normalize-score-duration (sdl->score voz-1))))
+(defun vox-2 () (timed-seq (sdl:normalize-score-duration (sdl->score voz-2 *my-time-labels*))))
+
+(play (sim (vox-1) (vox-2)))
+I
diff --git a/demos/sdl/inv-08.lsp b/demos/sdl/inv-08.lsp
new file mode 100644
index 0000000..f702d2d
--- /dev/null
+++ b/demos/sdl/inv-08.lsp
@@ -0,0 +1,180 @@
+; *********************************************
+; Inventio # 8 a 2 voci BWV 779. J. S. Bach.
+; Score Description Library example
+; Translated from a previous lambda Music score
+; by Pedro J. Morales.
+; Junio, 2005
+; Revised: July 25 2007
+; Nyquist 2.37
+; *********************************************
+
+(load "sdl")
+
+(setf *autonorm-type* 'previous)
+
+
+(defun analog-saw (pitch dur atk rel det reson-freq)
+ (let ((hz (step-to-hz pitch)))
+ (set-logical-stop
+ (reson
+ (mult 0.5
+ (sum -0.1 (pwev 0.1 atk 1 dur 0.8 (+ dur rel) 0.1))
+ (sum (stretch (+ dur rel) (osc-saw hz))
+ ; (scale 0.5 (stretch (+ dur rel) (osc-saw (* 2 hz))))
+ (stretch (+ dur rel) (osc-saw (+ hz det)))))
+ (sum (* 3 hz) (mult (* 8 hz) (sum -0.1 (pwev 1.1 (+ dur rel) 0.1))))
+ reson-freq 1)
+ dur)))
+
+
+(defun xan2 (&key pitch)
+ (analog-saw pitch 0.001 0.02 2.0 2 4000))
+
+(defun xan3 (&key pitch (rel 2.5) (atk 0.02)(reson 4000)(din 1))
+ (scale din (analog-saw pitch 0.001 atk rel 3 reson)))
+
+
+; SCORE --------------------------------------------------------------------
+
+(setf voz-1
+ '((ATTR :mm 120.0) ; 140?
+ (INIT-INSTR "i1" xan3) (INSTRUMENT "i1")
+ (PWL-POINT :rel 1.5)(ATTR :atk 0.005)
+ (DELTA 2) (f4 2) a4 f4 c5 f4
+(PWL-POINT :rel 2.5)
+f5 (e5 1) d5 c5 d5 c5 :bb4 a4 :bb4 a4 g4 (f4 2)
+ a4 c5 a4 f5 c5
+; linea 2
+ (PWL-POINT :rel 1.0)
+ (a5 1) c6 :bb5 c6 a5 c6 :bb5 c6 a5 c6 :bb5 c6
+ :f5 :a5 :g5 :a5 :f5 :a5 :g5 :a5 :f5 :a5 :g5 :a5
+ :d5 :f5 :e5 :f5 :d5 :f5 :e5 :f5 :d5 :f5 :e5 :f5
+; linea 3
+ (PWL-POINT :rel 3.0)
+ (MRK n5)
+ (:b4 2) :g4 :d5 :b4 :f5 :d5
+ (MRK n6)
+ (:g5 1) :a5 :g5 :f5 :e5 :f5 :e5 :d5 :c5 :d5 :c5 :bb4
+ (:a4 2)
+ (MRK n7)
+ (:d5 1) :c5 :b4 :c5 :b4 :a4 :g4 :a4 :g4 :f4
+; linea 4
+ :e4 :f4 :e4 :d4 (MRK n8)(:c4 2)
+ (:c5 1) :b4 (:c5 2)
+ (PWL-POINT :rel 4)
+ :e4 (PWL-POINT :rel 2) :f4 :c5 :e4 :c5 :d4 :b4 (MRK n9)
+ (PWL-POINT :rel 1.5)(:c5 4) 4 (MRK n10) 4
+; linea 5
+ 2 (:c5 2) :e5 :c5 :g5 :c5 :c6 (:b5 1) :a5 :g5 :a5 :g5 :f5 :e5 :f5 :e5
+ (MRK n11) :d5 :c5 :bb4 :c5 :a5
+ :c5 :a5 :bb4 :a5 :c5 :a5 :a4 :a5
+; linea 6
+ (PWL-POINT :rel 2.5)
+ (:bb4 2)(PWL-POINT :rel 2) :g4 :bb4 :g4 :d5 :g4 :g5 (:f5 1) :eb5 :d5 :eb5 :d5 :c5 :bb4 :c5 :bb4 :a4 (:g4 2) :bb4 :d5 :bb4 :g5 :d5
+; linea 7
+ (PWL-POINT :rel 3)
+ :bb5 :c#5 :bb5 :c#5 :bb5 :c#5
+ (MRK n12)
+ :d5 :a4 :f5 :d5 :a5 :f5
+ (MRK n12b)
+ (:g5 1) :f5 :g5 :bb5 :c5 :bb5 :d5 :bb5 :e5 :bb5 :c5 :bb5
+; linea 8
+ (MRK n12c)
+ :f5 :e5 :f5 :a5 :b4 :a5 :c#5 :a5 :d5 :a5 :b4 :a5
+ :e5 :d5 :e5 :g5 :a4 :g5 :b4 :g5 :c#5 :g5 :a4 :g5
+ (MRK n13)
+ (:f5 2) :d5 :bb4 :d5 :g4 :f5
+; linea 9
+ (MRK n14)
+ :e5 :c5 :a4 :c5 :f4 :eb5
+ (MRK n15)
+ (:d5 1) :f5 :eb5 :f5 :d5 :f5 :eb5 :f5 :d5 :f5 :eb5 :f5
+ (MRK n16)
+ :bb4 :d5 :c5 :d5 :bb4 :d5 :c5 :d5 :bb4 :d5 :c5
+ (PWL-POINT :rel 3) :d5
+ (PWL-POINT :rel 1)
+; linea 10
+ (MRK n17)
+ :g4 :bb4 :a4 :bb4 :g4 :bb4 :a4 :bb4 :g4 :bb4 :a4 (PWL-POINT :rel 1.5) :bb4
+ (MRK n18)
+ (PWL-POINT :rel 2)
+ (:e4 2) :c4 :g4 :e4 :bb4 :g4
+ (MRK n19)
+ (:c5 1) :d5 :c5 :bb4 :a4 :bb4 :a4 :g4 :f4 :g4 :f4 :eb4
+; linea 11
+ (:d4 2)
+ (PWL-POINT :rel 4)
+ (MRK n20)
+ (:g4 1) :f4 :e4 :f4 :e4 :d4 :c4 :d4 :c4 :bb3 :a3 :bb3 :a3 :g3
+ (:f3 2) (PWL-POINT :rel 2)
+ (MRK n21)
+ (:f4 1) :e4 (:f4 2) (MRK rall) :a3
+; rallentando
+ (:bb3 2.2) (:f4 2.4) (:a3 2.6) (PWL-POINT :rel 1) (:f4 2.8)
+ (MRK n22) (PWL-POINT :rel 3.2)
+ (:g3 3) (:e4 3.4) (MRK final)(DUR 4) (PWL-POINT :rel 5)(ATTR :din 0.5)(CH :a3 :c4 :f4)))
+(setf voz-2
+
+ '((ATTR :mm 120.0)
+ (INIT-INSTR "i1" xan3) (INSTRUMENT "i1")
+ (PWL-POINT :reson 100)(PWL-POINT :rel 1)(PWL-POINT :din 2.5)
+ (CHN 6)(PATCH 47) (DELTA 12)(DELTA 2) (:f3 2) :a3 :f3 :c4 :f3
+ (PWL-POINT :rel 1.5)(PWL-POINT :reson 500)(PWL-POINT :din 3)
+ :f4 (:e4 1) :d4 :c4 :d4 :c4 :bb3 :a3 :bb3 :a3 :g3
+ (PWL-POINT :din 1.5)
+; linea 2
+ (:f3 2) :a3 :c4 :a3 :f4 :c4 (:a4 1) :c5 :bb4 :c5 :a4 :c5 :bb4 :c5 :a4 :c5 :bb4 :c5
+ :f4 :a4 :g4 :a4 :f4 :a4 :g4 :a4 :f4 :a4 :g4 :a4
+; linea 3
+ (PWL-POINT :reson 2500)
+ :d4 :f4 :e4 :f4 :d4 :f4 :e4 :f4 :d4 :f4 :e4 :f4
+ (:b3 2) :g3 :c4 :g3 :e4 :c4
+ (PWL-POINT :rel 2)
+ (:f4 1) :g4 :f4 :e4 :d4 :e4 :d4 :c4 :b3 :c4 :b3 :a3
+; linea 4
+ (PWL-POINT :din 1)(PWL-POINT :rel 2)
+ (:g3 2) (:c4 1) :b3 :a3 :b3 :a3 :g3 :f3 :g3 :f3 :e3 :d3 :e3 :d3 :c3 :g3 :f3 :e3 :f3 (:g3 2) :g2
+ (PWL-POINT :rel 1.5)(PWL-POINT :reson 300)(PWL-POINT :din 3)
+ 2 :c3 (PWL-POINT :rel 2) :e3 :c3 :g3 :c3
+; linea 5
+ (PWL-POINT :rel 2.5)
+ (PWL-POINT :rel 1.5)(PWL-POINT :reson 500)
+ :c4 (:b3 1) :a3 :g3 :a3 :g3 :f3 :e3 :f3 :e3 :d3
+ (:c3 2) :e3 :g3 :e3 :c4 :g3 :eb4 :f#3 :eb4 :f#3 :eb4 :f#3
+; linea 6
+ :g3 (:f3 1) :eb3 :d3 :eb3 :d3 :c3 :bb2 :c3 :bb2 :a2
+ (PWL-POINT :rel 1.5)(PWL-POINT :din 1)
+ (:g2 2) :g3 :bb3 :g3 :d4 :g3 :g4 (:f4 1) :eb4 :d4 :eb4 :d4 :c4 :bb3 :c4 :bb3 :a3
+; linea 7
+ (PWL-POINT :rel 1.5)(PWL-POINT :reson 1500)(PWL-POINT :din 2)
+ :g3 :f3 :g3 :e4 :g3 :e4 :f3 :e4 :g3 :e4 :e3 :e4
+ :f3 :e3 :f3 :d4 :f3 :d4 :e3 :d4 :f3 :d4 :d3 :d4
+ (:bb3 2) :g3 :e3 :g3 :c3 :e3
+; linea 8
+ :a3 :f3 :d3 :f3 :b2 :d3 :g3 :e3 :c#3 :e3 :a2 (PWL-POINT :rel 1) :c#3
+ (PWL-POINT :rel 1.5)
+ (:d2 1) :d3 :c3 :d3 :g2 :d3 :a2 :d3 :bb2 :d3 :g2 (PWL-POINT :din 1.) :d3
+; linea 9
+ (PWL-POINT :din 1.)(PWL-POINT :rel 2)(PWL-POINT :reson 2000)
+ :c2 :c3 :bb2 :c3 :f2 :c3 :g2 :c3 :a2 :c3 :f2 :c3
+ (:bb2 2) :d3 :f3 :d3 :bb3 :f3
+ (PWL-POINT :din 2)(PWL-POINT :reson 1000)
+ (:d4 1) :f4 :eb4 :f4 :d4 :f4 :eb4 :f4 :d4 :f4 :eb4 :f4
+; linea 10
+ :bb3 :d4 :c4 :d4 :bb3 :d4 :c4 :d4 :bb3 :d4 :c4 :d4
+ :g3 :bb3 :a3 :bb3 :g3 :bb3 :a3 :bb3 :g3 :bb3 :a3 :bb3
+ (:e3 2) :c3 :f3 :c3 :a3 :f3
+; linea 11
+ (:bb3 1) :c4 :bb3 :a3
+ :g3 :a3 :g3 :f3 :e3 :f3 :e3 :d3 (:c3 2)
+ (:f3 1) :e3 :d3 :e3 :d3 :c3 :bb2 :c3 :bb2 :a2
+ (:g2 1.1) :a2 (:g2 1.2) :f2
+ (:c3 1.3) :bb2 (:a2 1.4) :bb2 (:c3 3.2)
+ (PWL-POINT :din 1)
+ (PWL-POINT :rel 2)(PWL-POINT :reson 3500) (:c2 3.4) (PWL-POINT :rel 4)(:f2 4)))
+
+
+(play
+ (sum
+ (scale 1 (timed-seq (sdl->score voz-1)))
+ (timed-seq (sdl->score voz-2))))
diff --git a/demos/sequence_example.htm b/demos/sequence_example.htm
new file mode 100644
index 0000000..7d29683
--- /dev/null
+++ b/demos/sequence_example.htm
@@ -0,0 +1,52 @@
+<html>
+
+
+<head>
+<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
+<title>Sequence Example</title>
+</head>
+
+<body>
+
+<h1>Sequence Example</h1>
+
+<p>A sequence of notes is often specified by a &quot;note list,&quot; consisting of times,
+durations, other transformations, and a parameterized behavior to generate the sound. The
+following is an example:</p>
+
+<pre>(defun ringpat1 ()
+ (scale 0.8
+ (sim
+ (scale 0.6 (at 0.0 (ring 0.6 45 2)))
+ (scale 0.5 (at 0.2 (ring 0.8 40 1.5)))
+ (scale 0.8 (at 0.6 (ring 1 44 1)))
+ (scale 0.7 (at 0.8 (ring 1.2 32 0.8)))
+ )))</pre>
+
+<p>Notice that there are 4 sounds. The sounds are shifted in time using the <code>at</code>
+transformation, and all four sounds are combined using the <code>sim</code> construction.
+Because of the time shifts, the sounds do not take place simultaneously, but they may
+overlap somewhat.</p>
+
+<p>Durations are specified by the first parameter to <code>ring</code>, so no <code>stretch</code>
+transformations are used here. Each sound is individually scaled.</p>
+
+<p>To play this sound, you need the <code>ring</code> function from <a
+href="scratch_tutorial.htm">Vinal Scratch Tutorial</a>. Then you can type:</p>
+
+<pre>(play (ringpat1))</pre>
+
+<p>Try the following combination, which plays a short and long version of <code>ringpat1</code>
+at about the same time:</p>
+
+<pre>(play (sim
+ (scale 1.0 (at 0.0 (ringpat1)))
+ (scale 0.7 (at 0.05 (stretch 1.5 (ringpat1)))) ))</pre>
+
+<pre>
+
+
+</pre>
+</body>
+</html>
+
diff --git a/demos/shepard.lsp b/demos/shepard.lsp
new file mode 100644
index 0000000..8c528c5
--- /dev/null
+++ b/demos/shepard.lsp
@@ -0,0 +1,195 @@
+; Shepard tones and paradoxes
+
+; to use try
+; (playscale (majorscale 60))
+; (playscale (minorscale 60))
+; (playscale (chromascale 60))
+; (playparadoxscale (chromascale 60))
+
+; for shepard sweeps, try
+; (play (sheptone-sweep 60 60 2 72 60 12 4))
+
+; the signature of sheptone-sweep should tell what the parameters do
+; (defun sheptone-sweep (pitch-1 centerpitch-1 duration pitch-2 centerpitch-2
+; overtonesemi overtones
+; &optional (wavetable *sine-table*))
+
+; Some notes about how this works:
+; Shepard tones consist of harmonics that are an octave apart, thus
+; the ratios are 1, 2, 4, 8, 16, etc. Note that the pitch is ambiguous
+; in the sense that there could be a missing fundamental at 0.5, 0.25, etc.
+; The other trick is that the spectral shape is constant. The amplitude
+; of each harmonic is a function of its absolute frequency. Here, the
+; shape is triangular so that as the frequency sweeps upward, harmonics
+; (which are ramping up in frequency) fade in, reach a maximum, and fade out.
+;
+; In this implementation, each harmonic is generated using an FM oscillator
+; controlled by a frequency ramp. The harmonic is multiplied by an envelope
+; to implement the spectral shape function. The envelope is computed by
+; running the frequency control (with some scaling) into a SHAPE function
+; that uses a triangular table to implement the spectral shape.
+;
+; Warning: Although I have not analyzed this code too carefully, I (RBD)
+; believe that the oscillators keep sweeping up to higher and higher
+; frequencies even after the amplitude drops to zero. This is not only
+; wasteful, but when oscillators start to alias, they run slower. If you
+; generate a very long Shepard tone with harmonics spanning many octaves,
+; the run time could get to be very large. A better implementation would
+; start the harmonics when they enter the non-zero part of the spectral
+; envelope and end them when they leave it.
+
+
+(setf *onepi* 3.141592654)
+(setf *twopi* (* 2 pi))
+(setf *halfpi* (/ pi 2))
+
+
+; envshaper is a raised cosine curve used to control
+; the spectral shape. Its domain is 0 to 2
+; it transforms (0 2) into 0 1
+; it has to be used like
+; (shape s (envshaper) 1)
+
+(defun envshaper ()
+ (mult (sum 1 (hzosc (const (/ 1.0 2.0) 2) *table* 270)) 0.5))
+
+
+; some utility functions
+
+;; ISEQ-HELPER -- generates an integer sequence
+(defun iseq-helper (a b)
+ (let ((mylist '()))
+ (dotimes (i (1+ (- b a)) (reverse mylist))
+ (setf mylist (cons (+ a i) mylist)))))
+
+;; ISEQ -- sequence of integers from a to b
+(defun iseq (a b)
+ (if (> a b) (reverse (iseq-helper b a))
+ (iseq-helper a b)))
+
+
+(defun floor (x)
+ (if (< x 0)
+ (1- (truncate x))
+ (truncate x)))
+
+
+
+; the main part
+
+(defun sheptone-sweep-helper (pitch-1 centerpitch-1
+ duration
+ pitch-2 centerpitch-2
+ overtonesemi overtones
+ &optional (wavetable *sine-table*))
+ (let ((mytone (const 0 duration))
+ (maxovertones (+ (floor (/ (float (max (abs (- pitch-1 centerpitch-2))
+ (abs (- pitch-1 centerpitch-2))))
+ overtonesemi))
+ overtones 2))
+ (ampshaper (envshaper)))
+ ;; synthesize and sum maxovertones partials
+ (dolist (i (iseq (- maxovertones) maxovertones) mytone)
+ (progn
+ ;; partials start at pitch-1, spaced by overtonesemi (normally 12)
+ (setf startpitch (+ pitch-1 (* i overtonesemi)))
+ ;; partials end at pitch-2 + offset
+ (setf endpitch (+ pitch-2 (* i overtonesemi)))
+ ;; f is the frequency modulation (in hz)
+ (setf f (pwe 0 (step-to-hz startpitch)
+ duration (step-to-hz endpitch)))
+ ;; p is the pitch in steps
+ (setf p (pwl 0 startpitch duration endpitch))
+ ;; c is the centerpitch curve
+ ;; (probably we could compute this outside the loop)
+ (setf c (pwl 0 centerpitch-1 duration centerpitch-2))
+ ;; normwidthfactor is used to map pitch curves into the spectral shape
+ ;; function (range 0 to 2)
+ (setf normwidthfactor (/ 1.0 (* overtones overtonesemi)))
+ ;; a is the amplitude envelope: f(p - c)
+ (setf a (shape (mult (diff p c) normwidthfactor)
+ ampshaper 1))
+ ;; voice is one partial
+ (setf voice (mult a (hzosc f wavetable)))
+ ;; sum the partials into mytone
+ (setf mytone (sum mytone voice))
+ )
+ )))
+
+
+(defun sheptone-sweep (pitch-1 centerpitch-1 duration pitch-2 centerpitch-2
+ overtonesemi overtones
+ &optional (wavetable *sine-table*))
+ (normalize ;; note: you might not want to normalize as is done here
+ ;; use an envelope to get a smooth start and stop
+ (mult (sheptone-sweep-helper pitch-1 centerpitch-1
+ duration
+ pitch-2 centerpitch-2
+ overtonesemi overtones wavetable)
+ (env 0.05 0 0.05 1 1 1 duration))))
+
+
+;; SHEPTONE is a special case of sheptone-sweep.
+;; The spectral centroid and pitch is constant.
+(defun sheptone (pitch centerpitch duration
+ overtonesemi overtones
+ &optional (wavetable *sine-table*))
+ (sheptone-sweep pitch centerpitch duration pitch centerpitch
+ overtonesemi overtones
+ wavetable))
+
+(defun majorscale (basepitch)
+ (mapcar (lambda (x) (+ basepitch x)) '(0 2 4 5 7 9 11 12)))
+
+(defun minorscale (basepitch)
+ (mapcar (lambda (x) (+ basepitch x)) '(0 2 3 5 7 8 10 12)))
+
+(defun chromascale (basepitch)
+ (mapcar (lambda (x) (+ basepitch x)) (iseq 0 12)))
+
+
+;; MAKE-TABLE turns a function of 0-1 into a lookup table
+(defun make-table (func-exp points)
+ (let ((table (make-array points)))
+ (dotimes (i points)
+ (setf (aref table i)
+ (funcall func-exp (/ (float i) (float points)))))
+ (list (snd-from-array 0.0 points table) (hz-to-step 1) T)
+ ))
+
+
+(defun erich-wave (skew)
+ (make-table
+ (lambda (x) (if (< (abs skew) 0.000001) (sin (* *twopi* x))
+ (*
+ (/ (sin (* *twopi* x)) (- (/ 1.0 skew)
+ (cos (* *twopi* x))))
+ (/ (sqrt (- 1.0 (* skew skew))) skew))))
+ 2048))
+
+
+;; NORMALIZE -- normalize a sound
+;;
+(defun normalize (s &optional (maxvol 0.8) (maxlen 44100))
+ (let* ((mysound s)
+ (vol (peak mysound maxlen)))
+ (scale (/ (float maxvol) vol) mysound)))
+
+(defun playsafe (s)
+ (play (normalize s)))
+
+;; PLAYSCALE uses SHEPTONE to synthesize a scale that goes up on every
+;; step, but never actually ends up an octave higher
+;;
+(defun playscale (scaleseq &optional (duration 1) (wavetable *sine-table*))
+ (mapcar (lambda (x) (play (sheptone x 60 duration 12 4 wavetable)))
+ scaleseq))
+
+
+;; PLAYPARADOXSCALE uses sheptone to go up by half steps, yet end up
+;; an octave lower than it starts
+;;
+(defun playparadoxscale (scaleseq
+ &optional (duration 1) (wavetable *sine-table*))
+ (mapcar (lambda (x y) (play (sheptone x y duration 12 4 wavetable)))
+ scaleseq (reverse scaleseq)))
diff --git a/demos/shepard.ny b/demos/shepard.ny
new file mode 100644
index 0000000..2bd10a6
--- /dev/null
+++ b/demos/shepard.ny
@@ -0,0 +1,139 @@
+;nyquist plug-in
+;version 1
+;type generate
+;name "Shephard glissando"
+;action"Creating Shephard glissando"
+;info "Shephard-Risset glissando\nwritten by Erich Neuwirth"
+;control pitch1 "Start pitch" real "MIDInote" 60 24 96
+;control pitch2 "End pitch" real "MIDInote" 72 24 96
+;control cpitch1 "Start filter pitch" real "MIDInote" 60 24 96
+;control cpitch2 "End filter pitch" real "MIDInote" 60 24 96
+;control overtonesemi "Overtone interval" real "MIDInote" 12 3 24
+;control overtones "Overtones" int "" 4 1 8
+;control duration "Duration" real "seconds" 1.5 0.3 30
+;control skew "Tone skewness" real "" 0.0 0.0 0.99
+
+(setf overtones (truncate overtones))
+
+(setf *onepi* 3.141592654)
+(setf *twopi* (* 2 pi))
+(setf *halfpi* (/ pi 2))
+
+
+(defun make-table (func-exp points)
+ (let ((table (make-array points)))
+ (dotimes (i points)
+ (setf (aref table i)
+ (funcall func-exp (/ (float i) (float points)))))
+ (list (snd-from-array 0.0 points table) (hz-to-step 1) T)
+ ))
+
+
+(defun erich-wave (skew)
+ (make-table
+ (lambda (x) (if (< (abs skew) 0.000001) (sin (* *twopi* x))
+ (*
+ (/ (sin (* *twopi* x)) (- (/ 1.0 skew)
+ (cos (* *twopi* x))))
+ (/ (
+ sqrt (- 1.0 (* skew skew))) skew))))
+ 2048))
+
+
+(defun pitchenv (pitch centerpitch halfwidth)
+ (let ((xarg (abs (/ (- (float pitch) centerpitch) halfwidth))))
+ (if (> xarg 1) 0
+ (/ (+ (cos (* *onepi* xarg)) 1.0) 2.0))
+ ))
+
+
+
+
+; envshaper is shifted from 0 to 2
+; it transforms (0 2) into 0 1
+; to use it as envelope distorter, it has to be used like
+; (shape s (envshaper) 1)
+
+(defun envshaper ()
+ (mult (sum 1 (hzosc (const (/ 1.0 2.0) 2) *table* 270)) 0.5))
+
+
+; some utility functions
+
+(defun normalize (s &optional (maxvol 0.8) (maxlen 44100))
+ (let* ((mysound s)
+ (vol (peak mysound maxlen)))
+ (scale (/ (float maxvol) vol) mysound)))
+
+
+(defun buffer (s t1 duration t2)
+ (let ((timebase (hzosc (pwl (+ duration t1 t2)))))
+ (sim timebase (at t1 (cue s)))))
+
+
+(defun iseq-helper (a b)
+ (let ((mylist '()))
+ (dotimes (i (1+ (- b a)) (reverse mylist))
+ (setf mylist (cons (+ a i) mylist)))))
+
+
+(defun iseq (a b)
+ (if (> a b) (reverse (iseq-helper b a))
+ (iseq-helper a b)))
+
+
+(defun floor (x)
+ (if (< x 0)
+ (1- (truncate x))
+ (truncate x)))
+
+(defun realrem (x mod)
+ (- (float x) (* (floor (/ (float x) (float mod))) (float mod))))
+
+
+(defun sheptone-sweep-helper (pitch-1 centerpitch-1
+ duration
+ pitch-2 centerpitch-2
+ overtonesemi overtones
+ &optional (wavetable *sine-table*))
+ (let ((mytone (const 0 duration))
+ (maxovertones (+ (floor (/ (float (max (abs (- pitch-1 centerpitch-2))
+ (abs (- pitch-1 centerpitch-2))))
+ overtonesemi))
+ overtones 2))
+ (ampshaper (envshaper))
+ )
+ (dolist (i (iseq (- maxovertones) maxovertones) mytone)
+ (progn
+ (setf startpitch (+ pitch-1 (* i overtonesemi)))
+ (setf endpitch (+ pitch-2 (* i overtonesemi)))
+ (setf f (pwe 0 (step-to-hz startpitch)
+ duration (step-to-hz endpitch)))
+ (setf p (pwl 0 startpitch duration endpitch))
+ (setf c (pwl 0 centerpitch-1 duration centerpitch-2))
+ (setf normwidthfactor (/ 1.0 (* overtones overtonesemi)))
+ (setf a (shape (mult (diff p c) normwidthfactor)
+ ampshaper 1))
+ (setf voice (mult a (hzosc f wavetable)))
+ (setf mytone (sum mytone voice))
+ )
+ )))
+
+
+
+(defun sheptone-sweep (pitch-1 centerpitch-1 duration pitch-2 centerpitch-2
+ overtonesemi overtones
+ &optional (wavetable *sine-table*))
+ (normalize
+ (mult (sheptone-sweep-helper pitch-1 centerpitch-1
+ duration
+ pitch-2 centerpitch-2
+ overtonesemi overtones wavetable)
+ (env 0.05 0 0.05 1 1 1 duration)))
+ )
+
+
+(setf result (buffer (sheptone-sweep pitch1 cpitch1
+ duration pitch2 cpitch2 overtonesemi overtones) 0.1 duration 0.2))
+
+result
diff --git a/demos/softclip.gif b/demos/softclip.gif
new file mode 100644
index 0000000..3881970
--- /dev/null
+++ b/demos/softclip.gif
Binary files differ
diff --git a/demos/softclip.jpg b/demos/softclip.jpg
new file mode 100644
index 0000000..9d8bf53
--- /dev/null
+++ b/demos/softclip.jpg
Binary files differ
diff --git a/demos/stktest.lsp b/demos/stktest.lsp
new file mode 100644
index 0000000..c83d296
--- /dev/null
+++ b/demos/stktest.lsp
@@ -0,0 +1,407 @@
+;; stktest.lsp -- test the STK instruments
+
+(autonorm-on)
+
+(print "Type (makedemo number) with number ranging from 1 to 17")
+(print "Type (all-stk-demos) to hear them all")
+
+(defun makedemo (n)
+ (case n
+ (1 (progn (nrev-demo)(print "NRev Demo")))
+ (2 (progn (jcrev-demo)(print "JCRev Demo")))
+ (3 (progn (prcrev-demo)(print "PRCRev Demo")))
+ (4 (progn (stkchorus-demo)(print "Chorus Demo")))
+ (5 (progn (pitshift-demo) (print "Pitch Shift Demo")))
+ (6 (progn (flute-demo)(print "Flute Demo")))
+ (7 (progn (flute-freq-demo)(print "Flute Freq Demo")))
+ (8 (progn (flute-all-demo)(print "Flute All Demo")))
+ (9 (progn (bowed-demo 0.4)(print "Bowed Instrument Demo")))
+ (10 (progn (bowed-freq-demo)(print "Bowed Freq Instrument Demo")))
+ (11 (progn (mandolin-demo)(print "Mandolin Demo")))
+ (12 (progn (wg-uniform-bar-demo) (print "Uniform Bar Wave Guide Demo")))
+ (13 (progn (wg-tuned-bar-demo)(print "Tuned Bar Wave Guide Demo")))
+ (14 (progn (wg-glass-harm-demo)(print "Glass Harmonica Wave Guide Demo")))
+ (15 (progn (wg-tibetan-bowl-demo)(print "Tibetan Bowl Prayer Wave Guide Demo")))
+ (16 (progn (modalbar-demo)(print "Modal Bar Demo")))
+ (17 (progn (sitar-demo) (print "Sitar Demo")))
+ (18 (progn (clarinet-example-1) (print "Clarinet Demo 1")))
+ (19 (progn (clarinet-example-2) (print "Clarinet Demo 2")))
+ (20 (progn (clarinet-example-3) (print "Clarinet Demo 3")))
+ (21 (progn (clarinet-example-4) (print "Clarinet Demo 4")))
+ (22 (progn (clarinet-example-5) (print "Clarinet Demo 5")))
+ (23 (progn (sax-example-1) (print "Sax Demo 1")))
+ (24 (progn (sax-example-2) (print "Sax Demo 2")))
+ (t (error "number ranges from 1 to 24"))))
+
+
+(defun all-stk-demos ()
+ (dotimes (i 24) (makedemo (1+ i))))
+
+
+
+;;; ********************************
+;;;
+;;; EFFECTS DEMOS
+;;;
+;;; ********************************
+
+
+; design of a tubular-bell-like sound
+
+(setf *pi-over-2* (/ 3.141592 2))
+
+(defun pan-fun-l (x)
+ (* (/ (sqrt 2.0)) (- (cos (* x *pi-over-2*)) (sin (* x *pi-over-2*)))))
+
+(defun pan-fun-r (x)
+ (* (/ (sqrt 2.0)) (+ (cos (* x *pi-over-2*)) (sin (* x *pi-over-2*)))))
+
+(defun pan-snd (snd pan)
+ (vector (scale (pan-fun-l pan) snd)
+ (scale (pan-fun-r pan) snd)))
+
+
+(defun tub-partial (scale-factor freq-factor time-factor pitch dur)
+ (scale scale-factor (mult (sim -1.0 (pwev 10 (* dur time-factor) 1))
+ (osc (hz-to-step (* freq-factor (step-to-hz pitch)))
+ (* dur time-factor)))))
+
+(defun tubular (pitch dur)
+ (let ((hz (step-to-hz pitch)))
+ (sim (tub-partial 0.1 1.0 1.0 pitch dur)
+ (tub-partial 0.06 2.76 0.8 pitch dur)
+ (tub-partial 0.04 5.4 0.7 pitch dur)
+ (tub-partial 0.03 8.93 0.4 pitch dur)
+ (tub-partial 0.02 13.34 0.2 pitch dur)
+ (tub-partial 0.01 18.64 0.1 pitch dur)
+ (tub-partial 0.005 31.87 0.05 pitch dur))))
+
+(defun ktubular (&key pitch idur pan dyn)
+ (pan-snd (scale dyn (tubular pitch idur)) pan))
+
+; (if rev (nrev snd 4 0.25)
+; snd)))
+
+; algorithmic score by means of Xmusic
+
+(setf pitches1 (make-cycle (list c5 g4 e4 c4) :for 8))
+(setf pitches2 (make-cycle (list c5 a4 f4 d4) :for 8))
+(setf *pitches* (make-cycle (list pitches1 pitches2) :for 6))
+
+(setf *ioi* (make-cycle (list 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.6)))
+(setf *pan* (make-cycle (list 0 -0.2 0.2 -0.4 0.4 -0.45 0.45 -0.1 0.1 -0.25 0.25 -0.3 0.3)))
+(setf *dyn* (make-cycle (list 1 1 1 1 1 1 1 1.2 2 2 1 2 1 2 1 2 )))
+
+(setf my-score (score-gen :name 'ktubular :dur 1 :idur 2
+ :ioi 0.2
+ :pitch (next *pitches*)
+ :dyn (next *dyn*)
+ :pan (next *pan*)
+ :score-len 16))
+
+
+(defun nrev-demo ()
+ (play (seq (timed-seq my-score)
+ (nrev (timed-seq my-score) 4.0 0.25))))
+
+;(nrev-demo)
+
+(defun jcrev-demo ()
+ (play (seq (timed-seq my-score)
+ (jcrev (timed-seq my-score) 4.0 0.25))))
+
+;(jcrev-demo)
+
+(defun prcrev-demo ()
+ (play (seq (timed-seq my-score)
+ (prcrev (timed-seq my-score) 4.0 0.25))))
+
+;(prcrev-demo)
+
+
+(defun stkchorus-demo ()
+ (play (seq (timed-seq my-score)
+ (stkchorus (timed-seq my-score) 0.1 0.2 0.5))))
+
+;(stkchorus-demo)
+
+(defun pitshift-demo ()
+ (play (seq (timed-seq my-score)
+ (pitshift (timed-seq my-score) 2.0 0.9)
+ (pitshift (timed-seq my-score) 0.4 0.7)
+ (pitshift (timed-seq my-score) 6.0 0.7))))
+
+;(pitshift-demo)
+
+
+; *******************************************
+;
+; INSTRUMENTS DEMOS
+;
+; *******************************************
+
+
+(defun env1 (d)
+ (pwl 0.1 0.7 (- d 0.3) 0.5 d))
+
+(defun flute-demo ()
+ (play
+ (seq (flute e5 (env1 1))
+ (flute c5 (env1 1))
+ (flute g4 (env1 2)))))
+
+;(flute-demo)
+
+(defun env2 (ampl d)
+ (scale ampl (mult (pwlv 0.0 1.0 0.0 d 1.0) (lfo 5 d))))
+(defun flute-freq-demo ()
+ (play (flute-freq c5 (env1 6) (env2 8 6))))
+
+;(flute-freq-demo)
+
+(defun env3 (d)
+ (pwl (* d 0.5) 20 d))
+(defun flute-all-demo ()
+ (play (flute-all c5 (env1 6) (env3 6) 6 0.2 0.5 0.06)))
+
+;(flute-all-demo)
+
+(defun bow-env (d)
+ (pwl 0.05 0.5 (- d 0.1) 0.3 d))
+
+(defun bowed-demo (d)
+ (play (seq (bowed g4 (bow-env d))
+ (bowed d5 (bow-env d))
+ (bowed b5 (bow-env d))
+ (bowed a5 (bow-env d))
+ (bowed b5 (bow-env d))
+ (bowed d5 (bow-env d))
+ (bowed b5 (bow-env d))
+ (bowed d5 (bow-env d))
+ (bowed g4 (bow-env d)))))
+
+;(bowed-demo 0.4)
+
+(defun bowed-freq-demo ()
+ (play (bowed-freq c3 (bow-env 10) (env2 5 10))))
+
+;(bowed-freq-demo)
+
+(defun mandolin-demo ()
+ (play (seq (mandolin c4 1.0)
+ (mandolin c4 1.0 2.0)
+ (mandolin c4 1.0 3.0)
+ (mandolin c4 1.0 4.0)
+ (mandolin c4 1.0 5.0)
+ (mandolin c4 1.0 6.0)
+ (mandolin c4 1.0 7.0)
+ (mandolin c4 1.0 8.0)
+ (mandolin c4 1.0 9.0)
+ (mandolin c4 1.0 10.0)
+ (mandolin c4 1.0 11.0)
+ (mandolin c4 1.0 12.0)
+ (mandolin c4 1.0 13.0)
+ (mandolin c4 1.0 14.0)
+ (mandolin c4 1.0 15.0)
+ (mandolin c4 1.0 16.0)
+ (mandolin c4 1.0 17.0)
+ (mandolin c4 1.0 18.0)
+ (mandolin c4 1.0 19.0)
+ (mandolin c4 1.0 20.0)
+ (mandolin c4 1.0 25.0)
+ (mandolin c4 1.0 30.0)
+ (mandolin c4 1.0 35.0)
+ (mandolin c4 1.0 40.0)
+ (mandolin c4 1.0 45.0)
+ (mandolin c4 1.0 50.0)
+ (mandolin c4 1.0 55.0)
+ (mandolin c4 1.0 60.0)
+ (mandolin c4 1.0 65.0))))
+
+;(mandolin-demo)
+
+(defun wg-env (d)
+ (pwlv 1 d 1))
+
+(defun wg-uniform-bar-demo ()
+ (play (seq (wg-uniform-bar c4 (wg-env 0.2))
+ (wg-uniform-bar g3 (wg-env 0.2))
+ (wg-uniform-bar c4 (wg-env 0.2))
+ (wg-uniform-bar e4 (wg-env 0.2))
+ (wg-uniform-bar g4 (wg-env 2.2)))))
+
+;(wg-uniform-bar-demo)
+
+(defun wg-tuned-bar-demo ()
+ (play (seq (wg-tuned-bar c4 (wg-env 0.2))
+ (wg-tuned-bar g3 (wg-env 0.2))
+ (wg-tuned-bar c4 (wg-env 0.2))
+ (wg-tuned-bar e4 (wg-env 0.2))
+ (wg-tuned-bar g4 (wg-env 0.2)))))
+
+;(wg-tuned-bar-demo)
+
+(defun wg-glass-harm-demo ()
+ (play (seq (wg-glass-harm c4 (wg-env 0.2))
+ (wg-glass-harm g3 (wg-env 0.2))
+ (wg-glass-harm c4 (wg-env 0.2))
+ (wg-glass-harm e4 (wg-env 0.2))
+ (wg-glass-harm g4 (wg-env 1.2)))))
+
+;(wg-glass-harm-demo)
+
+(defun wg-tibetan-bowl-demo ()
+ (play (seq (wg-tibetan-bowl c4 (wg-env 0.2))
+ (wg-tibetan-bowl ef4 (wg-env 0.2))
+ (wg-tibetan-bowl fs4 (wg-env 0.2))
+ (wg-tibetan-bowl a4 (wg-env 2.0)))))
+
+;(wg-tibetan-bowl-demo)
+
+(defun modalbar-demo-1 (prst)
+ (seq (modalbar prst c4 0.2)
+ (modalbar prst g3 0.2)
+ (modalbar prst c4 0.2)
+ (modalbar prst e4 0.2)
+ (modalbar prst g4 1.0)))
+
+(defun modalbar-demo ()
+ (play (seq (modalbar-demo-1 'MARIMBA)
+ (modalbar-demo-1 'VIBRAPHONE)
+ (modalbar-demo-1 'AGOGO)
+ (modalbar-demo-1 'WOOD1)
+ (modalbar-demo-1 'RESO)
+ (modalbar-demo-1 'WOOD2)
+ (modalbar-demo-1 'BEATS)
+ (modalbar-demo-1 'TWO-FIXED)
+ (modalbar-demo-1 'CLUMP))))
+
+;(modalbar-demo)
+
+(defun sitar-demo ()
+ (play (seq (sitar c3 0.6)
+ (sitar g3 1.2)
+ (sitar fs3 0.4)
+ (sitar g3 0.4)
+ (sitar af3 0.6)
+ (sitar ef3 2.0))))
+
+;(sitar-demo)
+
+
+;; simple clarinet sound
+(defun clarinet-example-1 ()
+ (play (clarinet bf3 (stk-breath-env 1 0.2 0.1))))
+
+;; clarinet sound with frequency sweep (glissando)
+(defun clarinet-example-2 ()
+ (play (clarinet-freq bf3 (stk-breath-env 3 0.2 0.1) (pwl 1.5 80 3 80 3))))
+
+;; clarinet sound with change in breath pressure
+(defun clarinet-example-3 ()
+ (play (clarinet bf3 (prod (pwl 0 1 1.5 0.9 3 1 3) (stk-breath-env 3 0.2 0.1)))))
+
+;; clarinet sound using initial frequency sweep and built-in vibrato effect
+(defun clarinet-example-4 ()
+ (play (clarinet-all bf3 (stk-breath-env 3 0.5 0.05) (pwl 0.3 80 3 80 3) 5.7 0.5 0 0)))
+
+;; clarinet sound with increasing then decreasing reed stiffness
+(defun clarinet-example-5 ()
+ (play (clarinet-all bf3 (stk-breath-env 3 0.5 0.05) 0 0 0 (pwl 1.5 0.75 3) 0)))
+
+;; clarinet sound with increasing noise, with vibrato
+(defun clarinet-example-6 ()
+ (play (clarinet-all bf3 (stk-breath-env 3 0.5 0.05) 0 5.7 0.5 0 (pwl 3 1 3))))
+
+;(print "clarinet-example-1")
+;(clarinet-example-1)
+;(print "clarinet-example-2")
+;(clarinet-example-2)
+;(print "clarinet-example-3")
+;(clarinet-example-3)
+;(print "clarinet-example-4")
+;(clarinet-example-4)
+;(print "clarinet-example-5")
+;(clarinet-example-5)
+;(print "clarinet-example-6")
+;(clarinet-example-6)
+
+
+(defun sax-example-1 ()
+ (scale 0.5
+ (timed-seq '(
+ (0.0 1 (sax g3 (stk-breath-env 2 0.2 0.2)))
+ (2.0 1 (sax-freq c4 (stk-breath-env 4 0.6 0.6)
+ (scale 100 (mult (pwl 0 0.95 4 1.3 4)))))
+ )))
+)
+
+(defun sax-example-2 ()
+ (scale 0.5
+ (timed-seq
+ '(
+ (0.0 1 (sax-freq
+ bf3
+ (eight-sixteenths-env)
+ (freqenv 1 bf3 (list 0 bf3 0.125 af4 0.25 g4 0.375 d4
+ 0.5 f4 0.625 ef4 0.75 d4 0.875 ef4))))
+ (1.0 1 (sax-freq
+ e4
+ (eight-sixteenths-env)
+ (freqenv 1 e4 (list 0 e4 0.125 c4 0.25 a3 0.375 e3
+ 0.5 fs3 0.625 e3 0.75 fs3 0.875 e4))))
+ (2.0 1 (sax-freq
+ d4
+ (eight-sixteenths-env)
+ (freqenv 1 d4 (list 0 d4 0.125 c4 0.25 b3 0.375 a3
+ 0.5 g3 0.625 a3 0.75 b3 0.875 d4))))
+ (3.0 1 (sax-freq
+ ef4
+ (eight-sixteenths-env)
+ (freqenv 1 ef4 (list 0 ef4 0.125 cs4 0.25 b3 0.375 bf3
+ 0.625 gf3 0.75 af3 0.875 bf4))))))))
+
+(defun eight-sixteenths-env ()
+ (mult (envbreaks 1 (list 0.125 0.25 0.375 0.5 0.625 0.75 0.875))
+ (stk-breath-env 1 1 1)))
+
+(defun hzdiff (step1 step2)
+ (- (step-to-hz step2) (step-to-hz step1)))
+
+;; create a piecewise-constant (stairstep) function to control frequencies
+;; timesteplist is (time0 step0 time1 step1 etc.)
+;;
+(defun freqenv (dur step timesteplist)
+ (let ((finalenv nil) hzdiff (tslist timesteplist) currt currs)
+ (do () ((null tslist))
+ (setf currt (car tslist))
+ (setf currs (cadr tslist))
+ (setf tslist (cdr (cdr tslist)))
+
+ (setf finalenv (append finalenv
+ (list currt
+ (hzdiff step currs)
+ (if (null tslist) dur (car tslist))
+ (hzdiff step currs))
+ )))
+ (setf finalenv (append finalenv (list dur)))
+ (pwl-list finalenv)))
+
+;; create a breath envelope where pressure goes to zero at designated points
+;; dur is overall duration
+;; breaklist is places where pressure dips to zero during a 20ms window
+;;
+(defun envbreaks (dur breaklist)
+ (let ((finalenv nil))
+ (dolist (breakpt breaklist)
+ (setf finalenv (append finalenv (list (- breakpt 0.01) 1
+ (- breakpt 0.001) 0
+ breakpt 1))))
+ (setf finalenv (append (list 0 1) finalenv (list dur)))
+ (pwl-list finalenv)))
+
+;(print "sax-example-1")
+;(play (sax-example-1))
+;(print "sax-example-2")
+;(play (sax-example-2))
+
diff --git a/demos/voice_synthesis.htm b/demos/voice_synthesis.htm
new file mode 100644
index 0000000..4f9b922
--- /dev/null
+++ b/demos/voice_synthesis.htm
@@ -0,0 +1,290 @@
+<html>
+
+<head>
+<title>Voice Synthesis Tutorial</title>
+</head>
+
+<body>
+
+<h1>Voice Synthesis Tutorial</h1>
+
+<p>Nyquist voice synthesis instrument by Eduardo Reck Miranda.</p>
+
+<pre>;---------------------------------------------------------------------------
+; Nyquist voice synthesis instrument by Eduardo Reck Miranda
+;
+; Implements a geometrical articulator for tongue position (h p) and
+; lips rouding (r)
+;
+;---------------------------------------------------------------------------
+; Geometrical articulator: the following FORMx functions estimates the formant
+; values from the positions of the three articulators p h and r, where:
+; p = horizontal position of the tongue: 0.0 = front and 1.0 = back
+; h = vertical position of the tongue: 0.0 = low and 1.0 = high
+; r = rounding of the lips: 0.0 = spread -> 1.0 rounded
+;---------------------------------------------------------------------------
+; FORM1: converts p-h-r articulators to first formant frequency
+;---------------------------------------------------------------------------
+(defmacro form1 (p h r)
+ `(+ (* (+ (* (+ (- 392) (* 392 ,r)) (expt ,h 2))
+ (* (- 596 (* 668 ,r)) ,h)
+ (+ (- 146) (* 166 ,r)))
+ (expt ,p 2))
+
+ (* (+ (* (- 348 (* 348 ,r)) (expt ,h 2))
+ (* (+ (- 494) (* 606 ,r)) ,h)
+ (- 141 (* 175 ,r)))
+ ,p)
+
+ (+ (* (- 340 (* 72 ,r)) (expt ,h 2))
+ (* (+ (- 796) (* 108 ,r)) ,h)
+ (- 708 (* 38 ,r)))
+ ))
+
+;---------------------------------------------------------------------------
+; FORM2: converts p-h-r articulators to second formant frequency
+;---------------------------------------------------------------------------
+(defmacro form2 (p h r)
+ `(+ (* (+ (* (+ (- 1200) (* 1208 ,r)) (expt ,h 2))
+ (* (- 1320 (* 1328 ,r)) ,h)
+ (- 118 (* 158 ,r)))
+ (expt ,p 2))
+
+ (* (+ (* (- 1864 (* 1488 ,r)) (expt ,h 2))
+ (* (+ (- 2644) (* 1510 ,r)) ,h)
+ (+ (- 561) (* 221 ,r)))
+ ,p)
+
+ (+ (* (+ (- 670) (* 490 ,r)) (expt ,h 2))
+ (* (- 1355 (* 697 ,r)) ,h)
+ (- 1517 (* 117 ,r)))
+ ))
+
+;---------------------------------------------------------------------------
+; FORM3: converts p-h-r articulators to third formant frequency
+;---------------------------------------------------------------------------
+(defmacro form3 (p h r)
+ `(+ (* (+ (* (- 604 (* 604 ,r)) (expt ,h 2))
+ (* (- 1038 (* 1178 ,r)) ,h)
+ (+ 246 (* 566 ,r)))
+ (expt ,p 2))
+
+ (* (+ (* (+ (- 1150) (* 1262 ,r)) (expt ,h 2))
+ (* (+ (- 1443) (* 1313 ,r)) ,h)
+ (- (- 317) (* 483 ,r)))
+ ,p)
+
+ (+ (* (- 1130 (* 836 ,r)) (expt ,h 2))
+ (* (+ (- 315) (* 44 ,r)) ,h)
+ (- 2427 (* 127 ,r)))
+ ))
+
+
+;---------------------------------------------------------------------------
+; FORM4: converts p-h-r articulators to fourth formant frequency
+;---------------------------------------------------------------------------
+(defmacro form4 (p h r)
+ `(+ (* (+ (* (+ (- 1120) (* 16 ,r)) (expt ,h 2))
+ (* (- 1696 (* 180 ,r)) ,h)
+ (+ 500 (* 522 ,r)))
+ (expt ,p 2))
+
+ (* (+ (* (+ (- 140) (* 240 ,r)) (expt ,h 2))
+ (* (+ (- 578) (* 214 ,r)) ,h)
+ (- (- 692) (* 419 ,r)))
+ ,p)
+
+ (+ (* (- 1480 (* 602 ,r)) (expt ,h 2))
+ (* (+ (- 1220) (* 289 ,r)) ,h)
+ (- 3678 (* 178 ,r)))
+ ))
+
+;---------------------------------------------------------------------------
+; ADSR-SMOOTH: a standard ADSR envelope
+;---------------------------------------------------------------------------
+(defun adsr-smooth (signal dur)
+ (mult signal (env 0.1 0.2 0.5 1.0 0.8 0.4 dur)))
+;---------------------------------------------------------------------------
+; VIBRATO: generates vibrato
+; vib-rate = vibrato rate in Hz
+; dur = duration in seconds
+;---------------------------------------------------------------------------
+(defun vibrato (vib-rate dur)
+ (osc (hz-to-step vib-rate) dur))
+
+;---------------------------------------------------------------------------
+; PULSE-TABLE: build table for generating a pulse signal
+; harm = number of harmonics
+;---------------------------------------------------------------------------
+(defun pulse-table (harm)
+ (abs-env ;prevent any timewarping in the following
+ (let ((table (build-harmonic 1 2048)))
+ (cond ((> harm 1) ;sum remaining harmonics
+ (setf harm (- harm 1))
+ (dotimes (i harm)
+ (setf table (sum table (build-harmonic (1+ i) 2048))))))
+ table)))
+
+;---------------------------------------------------------------------------
+; PULSE-WITH-VIBRATO: generate pulse with vibrato
+; step = pitch in steps
+; duration = duration in seconds
+; vib-rate = vibrato rate in Hz
+;---------------------------------------------------------------------------
+(defun pulse-with-vibrato (step duration vib-rate)
+ (let (harm freq)
+ (setf freq (step-to-hz step))
+ (setf harm (truncate (/ 22050 (* 2 freq))))
+ (setf table (scale (/ 1.0 harm) (pulse-table harm)))
+ (fmosc step (vibrato vib-rate duration) (list table (hz-to-step 1) t))))
+
+;---------------------------------------------------------------------------
+; VOICING-SOURCE: generate voicing source: pulse with vibrato + LPFs
+; step = pitch in steps
+; duration = duration in seconds
+; vib-rate = vibrato rate in Hz
+;---------------------------------------------------------------------------
+(defun voicing-source (step duration vib-rate)
+ (lp
+ (lp
+ (pulse-with-vibrato step duration vib-rate)
+ (* 1.414 (* 2 (step-to-hz step))))
+ (* 1.414 (* 4 (step-to-hz step)))))
+
+;---------------------------------------------------------------------------
+; NOISE-SOURCE: generate noise source: noise + offset oscillator + LPF
+; step = pitch in steps
+; duration = duration in seconds
+; vib-rate = vibrato rate in Hz
+;---------------------------------------------------------------------------
+(defun noise-source (step duration vib-rate)
+ (lp
+ (sum
+ (noise duration)
+ (fmosc step (vibrato vib-rate duration))) 8000))
+
+;---------------------------------------------------------------------------
+; SOURCE: generate source signal: voicing + noise sources
+; freq = fundamental frequency in Hz
+; duration = duration in seconds
+; vib-rate = vibrato rate in Hz
+; voicing-scale = percentage of voicing in the resulting signal (0.0 -> 1.0)
+; noise-scale = percentage of noise in the resulting signal (0.0 -> 1.0)
+;---------------------------------------------------------------------------
+(defun source (freq duration vib-rate voicing-scale noise-scale)
+ (sum
+ (scale voicing-scale (voicing-source (hz-to-step freq) duration vib-rate))
+ (scale noise-scale (noise-source (hz-to-step freq) duration vib-rate))))
+
+
+;---------------------------------------------------------------------------
+; MAKE-SPECTRUM: formant filters
+; freq = fundamental frequency in Hz
+; dur = duration in seconds
+; vib-rate = vibrato rate in Hz
+; v-scale = amplitude scaling for the voicing source
+; n-scale = amplitude scaling for the noise source
+; p = horizontal position of the tongue (0.0 = front -> 1.0 = back)
+; h = vertical position of the tongue (0.0 = low -> 1.0 = high)
+; r = rouding of the lips (0.0 = spread -> 1.0 = rounded)
+;---------------------------------------------------------------------------
+(defun make-spectrum (freq dur vib-rate v-scale n-scale p h r)
+ (let ((src (source freq dur vib-rate v-scale n-scale)))
+ (setf spectrum
+ (sim
+ (reson src (form1 p h r) 50 1)
+ (reson (scale-db (- 10) src) (form2 p h r) 70 1)
+ (reson (scale-db (- 14) src) (form3 p h r) 110 1)
+ (reson (scale-db (- 20) src) (form4 p h r) 250 1)))))
+
+;---------------------------------------------------------------------------
+; SYNTHESISE: the synthesise function
+; Simplified version of the instrument used by the agents discussed in Chapter 6.
+; f0 = pitch frequency
+; w1 = amplitude of voicing source (min = 0.0 max = 1.0)
+; w2 = amplitude of noise source (min = 0.0 max = 1.0)
+; a = horizontal position of the tongue (0.0 = front -> 1.0 = back)
+; b = vertical position of the tongue (0.0 = low -> 1.0 = high)
+; c = rouding of the lips (0.0 = spread -> 1.0 = rounded)
+; fm = vibrato rate (in Hz)
+; h = duration in seconds
+;---------------------------------------------------------------------------
+(defun synthesise (f0 w1 w2 a b c fm h)
+ (adsr-smooth (make-spectrum f0 h fm w1 w2 a b c) h))
+
+;=== The code for the instrument ends here ===
+
+;---------------------------------------------------------------------------
+; Test the SYNTHESISE function with different positions of the articulators
+;
+; Running steps:
+; 1 - run Nyquist
+; 2 - load "articulator.lsp"
+; 3 - type (play (vowel-1)) to synthesise the first test, and so on
+;---------------------------------------------------------------------------
+(defun vowel-1 ()
+ (synthesise 220 1.0 0.005 0.0 0.0 0.0 5.6 1.0))
+
+(defun vowel-2 ()
+ (synthesise 220 1.0 0.005 0.0 0.0 1.0 5.6 1.0))
+
+(defun vowel-3 ()
+ (synthesise 220 1.0 0.005 0.5 0.0 0.0 5.6 1.0))
+
+(defun vowel-4 ()
+ (synthesise 220 1.0 0.005 0.5 0.0 1.0 5.6 1.0))
+
+(defun vowel-5 ()
+ (synthesise 220 1.0 0.005 1.0 0.0 0.0 5.6 1.0))
+
+(defun vowel-6 ()
+ (synthesise 220 1.0 0.005 1.0 0.0 1.0 5.6 1.0))
+
+(defun vowel-7 ()
+ (synthesise 220 1.0 0.005 0.0 0.5 0.0 5.6 1.0))
+
+(defun vowel-8 ()
+ (synthesise 220 1.0 0.005 0.0 0.5 1.0 5.6 1.0))
+
+(defun vowel-9 ()
+ (synthesise 220 1.0 0.005 0.5 0.5 0.0 5.6 1.0))
+
+(defun vowel-10 ()
+ (synthesise 220 1.0 0.005 0.5 0.5 1.0 5.6 1.0))
+
+(defun vowel-11 ()
+ (synthesise 220 1.0 0.005 1.0 0.5 0.0 5.6 1.0))
+
+(defun vowel-12 ()
+ (synthesise 220 1.0 0.005 1.0 0.5 1.0 5.6 1.0))
+
+(defun vowel-13 ()
+ (synthesise 220 1.0 0.005 0.0 1.0 0.0 5.6 1.0))
+
+(defun vowel-14 ()
+ (synthesise 220 1.0 0.005 0.0 1.0 1.0 5.6 1.0))
+
+(defun vowel-15 ()
+ (synthesise 220 1.0 0.005 0.5 1.0 0.0 5.6 1.0))
+
+(defun vowel-16 ()
+ (synthesise 220 1.0 0.005 0.5 1.0 1.0 5.6 1.0))
+
+(defun vowel-17 ()
+ (synthesise 220 1.0 0.005 1.0 1.0 0.0 5.6 1.0))
+
+(defun vowel-18 ()
+ (synthesise 220 1.0 0.005 1.0 1.0 1.0 5.6 1.0))
+
+;; play everything
+(defun vowel-n (n) (funcall (intern (format nil "VOWEL-~A" n))))
+
+(defun play-all-vowels ()
+ (autonorm-off)
+ (dotimes (i 18) (play (scale 20 (vowel-n (1+ i)))))
+ (autonorm-on))
+
+; (play-all-vowels) will play everything in sequence
+</pre>
+</body>
+</html>
diff --git a/demos/warble_tutorial.htm b/demos/warble_tutorial.htm
new file mode 100644
index 0000000..15b08f8
--- /dev/null
+++ b/demos/warble_tutorial.htm
@@ -0,0 +1,76 @@
+<html>
+
+
+<head>
+<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
+<title>Warble Tutorial</title>
+</head>
+
+<body>
+
+<h1>Warble Tutorial</h1>
+
+<p>The warble function by Alex illustrates the use of AM and FM oscillators to create an
+&quot;analog&quot; electronic synthesizer sound.</p>
+
+<pre>(defun warble (&amp;optional (dur 1) (pch 60))
+ (stretch dur
+ (sum (mult
+ (env 0.017 0.1 0.004 1 0.7 0.8 1)
+ (amosc pch (fmosc (hz-to-step 8)
+ (pwl 0 4 0.2 -4 0.56 9 0.7 0 1 -8 1))))
+ (mult (stretch 0.96 (env 0.2 0.09 0.07 0.92 0.8 0.6 1))
+ (amosc pch (fmosc (* pch 1.414)
+ (pwl 0.2 80 0.5 4 0.9 1120 1 200 1)))))))</pre>
+
+<p>This sound is the sum of two components. To find the two components, look for <code>(mult
+...)</code>. Each of these components is the product of an envelope and an AM oscillator.
+The first one modulates the AM oscillator with a low frequency (about 8 Hz) sinusoid
+produced by an FM oscillator. The modulator varies in frequency according to a piece-wise
+linear envelope.</p>
+
+<p>The second component is similar, but uses a much higher modulating frequency in the
+audio range, producing a ring-modulation effect. Another piece-wise linear envelope sweeps
+the modulator frequency by as much as 1120 Hz.</p>
+
+<h2>Thicker Texture</h2>
+
+<p>A thicker texture can be obtained by playing copies of warble together with slight
+parameter changes. Here is an example:</p>
+
+<pre>(defun thicker ()
+ (sim (scale 0.5 (at 0.00 (warble 8 48)))
+ (scale 0.3 (at 0.05 (warble 8.05 47.9)))))</pre>
+
+<h2><br>
+Another FM Sound</h2>
+
+<p>The following produces another analog-sounding FM texture:</p>
+
+<pre>(defun mod (dur)
+ (stretch dur
+ (mult (pwl 0 1000 .2 200 .5 8000 1 100 1)
+ (fmosc c4 (pwl 0 1 .5 3.25 1 .74 1)))))
+
+(defun blurp (dur)
+ (fmosc c3 (mult (osc 07 dur) (mod dur))))</pre>
+
+<p>This example relies on a combination of AM and FM: the output is from an FM oscillator,
+but its modulator is formed by multiplying (AM) two oscillators. The first is low
+frequency (about 12 Hz), giving a warbling sound, and the second, generated by <code>(mod
+dur)</code>, is another FM oscillator. It appears that the modulation generated by the
+piece-wise linear function is almost insignificant. You might try scaling the expression
+(pwl 0 1 .5 3.25 1 .74 1) in <code>mod</code> by varying amounts to see what happens.</p>
+
+<p>The original duration of <code>blurp</code> was 3.1 (seconds), but longer versions are
+interesting and reveal more detail.</p>
+
+<h2>Yet Another Sound</h2>
+
+<p>See <a href="scratch_tutorial.htm#ring">Other Sounds Using Ring in Vinal Scratch
+Tutorial</a> for another example.</p>
+
+<pre>
+</pre>
+/body>
+</html>
diff --git a/demos/wind_tutorial.htm b/demos/wind_tutorial.htm
new file mode 100644
index 0000000..531724f
--- /dev/null
+++ b/demos/wind_tutorial.htm
@@ -0,0 +1,43 @@
+<html>
+<head>
+<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
+<title>Wind Tutorial</title>
+</head>
+
+<body>
+
+<h1>Wind Tutorial</h1>
+
+<p>This page describes a &quot;wind&quot; effect created by Alex. The basic function is as
+follows:</p>
+
+<pre>(defun wind (&amp;optional (dur 3) (scal 3) (cps 590) (bw 40))
+ (stretch dur
+ (mult (env 0.07 0.08 0.1 1 0.6 0.8 1)
+ (sum
+ (reson (scale scal (noise)) cps bw 2)
+ (reson (scale (mult scal 1.13) (noise))
+ (mult cps (pwl 0 0.74 0.2 0.96 0.5 0.8 0.75 1.16 0.9 0.97 1 0.74 1))
+ (mult bw 1.042)
+ 2)))))</pre>
+
+<p>The basic idea is to use bandpassed noise to create the sound of wind. In this example,
+two bandpass filters are added together. The first uses a fixed center frequency and
+bandwidth, and the second uses a piece-wise linear function to control the center
+frequency. The entire sound is multiplied by an envelope and stretched to the desired
+duration. Note how several optional parameters can be used to change the default behavior.</p>
+
+<p>A slight elaboration of the wind function uses several copies of wind in sequence with
+slight overlap:</p>
+
+<pre>(defun multiwind ()
+ (simrep (i 4) (at (* i 2.9) (wind))))</pre>
+
+<p>One problem with this approach is that the wind sound becomes periodic. This could be
+solved by using noise or random numbers to generate the center frequency variation rather
+than a fixed envelope.</p>
+
+<p>&nbsp;</p>
+</body>
+</html>
+