Documentation for Lisp Kernel FM instrument Music 401 October 1992 The FM function in the Lisp Kernel sets up the FM note structure to fit the FM instrument in csound's class.orc. The full Lisp code for the Lisp FM function from kernel.Oct92.cl is appended. First, here are the meanings of the various parameters. (fm (start dur amp pitch &key (mods mods) (fmi1 1) (fmi2 0) (devfn 5) (rise .01) (decay .01) (nfenv 3)(iatss 1) (iatdec .01) (ixmod 0) (ratio 1)(ratio2 0) (ratiofn 5) (ratiocps 0) (inddur 0) (glissint 0) (glissdur 0) (glissfn 1) (crescfactor 0) (crescdur 0) (crescfn 3) (stleft .5) (stcps 0) (fmstcps 0) (rvt 0) (pctrvb 0)) Fm takes 4 obligatory parameters which must be listed in order: start in seconds dur in seconds amp maximum from all instruments is 32,767. If more than one note is playing, the amplitude contributions from each note are simply added up. pitch in 8ve.pc, for example 8.03 is Eb above middle C The rest of the parameters are key-word parameters. They may be listed in any order. If any is omitted, that's ok, it is given a default which is the second element in its list above -- for example, (rise .01) means the default for rise is .01 seconds. If you want to override any default, do it like this, with the key-word preceded by a colon. (fm 0 1 5000 8.00 :rise 1.4 :stcps .2) Envelope parameters Envelope parameters affect the overall amplitude envelope of the note. This can make a great big difference in how it sounds. This uses the csound module envlpx. :rise rise time in seconds :decay decay time in seconds (decay is at the end of the note) :iatss amplitude at "steady state" from end of rise -- for example, :iatss .5 would get you a rise from 0 to amp, then a fall to .5 amp until the "decay" portion at the end of the note. :iatdec amplitude at end of decay :ixmod a number between -.9 and +.9 (default 0) that affects the sharpness of the exponential curve along which the amplitude varies. If you use an instrument such as mix which uses a csound oscil rather than envlpx for its envelope, you can specify the curve for the entire note using :nfenv . :nfenv function number for curve Glissando parameters :glissint glissando interval in semitones (default 0, no glissando) :glissdur glissando duration (defaults to entire note's duration) :glissfn function specifying curve for glissando (defaults to sine) You can use this to put a vibrato on the note -- for example, (fm 0 4 5000 8.00 :glissdur .2 :glissint .4) makes a sinusoid vibrato at a speed of 5 cycles per second (duration 1/5, a good speed for vibrato) and pitch width of .4 semitones (not too coarse). You can experiment. Stereo parameters Fm will pan between the speakers, which can give an illusion of spatial movement; or you can simply position each note somewhere between the lefet and right speakers. :stleft a number between 0 and 1 which multiplies the note's signal and puts the result in the left channel. The rest of the signal is put in the right channel (default is .5). :stcps cycles per second for stereo panning (default 0, no panning). for example, (fm 0 4 5000 8.00 :stleft 0) positions the note all in the left speaker (fm 0 4 5000 8.00 :stleft 1) positions the note all in the right speaker (fm 0 4 5000 8.00 :stleft 1 :stcps .25) starts in the right speaker and pans back and forth every 4 seconds (cps = .25, period = 1/cps, cps = 1/period). FM parameters for "timbre" These parameters affect the spectrum of the sound and the temporal evolution of that spectrum, using the efficient frequency modulation algorithm (see Dodge and Jerse, Chapter 4.1 for technical details). you can think of the timbre as having two "knobs" to control it, one for INDEX, the other for RATIO. The index knob specifies how much of the total energy is distributed in the upper partials (how "bright" it sounds). The ratio knob specifies just where in the frequency spectrum those upper partials are (integral ratios give harmonic partials, non-integral give non-harmonic). INDEX parameters :fmi1 value for the index, default 1. A value of 0 would get a sine tone; values up to around 10 will give very bright sounds, perhaps made non-harmonic due to foldover. :fmi2 default 0. If specified, the index will SWEEP from fmi1 to fmi2 during the note. This is useful as natural sounds are not static in spectrum. :inddur duration over which to sweep, default dur of note. :devfn curve over which to sweep, default 5 (a ramp) RATIO parameters :ratio ratio of m/c modulator divided by carrier, default 1 (NB D&J use c/m) :ratio2 if specified, sweeps from ratio to ratio2 :ratiocps speed at which to sweep the ratio, in cycles per second :ratiofn curve over which to seep the ratio, default ramp. The most useful of all these are FMI1, FMI2, and RATIO. For example, (fm 0 4 5000 7.00 :fmi1 8 :fmi2 0 :ratio 1.73) will get an interesting sound that starts bright with nonharmonics and ends with a sine. You can experiment. Crescendo (independently of envelope) :crescfactor multiplier, default 1 (e.g. if 2, goes to twice input amp) :crescdur duration over which to crescendo, default is entire duration of note :crescfn curve over which to crescendo, default 3 (exponential up) Others The :mods parameter will be described in a separate document -- essentially, it provides a modifiable Lisp Kernel environment to pass as a parameter, and enables the manipulation of musical entities at a level larger than that of the note. Avoid :rvt and :pctrvb as they take too long to compute (reverb time in seconds, percentage of signal reverbed) and there are better ways to do this. code from kernel.Oct92.cl ; a luxury FM instrument (insno 3 in class.orc) ; fmlx instrument pfields: ; p1 insno p2 start p3 dur p4 amp p5 8ve.pc ; p6 ratio m/c p7 fmi1 p8 fmi2 p9 devfunc [1] ; p10=rise p11=decay p12=nf for env [2] p13=iatss p14=iatdec p15=ixmod ; p16 ratio2 [ratio] p17 ratiofn [5] p18 ratiocps ; p19 dur for index sweep [dur] ; p20 gliss interval in semitones p21 dur for gliss [dur] p22 glissfn [1] ; p23 cresc factor p24 cresc dur [dur] p25 crescfn [3] ; p26 stereo initial portion in left channel [0] p27 stereo cps [.5] (defun fm (start dur amp pitch &key (mods mods) (fmi1 1) (fmi2 0) (devfn 5) (rise .01) (decay .01) (nfenv 3)(iatss 1) (iatdec .01) (ixmod 0) (ratio 1) (ratio2 0) (ratiofn 5) (ratiocps 0) (inddur 0) (glissint 0) (glissdur 0) (glissfn 1) (crescfactor 0) (crescdur 0) (crescfn 3) (stleft .5) (stcps 0) (fmstcps 0) (rvt 0) (pctrvb 0)) ;; insno 3: ;; fmlx instrument with all bells and whistles but without post-filtering (create-c) (-> insno 3) (-> start (+ (* start (car (getv mods 'durfac))) (car (getv mods 'starts)))) (-> dur (* dur (car (getv mods 'durfac)))) (-> amp (* amp (car (getv mods 'amplev)))) (-> amp (* (val amp) (car (getv mods 'gain)))) (-> amp (* (val amp) overallgain)) ; amp adjustment for soundfiles (-> pitch (transpose pitch (car (getv mods 'pitlev)))) (-> herz (pitch-cps (val pitch))) (-> rise (+ rise (car (getv mods 'riselev)))) (-> decay (+ decay (car (getv mods 'decaylev)))) (-> nfenv (+ nfenv (car (getv mods 'nfenvlev)))) (-> iatss (+ iatss (car (getv mods 'iatsslev)))) (-> iatdec (+ iatdec (car (getv mods 'iatdeclev)))) (-> ixmod (+ ixmod (car (getv mods 'ixmodlev)))) (-> ratio (+ ratio (car (getv mods 'ratiolev)))) (-> ratio2 (+ ratio2 (car (getv mods 'ratio2lev)))) (-> fmi1 (+ fmi1 (car (getv mods 'fmi1lev)))) (-> fmi2 (+ fmi2 (car (getv mods 'fmi2lev)))) (-> devfn (+ devfn (car (getv mods 'devfnlev)))) (-> ratiofn (+ ratiofn (car (getv mods 'ratiofnlev)))) (-> inddur (+ inddur (car (getv mods 'inddurlev)))) (-> ratiocps (* ratiocps (car (getv mods 'ratiocpsfactor)))) (-> glissint (+ glissint (car (getv mods 'glissintlev)))) (-> glissdur (+ glissdur (car (getv mods 'glissdurlev)))) (-> glissfn (+ glissfn (car (getv mods 'glissfnlev)))) (-> crescfactor (+ crescfactor (car (getv mods 'crescfactorlev)))) (-> crescdur (+ crescdur (car (getv mods 'crescdurlev)))) (-> crescfn (+ crescfn (car (getv mods 'crescfnlev)))) (-> stleft (+ stleft (car (getv mods 'stleftlev)))) (-> stcps (+ stcps (car (getv mods 'stcpslev)))) (-> fmstcps (+ fmstcps (car (getv mods 'fmstcpslev)))) (-> rvt (+ rvt (car (getv mods 'rvtlev)))) (-> pctrvb (+ pctrvb (car (getv mods 'pctrvblev)))) (save-note) )