The first approach involves creating all the necessary objects and assembling lists, then calling FOMUS's
main function to process everything.
The main function is FOMUS
and has the following format:
(FOMUS &key
setting
value
...)
setting
above is one of the setting keywords listed in chapter Settings, and
value
is its value.
Every piece of information FOMUS needs can be included in this function call.
The most important settings are GLOBAL
, PARTS
and EVENTS
, which contain all of the PART
,
TIMESIG
, NOTE
,
REST
and other objects that directly affect what appears on the score.
See the individual documentation for these for an explanation of how to use them.
A few examples are given below (illustrations are "raw" output processed with LilyPond version 2.4.2):
Example 3.1. FOMUS Usage 1
(fomus :output '(:lilypond :view t) :ensemble-type :orchestra :parts (list (make-part :name "Piano" :instr :piano :events (loop for off from 0 to 10 by 1/2 collect (make-note :off off :dur (if (< off 10) 1/2 1) :note (+ 48 (random 25)) :marks (when (<= (random 3) 0) '(:staccato)))))))
Example 3.2. FOMUS Usage 2
(fomus :output '(:lilypond :view t) :ensemble-type :orchestra :default-beat 1/4 :global (list (make-timesig :off 0 :time '(3 4)) (make-timesig :off 7 :time '(5 8))) :parts (list (make-part :name "Piano" :instr :piano :events (loop for basenote in '(54 42) nconc (loop for off = 0 then (+ off dur) and dur = (/ (1+ (random 4)) 2) while (< (+ off dur) 12) collect (make-note :voice '(1 2) :off off :dur dur :note (+ basenote (random 25))))))))
Example 3.3. FOMUS Usage 3
(fomus :output '(:lilypond :view t) :ensemble-type :orchestra :beat-division 4 :quartertones t :parts (list (make-part :partid 'flute :name "Flute" :instr :flute) (make-part :partid 'tuba :name "Tuba" :instr :tuba)) :events (loop repeat 5 for off = (random 1.0) then (+ off (1+ (random 1.0))) and dur = (random 1.0) and inst = (if (eq inst 'flute) 'tuba 'flute) collect (make-note :partid inst :off off :dur dur :note (+ (case inst (flute 72) (tuba 36)) (/ (random 25) 2)) :marks (case (random 3) (0 '(:accent)) (1 '(:staccato))))))
All of these settings are also present as special variables (see chapter Settings).
The following example accomplishes exactly the same thing as example
(fomus
:output '(:lilypond :view t)
:ensemble-type :orchestra
:parts
(list
(make-part
:name "Piano"
:instr :piano
:events
(loop
for off from 0 to 10 by 1/2
collect (make-note :off off
:dur (if (< off 10) 1/2 1)
:note (+ 48 (random 25))
:marks (when (<= (random 3) 0)
'(:staccato)))))))
Example 3.4. FOMUS Usage 4
(setf *output* '(:lilypond :view t)) (fomus :ensemble-type :orchestra :parts (list (make-part :name "Piano" :instr :piano :events (loop for off from 0 to 10 by 1/2 collect (make-note :off off :dur (if (< off 10) 1/2 1) :note (+ 48 (random 25)) :marks (when (<= (random 3) 0) '(:staccato)))))))
Specifying keywords in the FOMUS
function always overrides what is contained in the special variables.
Also, FOMUS
accepts one additional key, :ALLOW-OTHER-KEYS
.
Passing a value of T
to this argument allows other keys that FOMUS doesn't recognize
to be present in the call.
By default, FOMUS
accepts only keywords listed in Settings.