Note lists are the "scores" of MusicN-style music computation. Each note event in the output mix is specified by a begin time, duration, and any associated parameters for the instrument used, e.g., frequency, amplitude, localization, timbre, etc.
A typical note in Snd looks like
; this calls a synthesis instrument procedure, fm-violin, at time 1 sec. for 2 secs. at pitch 440 Hz. and amplitude 0.5A list of notes is time-ordered by begin time and embedded within the with-sound macro, which allows various options on the output sound file, ala
(fm-violin 1.0 2.0 440.0 0.5)
(with-sound (:channels 2 :srate 96000 :output "/zap/aFewNotes.wav")But, heck we're using a computer -- so why always write all that detail by hand? The same structure can be used for algorithmically created lists of notes:
(fm-violin 0.0 2.0 440.0 0.5)
(fm-violin 1.0 2.0 880.0 0.5) ; notes can overlap
... etc.
)
(with-sound (:channels 2 :srate 96000 :output "/zap/lotsaNotes.wav")To use these features, pick up with-sound with (load "/usr/ccrma/lisp/src/snd/examp.scm") and for fm-violin (load "/usr/ccrma/lisp/src/snd/fmv.scm")
(do ((i 1 (1+ i))) ((= i 15))
; a note every second, shortening duration, up the chromatic scale from `A440', random amp
(fm-violin (* i 1.0) (/ 2.0 i) (* 440.0 (expt 2.0 (/ i 12.0))) (random 0.5))
))
Further explanation of the "unit generator" concept is
in order. Common equations used for creating or modifying signals have
been collected into a preloaded set of library of procedures for convenience.
Instead of writing a sine generator equation the hard way every time (like
sine.scm), it is easier to just call the procedure "oscil" which hides
the nitty-gritty of the oscillator equation. Instances of unit generators
are always created by a "make-" procedure and the instance is then available
to be called per sample, returning a value.
oscil = an oscillator
env = a piece-wise linear breakpoint
function
delay = delayline
etc.
Envelopes for frequency, amplitude, breath pressure and the like are created from time-varying functions. The simplest is a piece-wise linear breakpoint function available as a unit generator in Snd, called the env procedure. Syntax is described in its entry in index.html but briefly, the breakpoint function is a list of x y values, eg. (0 0 1 1 2 0) for a triangle shape.
Time-varying envelopes can be derived from procedures besides env, as long as they compute a value per sample. The notes.scm script includes one example demonstrating an oscil-driven frequency envelope.
Alternatives to note list style performance:
Note list performance is "one note / one event" much like a keyboard. Performance on other families of instruments is difficult to squeeze into this paradigm, also physical models which retain their state would rather be sounded "legato-style," so that state persists between events. More on this to come...