Am 04.01.2015 um 02:13 schrieb Kieren MacMillan:
Hi Urs,

I'm not sure about that because that wasn't the problem at hand.
My problem was that I have to merge multimeasure rests that were written as e.g.

R1*4 {} R1*6

The empty expression is a music function that can return a \break (-> no rest 
merging) or an empty expression.
The linked function is able to merge consecutive rests when they are of the 
same type.

As I didn't look too close into the thread you linked I don't know if my 
problem is related to yours, but I suspect it's rather something different.
My problem was

\version "2.19.15"

\new Staff \with { \compressFullBarRests }
     << { R1*8 } { \repeat unfold 8 {s1} } >>

Keith’s \mergeSkips deals with that, but (if I understand correctly) not your 
empty-expression problem.

My function also merges skips but it fails on the \repeat construct.
So R1 R1 s1 s1 gives the attached result, but when you use \repeat multiple empty bars are printed. This is because \repeat unfold is a completely different representation than explicitly repeated music. I think it could be included if that's the issue, but I assume it's over my head so far. Principally it's a quite simple thing (just adding another conditional and taking the expression apart) but I don't have experience with this.

See the attached -- now self-contained -- file for some examples.

Urs


Cheers,
Kieren.
_______________________

Kieren MacMillan, composer
www:  <http://www.kierenmacmillan.info>
email:  i...@kierenmacmillan.info


\version "2.16.0"

% Taken from improved version from
% http://lilypond.1069038.n5.nabble.com/new-snippet-combine-multimeasure-rests-td144688.html
% Improved by Urs Liska to also merge over empty music expressions


#(define (add-durations dur1 dur2)
   (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)
        (or (eq? 'MultiMeasureRestMusic (ly:music-property rest 'name))
            (eq? 'SkipEvent (ly:music-property rest 'name)))
        (null? (ly:music-property rest 'articulations))))

#(define (combine-rests rest1 rest2)
   ;; create one rest/skip with the sum of both lengths
   (make-music (ly:music-property rest1 'name)
     'duration (add-durations (ly:music-property rest1 'duration)
                 (ly:music-property rest2 'duration))
     'articulations '()))

#(define (consolidator curr rest)
   ;; determine ir we have consecutive MultimeasureRests or skips
   (if (and (combinable-rest? curr)
            (not (null? rest)))
       ;; -> we have a combinable rest left and 'something' right
       (if (and (combinable-rest? (car rest))
                (eq? (ly:music-property curr 'name) (ly:music-property (car rest) 'name)))
           ;; -> we also have a combinable rest right and both are the same type,
           ;; recurse by first merging rests and then looking for the next item
           (consolidator (combine-rests curr (car rest))
             (cdr rest))
           ;; -> right is either no combinable rest or one of different type.
           (if (or (eq? 'BarCheck (ly:music-property (car rest) 'name))
                   (eq? 'Music (ly:music-property (car rest) 'name)))
               ;; -> right is one of the 'skippable' types,
               ;; so recurse using left and the next one to the right
               (consolidator curr (cdr rest))
               ;; just return left followed by righ
               (cons curr rest)))
       ;; -> no combinable rest to the left
       ; But what happens when rest *is* null?
       (cons curr rest)))

#(define (accumulate-result output input)
   ;; recurse over the elements of 'music', appending consolidated
   ;; items (i.e. the item or a merged rest) to 'output'
   (if (null? input)
       output
       (let ((done output)
             (curr (car input))
             (rest (cdr input)))
         (if (null? rest)
             (append done (list curr))
             (let ((prev (consolidator curr rest)))
               (accumulate-result (append done (list (car prev))) (cdr prev)))))))

#(define (condense music)
   ;; recurse over the music list and condense consecutive rests
   (let* ((output music)
          (elts (ly:music-property output 'elements))
          (elt (ly:music-property output 'element)))
     (if (pair? elts)
         (ly:music-set-property! output 'elements (map condense (accumulate-result '() elts))))
     (if (ly:music? elt)
         (ly:music-set-property! output 'element (condense elt)))
     output))

combineMMRests =
#(define-music-function (parser location music) (ly:music?)
   ;; process the 'music' argument and merge consecutive MultimeasureRests
       (condense music))

\combineMMRests {
  \compressFullBarRests
  c''1 \repeat unfold 3 R1 R1 R1 s1 s1 c''1
}

{
  \displayMusic {
    \repeat unfold 4 { R1 }
  }
}

{
  \displayMusic {
    R1*4
  }
}

{
  \displayMusic {
    R1 R1 R1 R1
  }
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to