Posted March 25, 20177 yr Dear Janusz, Are there some functions to merge or disassemble articulation symbols, as shown below? (merge-articulations '(leg ponte)) => leg+ponte (disassemble-articulations leg+ponte) => (leg ponte) This would be useful when algorithmically generating or processing articulations, like chordize and friends are for algorithmically working with chords. Do you perhaps have such functionality already somewhere anyway, e.g., for generating this MusicXML output? Thanks! Best, Torsten
March 25, 20177 yr Author EDIT: OK, I now this this myself: (defun merge-articulations (arts &key (empty-articulations '(- default))) "Merges list of OMN articulations to a combined attribute. Args: arts: a list of OMN articulations empty-attributes: articulations to ignore in a combination. Examples: (merge-articulations '(ten ponte ubow)) => ten+ponte+ubow (merge-articulations '(- stacc)) => stacc" #| ; can be uncommented when articulationp works (assert (every #'articulationp arts) (arts) "All values to merge must be OMN attributes: ~A.~%" arts) |# (intern (reduce #'(lambda (a1 a2) (format nil "~A+~A" a1 a2)) (mappend #'(lambda (art) (unless (some #'(lambda (a) (eq art a)) empty-articulations) (list (symbol-name art)))) arts)))) (defun disassemble-articulations (art) "Splits a combined OMN articulations into a list of its individual attributes. Example: (disassemble-articulations 'leg+ponte) => (leg ponte)" #| (assert (articulationp art) (art) "Value not OMN articulations: ~A.~%" art) |# ;; split-string seems to be part of OMN (mapcar #'intern (split-string (symbol-name art) :separator "+")))
March 25, 20177 yr Author Here is some application example for the above functions. (setf my-rhythm '(1/8 1/8 1/16 1/16 -1/16 1/8 1/8 1/8 1/8)) (setf arts-1 (pattern-map '(((1/8 1/8) (leg stacc))) my-rhythm :otherwise '(default))) (setf arts-2 (pattern-map '(((1/8) (tasto))) my-rhythm :otherwise '(ord))) (mapcar #'merge-articulations (matrix-transpose (list (flatten arts-1) (flatten arts-2)))) => (leg+tasto stacc+tasto ord ord ord leg+tasto stacc+tasto leg+tasto stacc+tasto)
March 25, 20177 yr Author I thought we better have a function zipping articulations for us, in particular if there are articulation lists of different length. The function definition is below. Here is a usage example. Apologies to all string players that this does not necessarily make sense musically :) (make-omn :length '(1/8 1/8 1/16 1/16 -1/16 1/8 1/8 1/8 1/8) :articulation (zip-articulations '(default stacc stacc default) '(ubow dbow) '(ponte)) :swallow NIL :flat T) => (e ubow+ponte nil stacc+dbow+ponte s stacc+ubow+ponte nil dbow+ponte - e ubow+ponte nil stacc+dbow+ponte nil stacc+ubow+ponte nil dbow+ponte) Janusz: as with the dynamics function, this function does also not yet handle nested lists. Best, Torsten ;;; TODO: support nested lists -- somehow store nesting structure, then process flattened list and apply nesting back (defun zip-articulations (&rest arts) "Expects lists of articulations and combines them to a single list of merged articulations. Shorter lists are circled to the length of the longest. Example: (zip-articulations '(default leg leg default) '(breathy))" (let ((max-length (apply #'max (mapcar #'length arts)))) (mapcar #'merge-articulations (matrix-transpose (mapcar #'(lambda (xs) (circle-repeat xs max-length)) arts))))) (defun circle-repeat (pattern n) "Circle through elements in pattern (a list) until n elements are collected. NOTE: only supports flat list so far." (let ((l (length pattern))) (loop for i from 0 to (- n 1) collect (nth (mod i l) pattern)))) ; (circle-repeat '(bb4 g4 f4) 20)
Create an account or sign in to comment