>>>>> "Mats" == Mats Bengtsson <[EMAIL PROTECTED]> writes:
Mats> Isn't it possible to obtain the same result in a simpler way by Mats> just transposing a hard coded template in C major into the Mats> current key? You'ld need a different template for each degree of each kind of scale, I think. And for flatted and sharpened turns. The number of templates multiplies fast. If you have a general rule for going one step up, one step down from any note given the current key, then you can do any turn; you just need to handle the alteration. Mats> Information on the current key signature is Mats> available in the keySignature context property (see the internal Mats> reference documentation for Key-engraver), but perhaps not in a Mats> very useful way. Hmmm. How does one get at that from a music function? ly:context-property ?? Mats> Also, don't forget about the instrumentTransposition property Mats> (which is set by the \transposition command) if you want to Mats> handle transposing instruments correctly. That shouldn't matter. Here's what I have so far, anyway. It mostly works, and handles ordinary turns. I'm not happy about tenuto (a note marked tenuto should be lengthened slightly and steal time from the next note on), nor about the handling of grace notes. And there are lots of ornaments I haven't handled yet. The resulting Midi sounds reasonable, but needs more work. In particular, it sounds (for clarinet) as if slurred notes are being tongued (I don't know enough about Midi yet, but suspect that when a EndNote event and a StartNote event are adjacent, one should omit the EndNote.) And there are lots of tempo markings to handle. I wish that Director Musices were implemented in scheme not common lisp... ---articulate.ly #(define ac:staccatoFactor '(1 . 8)) #(define ac:tenutoFactor '(1 . 1)) #(define ac:normalFactor '(7 . 8)) % assume start in C major #(define ac:current-key (make-music 'KeyChangeEvent 'tonic (ly:make-pitch -1 0 0) 'pitch-alist (list (cons 0 0) (cons 1 0) (cons 2 0) (cons 3 0) (cons 4 0) (cons 5 0) (cons 6 0)))) #(define ac:currentDuration (ly:make-duration 0 0)) #(define (ac:up note) (let* ((pitch (ly:music-property note 'pitch)) (notename (ly:pitch-notename pitch)) (new-notename (if (eq? notename 6) 0 (+ 1 notename))) (alterations (ly:music-property ac:current-key 'pitch-alist)) (new-alteration (cdr (assq new-notename alterations))) (new-octave (if (eq? new-notename 0) (+ 1 (ly:pitch-octave pitch)) (ly:pitch-octave pitch))) ) (set! (ly:music-property note 'pitch)(ly:make-pitch new-octave new-notename new-alteration)))) #(use-modules (ice-9 debug)) #(define (ac:down note) (begin (let* ((pitch (ly:music-property note 'pitch)) (notename (ly:pitch-notename pitch)) (new-notename (if (eq? notename 0) 6 (- notename 1))) (alterations (ly:music-property ac:current-key 'pitch-alist)) (new-alteration (cdr (assq new-notename alterations))) (new-octave (if (eq? new-notename 6) (- (ly:pitch-octave pitch) 1) (ly:pitch-octave pitch))) ) (set! (ly:music-property note 'pitch)(ly:make-pitch new-octave new-notename new-alteration)))) ) #(define (ac:articulate-one-note m fraction) "Replace m with m*fraction rest*(1-fraction)" (if (eq? 'NoteEvent (ly:music-property m 'name)) (let* ((dur (ly:music-property m 'duration)) (l (ly:duration-log dur)) (d (ly:duration-dot-count dur)) (factor (ly:duration-factor dur)) (num (car fraction)) (denom (cdr fraction))) (begin (set! ac:currentDuration dur) (set! (ly:music-property m 'duration) (ly:make-duration l d (* num (car factor)) (* denom (cdr factor)))))) m)) #(define ac:inSlur #f) #(define ac:inPhrasingSlur #f) % If there's an articulation, use it. % If in a slur, use tenutoFactor instead. % What to do about phrasing slurs? % Expect an EventChord % trills, turns., ornaments pralls etc. % are also treated as Articulations. % How should they be handled??? #(define (ac:getactions:elements es actions) (let* ((factor ac:normalFactor) (e (car es)) (tail (cdr es))) (case (ly:music-property e 'name) ((SkipEvent) (set! factor (cons 1 1))) ((RestEvent) (set! factor (cons 1 1))) ((ArticulationEvent) (let ((articname (ly:music-property e 'articulation-type))) (cond ((string= articname "staccato") (set! factor ac:staccatoFactor)) ((string= articname "tenuto") (set! factor ac:tenutoFactor)) ((string= articname "mordent") (set! actions (list 'mordent))) ((string= articname "prall") (set! actions (list 'trill))) ((string= articname "trill") (set! actions (list 'trill))) ((string= articname "turn") (set! actions (list 'turn))) ))) ((SlurEvent) (let ((direction (ly:music-property e 'span-direction))) (set! ac:inSlur (eq? direction -1)))) ((PhrasingSlurEvent) (let ((direction (ly:music-property e 'span-direction))) (set! ac:inPhrasingSlur (eq? direction -1))))) (if (null? tail) (cond ((null? actions) (if ac:inSlur (cons 'articulation '(1 . 1)) (cons 'articulation factor))) (else actions)) (ac:getactions:elements tail actions)))) #(define (ac:getactions music) (let* ((es (ly:music-property music 'elements))) (ac:getactions:elements es '()))) #(define (ac:setduration music duration) (if (or (eq? (ly:music-property music 'name) 'NoteEvent) (eq? (ly:music-property music 'name) 'RestEvent)) (set! (ly:music-property music 'duration) duration))) #(define (ac:articulate-chord music) (begin (cond ((eq? 'EventChord (ly:music-property music 'name)) (let ((actions (ac:getactions music))) (case (car actions) ((articulation) (map (lambda (x) (ac:articulate-one-note x (cdr actions))) (ly:music-property music 'elements)) (let* ((num (car (cdr actions))) (denom (cdr (cdr actions))) (mult (ly:duration-factor ac:currentDuration)) (newnum (* (- denom num) (car mult))) (newdenom (* (cdr mult) denom)) (len (ly:duration-log ac:currentDuration)) (dots (ly:duration-dot-count ac:currentDuration))) (if (not (eq? num denom)) (make-music 'SequentialMusic 'elements (list music (make-music 'EventChord 'elements (list (make-music 'RestEvent 'duration (ly:make-duration len dots newnum newdenom)))))) music))) ((trill) music) ((turn) (let* ((dur (ly:music-property (car (ly:music-property music 'elements)) 'duration)) (factor (ly:duration-factor dur)) (newdur (ly:make-duration (+ (ly:duration-log dur) 2) (ly:duration-dot-count dur) (car factor)(cdr factor)))) (begin (map (lambda (y) (ac:setduration y newdur)) (ly:music-property music 'elements)) (let* ((above (ly:music-deep-copy music)) (below (ly:music-deep-copy music)) (newmusic (make-music 'SequentialMusic 'elements (list above music below music)))) (begin (map (lambda (y) (ac:down y)) (filter (lambda (z) (eq? 'NoteEvent (ly:music-property z 'name))) (ly:music-property below 'elements))) (map (lambda (y) (ac:up y)) (filter (lambda (z) (eq? 'NoteEvent (ly:music-property z 'name))) (ly:music-property above 'elements))) newmusic))))) ))) ((eq? 'KeyChangeEvent (ly:music-property music 'name)) (set! ac:current-key music) music ) (else music)) )) articulate = #(define-music-function (parser location music) (ly:music?) "Adjust times of note to add tenuto, staccato and normal articulations. " (music-map ac:articulate-chord music) ) ----Usage lots-of-music=\relative c'' { ... } \include "articulate.ly" \score { \unfoldRepeats \articulate lots-of-music \midi{} } -- Dr Peter Chubb http://www.gelato.unsw.edu.au peterc AT gelato.unsw.edu.au http://www.ertos.nicta.com.au ERTOS within National ICT Australia _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user