lilypond-user
[Top][All Lists]
Advanced

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

new snippet: combine multimeasure rests


From: Shevek
Subject: new snippet: combine multimeasure rests
Date: Thu, 18 Apr 2013 16:41:50 -0700 (PDT)

I just finished writing my first Scheme extension for Lilypond! It is a
function to take a sequential music expression and condense consecutive
multimeasure rests into a single multimeasure rest. Since this is my first
attempt at Scheme, I'd love suggestions on how to improve it. One thing I'd
like is to make this something that can be turned on with a single line in a
layout block, instead of a function that needs to be included with every
staff or voice.

% \version "2.14.2"
\version "2.16.0"

#(define (add-durations dur1 dur2) (ly:duration? ly:duration?)
         (let* ((len1 (ly:duration-length dur1))
                (len2 (ly:duration-length dur2))
                (mult (ly:moment-div (ly:moment-add len1 len2) len1)))
               (ly:make-duration (ly:duration-log dur1) 
                                 (ly:duration-dot-count dur1) 
                                 (* (ly:duration-scale dur1) (ly:moment-main
mult)))))

#(define (combinable-rest? rest)
         (and (ly:music? rest)
              (eq? 'MultiMeasureRestMusic (ly:music-property rest 'name))
              (null? (ly:music-property rest 'articulations))))

#(define (combine-mm-rests rest1 rest2) (combinable-rest? combinable-rest?)
         (make-music 'MultiMeasureRestMusic
           'duration (add-durations (ly:music-property rest1 'duration)
                                    (ly:music-property rest2 'duration))
           'articulations '()))

#(define (consolidator curr rest) (ly:music? ly:music?)
         (if (null? rest)
             (cons curr rest)
             (if (combinable-rest? (car rest))
                 (consolidator (combine-mm-rests curr (car rest))
                               (cdr rest))
                 (cons curr rest))))

#(define (accumulate-result output input) (list? list?)
         (if (null? input)
             output
             (let ((done output)
                   (curr (car input))
                   (rest (cdr input)))
                  (if (null? rest)
                      (append done (list curr))
                      (let ((prev (if (combinable-rest? curr)
                                      (consolidator curr rest)
                                      (cons curr rest))))
                           (accumulate-result (append done (list (car
prev))) (cdr prev)))))))

#(define (sequential-music? music)
         (and (ly:music? music)
              (eq? 'SequentialMusic (ly:music-property music 'name))))

combineMMRests = 
#(define-music-function (location parser music) (sequential-music?)
                        (make-music 'SequentialMusic
                          'elements (accumulate-result '() 
                                                        (ly:music-property
music 'elements))))

test = {
  \compressFullBarRests
  R1\fermataMarkup
  R1*2
  \tag #'foo \key e \major
  R2*6
  c1
  R1
  R2.*4
}

{ \removeWithTag #'foo \test }

{  \combineMMRests \removeWithTag #'foo \test }

Thanks for looking! I hope someone finds this useful.



--
View this message in context: 
http://lilypond.1069038.n5.nabble.com/new-snippet-combine-multimeasure-rests-tp144688.html
Sent from the User mailing list archive at Nabble.com.



reply via email to

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