[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Merge Rests Engraver
From: |
Jay Anderson |
Subject: |
Merge Rests Engraver |
Date: |
Tue, 21 Feb 2012 22:38:06 -0700 |
I want to open up the conversation about merging rests again (see bug
1228 http://code.google.com/p/lilypond/issues/detail?id=1228). Below
is a first go at a scheme based engraver. It doesn't kill any grobs so
the chance of segfaults is lower. Do overlapping grobs have any other
unintended consequences? I haven't spent much time testing it yet
besides the attached examples and a couple other scores. It seems to
work well enough. Let me know if you see any ways it can be
simplified.
-----Jay
\version "2.15.30"
#(define (grob-name grob)
(if (ly:grob? grob)
(assoc-ref (ly:grob-property grob 'meta) 'name)
#f))
#(define (moment=? a b)
(and
(eq? (ly:moment-main-numerator a) (ly:moment-main-numerator b))
(eq? (ly:moment-main-denominator a) (ly:moment-main-denominator b))))
#(define (mm-rest-length rest)
(ly:prob-property (ly:grob-property rest 'cause) 'length))
#(define merge-rests-engraver
(lambda (context)
(let ((calc-y-offset (lambda (rest)
(if
(and
(eq? (grob-name rest) 'MultiMeasureRest)
(moment=? (ly:context-property context 'measureLength)
(mm-rest-length rest)))
1 0)))
(same-length (lambda (rest-a rest-b)
(let ((type-a (grob-name rest-a))
(type-b (grob-name rest-b)))
(or
(and
(eq? type-a 'MultiMeasureRest)
(eq? type-b 'MultiMeasureRest)
(moment=? (mm-rest-length rest-a) (mm-rest-length rest-b)))
(and
(eq? type-a 'Rest)
(eq? type-b 'Rest)
(eq? (ly:grob-property rest-a 'duration-log)
(ly:grob-property rest-b 'duration-log)))))))
(rest-a #f)
(rest-b #f))
`((start-translation-timestep . ,(lambda (trans)
(set! rest-a #f)
(set! rest-b #f)))
(stop-translation-timestep . ,(lambda (trans)
(if (and rest-a rest-b
(same-length rest-a rest-b))
(let ((offset (calc-y-offset rest-a)))
(begin
(ly:grob-set-property!
rest-a 'Y-offset offset)
(ly:grob-set-property!
rest-b 'Y-offset offset))))))
(acknowledgers
(rest-interface . ,(lambda (engraver grob source-engraver)
(if rest-a
(set! rest-b grob)
(set! rest-a grob)))))))))
\score
{
\new Staff
<<
\new Voice \relative c'
{
\voiceOne
e4 r e r |
R1 |
r2 e |
}
\new Voice \relative c'
{
\voiceTwo
r4 c r r |
R1 |
r2 r4 c |
}
>>
\layout { \context { \Staff \consists #merge-rests-engraver } }
}
\score
{
\new Staff \relative c'
<<
{
\compressFullBarRests
c4 r r2 |
R1 |
r2 r4 r8 r16 r32 r |
R1*3 |
}
\\
{
c4 r r r |
R1 |
r2 r4 r8 r16 r32 r |
R1*3 |
}
>>
\layout { \context { \Staff \consists #merge-rests-engraver } }
}
- Merge Rests Engraver,
Jay Anderson <=