(defun no-voice-crossing ;<== Note that this version uses keys instead of simple arguments. ; This should be used like: ; (no-voice-crossing :voices :input-mode :gracenotes? :rule-type :weight ). (&key (voices 0) ;<== the second argument is always the initial values and should be placed in :initvals for OM (input-mode :all) ; options: :all, :beat, :1st-beat, :1st-voice ;<== These options should be placed in the :menuins for OM (gracenotes? :include-gracenotes) ; options: :include-gracenotes, :exclude-gracenotes <== should be removed - no gracenotes in OM (rule-type :true/false) ; options: :true/false :heur-switch ;<== These options should be placed in the :menuins for OM (weight 1)) ;<== the second argument -> :menuins "Voices should not cross, i.e., the pitch of simultaneous note pairs in voices are always sorted in decreasing order. Arguments are inherited from r-pitch-pitch." ;<== should be placed in :doc for OM (let ((sorted-voices (sort voices #'<))) ;<== LISP code (mappend #'(lambda (voice1 voice2) (ce::r-pitch-pitch #'(lambda (pitches) ;<== Included ce:: prefix here ;; no rests -- no NILs (apply #'>= (remove NIL pitches))) (list voice1 voice2) '(0) input-mode gracenotes? :pitch rule-type weight)) (butlast sorted-voices) (rest sorted-voices))))