lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Ritardandi and Accelerandi for MIDI


From: Michael Welsh Duggan
Subject: Ritardandi and Accelerandi for MIDI
Date: Sun, 28 Aug 2005 23:34:59 -0400
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/22.0.50 (gnu/linux)

Desiring to have my midi outputs support gradual tempo changes, I
hacked up the following file, which I present for discussion.  I would
be especially grateful for suggestions on how to improve this code, as
my scheme knowledge is sparse (I am much more conversant with elisp),
and my understanding of many of the lilypond internals is shaky, at
best.

% -*-Scheme-*-

\version "2.6.0"

#(use-modules (ice-9 optargs))
#(define* (tempo-change beat start end music #:optional quantum)
   "Applies a linear tempo change to some music.

Using BEAT as beat duration, applies a midi tempo change from
START beats per minute to END bpm over MUSIC.  This is
implemented by changing the tempo every QUANTUM (duration).
QUANTUM defaults to 32nd."
   (define (dur->mom x)
     (ly:music-length (make-music 'NoteEvent 
                                  'duration x 
                                  'pitch (ly:make-pitch 0 0 0))))
   (define (tempo-change tempo)
     (list
      (make-music 'ContextSpeccedMusic
                  'property-operations '()
                  'context-type 'Score
                  'element
                  (make-music 'OverrideProperty
                              'once #t
                              'pop-first #t
                              'grob-property 'transparent
                              'grob-value #t
                              'symbol 'MetronomeMark))
      (make-music 
       'EventChord
       'elements
       (list 
        (make-music 'MetronomeChangeEvent
                    'metronome-count tempo
                    'tempo-unit beat)))))
   (define (add-patch dur tempo rest)
       (append (list (make-music 'EventChord
                      'elements  (list 
                                  (make-music 'SkipEvent
                                   'duration dur))))
               (tempo-change (inexact->exact (round tempo)))
               rest))
   (let* ((len (ly:music-length music))
          (quantum (or quantum (ly:make-duration 4 0 1 1)))
          (intervals-mom (ly:moment-div len (dur->mom quantum)))
          (intervals (inexact->exact 
                      (floor 
                       (/ (ly:moment-main-numerator intervals-mom)
                          (ly:moment-main-denominator intervals-mom))))))
     (let loop
         ((count intervals)
          (elts '()))
       (if (zero? count)
           (make-music 'SimultaneousMusic
                       'elements
                       (list
                        (make-music 'SequentialMusic
                                    'elements
                                    (append (tempo-change start) elts))
                        music))
           (let ((tempo (+ start (/ (* (- end start) count) intervals))))
             (loop (- count 1) (add-patch quantum tempo elts)))))))
-- 
Michael Welsh Duggan
(address@hidden)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]