With Nyquist, you can design instruments by combining functions (much as you would using the orchestra languages of Music V, cmusic, or Csound). You can call upon these instruments and generate a sound just by typing a simple expression. You can combine simple expressions into complex ones to create a whole composition.
Nyquist runs under any Unix environment, MacOS, Windows 95, and Windows NT, and it produces sound files as output (or direct audio output under Windows). Under Unix, if you can play a sound file by typing a command to a Unix shell, then you can get Nyquist to play sounds for you. Nyquist is currently configured to run on an IBM RS6000 with an ACPA audio board, or a NeXT machine, using the built-in sound system to play Nyquist output. Recent versions have also run on SGI, DEC pmax, Linux, and Sun Sparc machines, and makefiles for these are included. Let me know if you have problems with any of these machines.
To use Nyquist, you should have a basic knowledge of Lisp. An excellent text by Touretzky is recommended (Touretzky 1984). Appendix "XLISP: An Object-oriented Lisp" is the reference manual for XLISP, of which Nyquist is a superset.
Installation
Nyquist is a C program intended to run under various operating systems including Unix, MacOS, and Windows.
Unix Installation
For Unix systems, Nyquist is distributed as a compressed tar file named nyquist2nn.zip
,
where nn is the version number (e.g. v2.19 was nyquist219.zip
). To
install Nyquist, copy nyquist2nn.zip
to a fresh directory on your machine
and type:
gunzip nyquist2nn.zip ln -s sys/unix/linux/Makefile Makefile setenv XLISPPATH `pwd`/runtime:`pwd`/lib makeThe first line creates a
nyquist
directory and some subdirectories. The
second line makes a link from the top-level directory to the Makefile for your
system. In place of linux
in sys/unix/linux/Makefile
, you should
substitute your system type. Current systems are next
, pmax
,
rs6k
, sgi
, linux
, and sparc
. The setenv
command tells Nyquist where to search for lisp files to be loaded when a file
is not found in the current directory. The runtime
directory should
always be on your XLISPPATH
when you run Nyquist, so you may want to
set XLISPPATH
in your shell startup file, e.g. .cshrc
.
Assuming the make completes successfully, you can run Nyquist as follows:
./nyWhen you get the prompt, you may begin typing expressions such as the ones in the following "Examples" section.
One you establish that Nyquist (ny) is working from the command line, you should
try using jNyqIDE, the Java-based Nyquist development environment. First,
make jny
executable (do this only once when you install Nyquist):
chmod +x jnyThen try running jNyqIDE by typing:
./jnyIf the jNyqIDE window does not appear, make sure you have Java installed (if not, you probably already encountered errors when you ran
make
). You can also try recompiling the Java files:
cd jnyqide javac *.java cd ..
Note: With Linux and the Macintosh OS X,
jNyqIDE defines the environment passed to Nyquist. If you
set
You can specify additional directories for the search path by creating the
file
Note: Nyquist looks for the file
The runtime versions contain everything you need to run Nyquist, including the executable,
examples, and documentation. Each runtime version is packaged as an executable installer program.
I recommend
Optional: Nyquist needs to know where to find the standard runtime files. The location of runtime files must be stored in the Registry.
The installers create a registry entry, but if
you move Nyquist or deal with different versions, you can edit the Registry manually as follows:
Create a file named
You will find
On the Macintosh, Nyquist automatically creates a file
You can also download a pre-compiled version of Nyquist for the Mac.
Just download
The file <tt>jNyqIDE.app/Contents/Resources/Java/ny</tt>
is the command line executable (if you should need it). To run from the
command line, you will need to set the XLISPPATH environment variable as
with Linux. On the topic of the
You can cut and paste text into Nyquist, but for serious work, you will want to use the Lisp
Under Windows, if you encounter an error while loading a file, the file is left open, and you may not be able to overwrite the file with a correction.
To close the file, type
The Emacs editor is free GNU software and will help you balance parentheses if you use Lisp mode. Also, the NyqIDE and jNyqIDE versions have
built-in lisp editors. If your editor does not help you balance parentheses, you may find yourself counting parens and searching for unbalanced
expressions. If you are desparate, type
Our first example makes and plays a sound:
Note: when Nyquist plays a sound, it scales the signal by 2^(15)-1 and (by default) converts to a 16-bit integer format. A signal like
The function
A complete Nyquist waveform is a list consisting of a sound, a pitch,
and
Now that we have defined a function, the last step of this example is to
build the wave. The following code calls
Note that in Lisp, global variables often start and end with asterisks (*). These are not special syntax, they just happen to be legal characters for names, and their use is purely a convention.
(play (seq (note c4 i)
(note d4 i)
(note f4 i)
(note g4 i)
(note d4 q)))
The
Sequences can also be constructed using the
Figure 1: An envelope generated by the
; try it out:
;
(play (env-note c4))
In the next example,
In addition to
; a square pulse of height 10 and duration 5.
; Note that the first pair (0, 10) overrides the default initial
; point of (0, 0). Also, there are two points specified at time 5:
; (5, 10) and (5, 0). (The last 0 is implicit). The conflict is
; automatically resolved by pushing the (5, 10) breakpoint back to
; the previous sample, so the actual time will be 5 - 1/sr, where
; sr is the sample rate.
;
(pwl 0 10 5 10 5)
; a constant function with the value zero over the time interval
; 0 to 3.5. This is a very degenerate form of pwl. Recall that there
; is an implicit initial point at (0, 0) and a final implicit value of
; 0, so this is really specifying two breakpoints: (0, 0) and (3.5, 0):
;
(pwl 3.5)
; a linear ramp from 0 to 10 and duration 1.
; Note the ramp returns to zero at time 1. As with the square pulse
; above, the breakpoint (1, 10) is pushed back to the previous sample.
;
(pwl 1 10 1)
; If you really want a linear ramp to reach its final value at the
; specified time, you need to make a signal that is one sample longer.
; The RAMP function does this:
;
(ramp 10) ; ramp from 0 to 10 with duration 1 + one sample period
;
; RAMP is based on PWL; it is defined in nyquist.lsp.
;
XLISPPATH
as shown above, it will be ignored under jNyqIDE. Instead,
the XLISPPATH will have the lib
and runtime
directories only.
This does not apply to Windows because even though the environment is there,
the Windows version of Nyquist reads the XLISPPATH
from the Registry.
nyquist/xlisppath
, which should have colon-separated paths
on a single line of text.
init.lsp
in the current
directory. If you look in the init.lsp
in runtime
, you
will notice two things. First, init.lsp
loads nyquist.lsp
from the Nyquist directory, and second, init.lsp
loads system.lsp
which in turn defines the macro
play
. You may have to modify system.lsp
to invoke
the right programs on your machine.
Win32 Installation
The Win32 version of Nyquist is packaged in three versions: the source version
and two runtime versions. The source version is a superset of the runtime
version intended for developers who
want to recompile Nyquist. The source version exists as a .zip
file,
so you need a utility like WinZip to unpack them. The
URL http://www.winzip.com/
has information on this product. Typically,
the contents of the zip file are extracted to the C:\nyquist
directory,
but you can put it anywhere you like. You can then open the workspace file,
nyquist.sln, using Microsoft
Visual C++. You can build and run the command line and the NyqWin versions of Nyquist
from within Visual C++.
setupnyqiderun2xx.exe
("2xx" refers to the current version
number), a graphical interface written in
Java that runs nyquist.exe as
a separate process. This IDE has a simple lisp editor built in. Alternatively,
you can install setupnyqwinrun2xx.exe
, a different graphical
interface written in C++. Just copy the installer you want
to your system and run it. Then find Nyquist in your Start menu to run it.
You may begin typing expressions such as the ones in the following "Examples" section.
C:\WINNT\system32\regedt32.exe
. Under Windows95, run C:\WINDOWS\regedit.exe
.
SOFTWARE
key under HKEY_LOCAL_MACHINE
.
Add key ...
from the Edit
menu, type CMU
, and click the OK
button.
CMU
key.
Add key ...
from the Edit
menu, type Nyquist
, and click the OK
button. (Note that CMU
and Nyquist
are case sensitive.)
Nyquist
key.
Add value ...
from the Edit
menu, type XLISPPATH
, and click the OK
button. (Under WinXP the menu item is Edit:New:String Value
, after which you need to select the new string name that appears in the right panel, select Edit:Rename
, and type XLISPPATH
.)
Edit:Modify
menu item in WinXP),
type a list of paths you want Nyquist to search for lisp files. For example, if you installed Nyquist as C:\nyquist
, then type:
C:\nyquist\runtime,C:\nyquist\lib
The paths should be separated by a comma or semicolon and no space. The runtime
path is essential, and the lib
path may become essential in a future release. You can also add paths to personal libraries of Lisp and Nyquist code.
OK
button of the string box and exit from the Registry Editor application.
What if Nyquist functions are undefined?
If you do not have administrative privileges for your machine, the installer may fail to set up the Registry entry that Nyquist uses to find initialization files. In this case, Nyquist will run a lisp interpreter, but many Nyquist functions will not be defined. If you can log in as administrator, do it and reinstall Nyquist. If you do not have permission, you can still run Nyquist as follows:
init.lsp
in the same directory as Nyquist.exe (the default location is C:\Program Files\Nyquist
, but you may have installed it in some other location.) Put the following text in init.lsp
:
(setf *search-path* "C:/Program Files/Nyquist/runtime,C:/Program Files/Nyquist/lib")
Note: in the three places where you see
(load "C:/Program Files/Nyquist/runtime/init.lsp")
C:/Program Files/Nyquist
, insert the full path where Nyquist is actually installed. Use forward slashes (/
) rather than back slashes (\
) to separate directories. For example, if Nyquist is installed at D:\rbd\nyquist
, then init.lsp
should contain:
(setf *search-path* "D:/rbd/nyquist/runtime,D:/rbd/nyquist/lib")
The variable
(load "d:/rbd/nyquist/runtime/init.lsp")
*search-path*
, if defined, is used in place of the registry to determine search paths for files.
SystemRoot
(Ignore this paragraph if you are not planning to use Open Sound Control under Windows.)
If Nyquist prints an error message and quits when you enable Open Sound Control (using osc-enable
), check to see if you have an environment variable SystemRoot
, e.g. type set
to a command prompt and look for the value of SystemRoot
. The normal value is C:\windows
. If the value is something else, you should put the environment entry, for example:
SystemRoot="D:\windows"
into a file named
systemroot
(no extension). Put this file in your nyquist
directory. When you run jNyqIDE
, it will look for this file and pass the contents as an environment variable to Nyquist. The Nyquist process needs this to open a UDP socket, which is needed for Open Sound Control.
MacOS 9 Installation
The MacOS 9 version of Nyquist is no longer supported, but a old version still exists.
The MacOS version of Nyquist is packaged in two versions: the source version and the runtime version.
The source version is a superset of the runtime version. Both exist as self extracting archives,
so you just need to copy the archive file of your choice to your machine and double click on its icon.
You can extract the archive to any folder you like.
Nyquist
in the runtime
folder. Double click on it and you should see a
text window with some information that Nyquist has started and has loaded some files. You may begin
typing expressions such as the ones in the following section.
"System:Preferences:XLisp Preferences"
with a
default search path for files. You can edit this file to add new locations, although this
should not be necessary for most uses.
MacOS X Installation
The OS X version of Nyquist is very similar to the Linux version, but it
is developed using Xcode, Apple's programming environment. With a little
work, you can use the Linux installation instructions to compile Nyquist,
but it might be simpler to just open the Xcode project that is included
in the Nyquist sources.
nyqosx2xx.tgz
to the desktop and open it to
extract the folder <tt>nyqosx2xx</tt>. (Again, "2xx" refers to the current
version number, e.g. v2.31 would be named with "231".) Open the folder
to find a Mac Application named jNyqIDE and a directory named
<tt>nyquist/doc</tt>. Documentation is in the <tt>nyquist/doc</tt> directory.
XLISPPATH
, note that this variable is
set by jNyqIDE when running with that application, overriding any other
value. You can extend the search path by creating the file xlisppath
in the same directory as the nyquist executable ny
. The
xlisppath
file should have colon-separated paths
on a single line of text.
Helpful Hints
Under Win95 and Win98, the console sometimes locks up. Activating another window and then reactivating the Nyquist window should unlock the output.
(We suggest you use JNyqIDE, the interactive development environment rather than a console window.)
load
command. To save even more time, write a
function to load your working file, e.g. (defun l () (load "myfile.lsp"))
. Then you can type (l)
to (re)load your file.
(top)
to exit the debugger and resume at the top level of the interpreter. You may need to type (gc)
to
force a garbage collection. This will free and close the file. Now you can modify the file with your text editor.
(file-sexprs)
and type the lisp file name at the prompt. This function will read and print
expressions from the file, reporting an error when an extra paren or end-of-file is reached unexpectedly. By looking at the last expression
printed, you can at least tell where the unbalanced expression starts. Alternatively, try the verbose mode of the load
command.
Examples
We will begin with some simple Nyquist programs.
Detailed explanations of the functions used in these examples will be
presented in later chapters, so at this point, you should just read these
examples to get a sense of how Nyquist is used and what it can do. The
details will come later. Most of these examples can be found in the
file nyquist/sndtest/tutorial.lsp
.
;; Making a sound.
(play (osc 60)) ; generate a loud sine wave
This example is about the simplest way to create a sound with Nyquist. The
osc
function generates a sound using a table-lookup oscillator.
There are a number of optional parameters, but the default is to compute a
sinusoid with an amplitude of 1.0. The parameter 60
designates a
pitch of middle C. (Pitch specification will be described in greater detail
later.) The result of the osc
function is a sound. To hear a sound,
you must use the play
function, which under Unix writes the sound as a 16-bit sound file and runs a Unix program that plays the file through the machine's D/A converters. On the Macintosh, you have to explicitly play the file from another program, e.g. SoundApp, which is included in the Macintosh release. Under Windows, Nyquist outputs audio directly. It also writes a soundfile in case the computation cannot keep up with real time. You can then (re)play the file by typing:
(r)
This (r)
command is a general command to "replay" the last thing written by play
.
(osc 60)
, which ranges from +1 to -1, will play as a full-scale 16-bit audio signal. Signals are not normalized to full-scale, however, so an amplitude in excess of 1 will be clipped. See Section "Memory Space and Normalization" for information about normalization.
Waveforms
Our next example will be presented in several steps. The goal is to create a
sound using a
wavetable consisting of several harmonics as opposed to a simple sinusoid.
In order to build a table, we will use a function that computes a single
harmonic and add harmonics to form a wavetable. An oscillator
will be used to compute the harmonics.
mkwave
calls upon
build-harmonic
to generate a total of four
harmonics with amplitudes 1.0, 0.5, 0.25, and 0.12. These are scaled (using
scale
) and added (using sim
) to
create a waveform which is bound temporarily to *table*
.
T
, indicating a periodic waveform. The pitch gives the
nominal pitch of the sound. (This is implicit in a single cycle wave
table, but a sampled sound may have many periods of the fundamental.)
Pitch is expressed in half-steps, where middle C is 60 steps, as in MIDI
pitch numbers.
The list of sound, pitch, and T
is formed in the last line of
mkwave
: since build-harmonic
computes signals with a duration
of one second, the fundamental is 1 Hz, and the hz-to-step
function
converts to pitch (in units of steps) as required.
(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)))
mkwave
the first time the code is executed (loaded from a file). The second time, the variable *mkwave*
will be true, so mkwave
will not be invoked:
(cond ((not (boundp '*mkwave*))
(mkwave)
(setf *mkwave* t)))
Wavetables
When Nyquist starts, several waveforms are created and stored in global variables for convenience. They are: *sine-table*
, *saw-table*
, and *tri-table*
, implementing sinusoid, sawtooth, and triangle waves, respectively. The variable *table*
is initialized to *sine-table*
, and it is *table*
that forms the default wave table for many Nyquist oscillator behaviors. If you want a proper, band-limited waveform, you should construct it yourself, but if you do not understand this sentence and/or you do not mind a bit of aliasing, give *saw-table*
and *tri-table*
a try.
Sequences
Finally, we define note
to use the waveform, and play several notes
in a simple score:
(defun note (pitch dur)
(osc pitch dur *table*))
Here, note
is defined to take pitch and duration as parameters;
it calls osc
to do the work of generating a waveform, using
*table*
as a wave table.
seq
function is used to invoke a sequence of behaviors. Each
note is started at the time the previous note finishes. The parameters to
note
are predefined in Nyquist: c4
is middle C, i
(for
eIghth note) is 0.5, and q
(for Quarter note) is 1.0. See Section
"Predefined Constants" for a complete description. The result is the sum of
all the computed sounds.
at
transformation to
specify time offsets. See
sequence_example.htm
demos, sequence
for more examples and explanation.
Envelopes
The next example will illustrate the use of envelopes. In Nyquist,
envelopes are just ordinary sounds (although they normally have a low sample
rate). An envelope is applied to another sound by
multiplication using the mult
function. The code shows
the definition of env-note
, defined in terms of the
note
function in the previous example. In env-note
, a 4-phase
envelope is generated using the env
function, which is
illustrated in Figure 1.
env
function.
; env-note produces an enveloped note. The duration
; defaults to 1.0, but stretch can be used to change
; the duration.
;
(defun env-note (p)
(mult (note p 1.0)
(env 0.05 0.1 0.5 1.0 0.5 0.4)))
While this example shows a smooth envelope multiplied by an audio signal,
you can also use mult
to multiply to audio signals to achieve
what is often called ring modulation. See
the code and description in
demos/scratch_tutorial.htm
for an
interesting use of ring modulation to create "scratch" sounds.
stretch
is used to modify durations:
; now use stretch to play different durations
;
(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)))
stretch
, there are a number of transformations supported
by Nyquist,
and transformations of abstract behaviors is perhaps the fundamental
idea behind Nyquist. Chapter "Behavioral Abstraction" is devoted to
explaining this concept, and further elaboration can be found elsewhere
(Dannenberg and Frayley 1989).
Piece-wise Linear Functions
It is often convenient to construct signals in Nyquist using a list of
(time, value) breakpoints which are linearly interpolated to form a smooth
signal. Envelopes created by env
are a special case of the more
general piece-wise linear functions created by pwl
. Since pwl
is used in some examples later on, we will take a look at pwl
now. The pwl
function takes a list of parameters which denote (time,
value) pairs. There is an implicit initial (time, value) pair of (0, 0),
and an implicit final value of 0. There should always be an odd number of
parameters, since the final time is not implicit. Here are some examples:
; symetric rise to 10 (at time 1) and fall back to 0 (at time 2):
;
(pwl 1 10 2)
Predefined Constants
For convenience and readability, Nyquist pre-defines some constants, mostly
based on the notation of the Adagio score language, as follows:
lppp = -12.0 (dB)
lpp = -9.0
lp = -6.0
lmp = -3.0
lmf = 3.0
lf = 6.0
lff = 9.0
lfff = 12.0
dB0 = 1.00
dB1 = 1.122
dB10 = 3.1623
s = Sixteenth = 0.25
i = eIghth = 0.5
q = Quarter = 1.0
h = Half = 2.0
w = Whole = 4.0
sd, id, qd, hd, wd = dotted durations.
st, it, qt, ht, wt = triplet durations.
*A4-Hertz*
to the desired frequency for A4, and call
(set-pitch-names)
. This will recompute the names listed below with a
different tuning. In all cases, the pitch value 69.0 corresponds exactly to
440Hz, but fractional values are allowed, so for example, if you set
*A4-Hertz*
to 444 (Hz), then the symbol A4
will be bound to
69.1567, and C4
(middle C), which is normally 60.0, will be 60.1567.
c0 = 12.0
cs0, df0 = 13.0
d0 = 14.0
ds0, ef0 = 15.0
e0 = 16.0
f0 = 17.0
fs0, gf0 = 18.0
g0 = 19.0
gs0, af0 = 20.0
a0 = 21.0
as0, bf0 = 22.0
b0 = 23.0
c1 ... b1 = 24.0 ... 35.0
c2 ... b2 = 36.0 ... 47.0
c3 ... b3 = 48.0 ... 59.0
c4 ... b4 = 60.0 ... 71.0
c5 ... b5 = 72.0 ... 83.0
c6 ... b6 = 84.0 ... 95.0
c7 ... b7 = 96.0 ... 107.0
c8 ... b8 = 108.0 ... 119.0
ny:all
= "all the samples" (i.e. a big number) = 1000000000
More Examples
More examples can be found in the directory demos
, part of the standard
Nyquist release. In this directory, you will find the following and more:
demos/pmorales/b1.lsp
and demos/mateos/gong.lsp
demos/pmorales/b2.lsp
)
demos/pmorales/b3.lsp
, demos/pmorales/e2.lsp
, demos/pmorales/partial.lsp
, and demos/mateos/bell.lsp
)
demos/pmorales/b8.lsp
demos/shepard.lsp
and demos/pmorales/b9.lsp
)
demos/pmorales/c1.lsp
)
demos/pmorales/buzz.lsp
demos/pmorales/d1.lsp
demos/mateos/tuba.lsp
and clarinet sounds (demos/pmorales/e2.lsp
demos/rhythm_tutorial.htm
Previous Section | Next Section | Table of Contents | Index | Title Page