You can replace \time
by a custom function which does the same and stores the current time signature in a global variable. This is very much contrary to the spirit of functional programming but should work as long as your music is evaluated in the same order it will be processed (which, I suspect, covers most practical cases).
Here is some relevant code:
#(begin
(define *current-time* (cons 4 4))
; Usage: `\Time a b` (**not** a/b, sadly)
; Sets the current time signature and stores it in a global variable.
(define Time (define-music-function (a b) (integer? integer?)
(set! *current-time* (cons a b))
#{ \time $(cons a b) #} ))
(define (skip-n-bars ev) (define-music-function (n) (integer?)
(make-music ev 'duration
(ly:make-duration 0 0 (* n (car *current-time*)) (cdr *current-time*)))))
; sb = skip bars; rb = rest bars
; Usage: `\sb n` will skip `n` bars with current time signature
(define sb (skip-n-bars 'SkipEvent))
(define rb (skip-n-bars 'MultiMeasureRestMusic))
)
\score { \relative c' {
\Time 6 8 c4. d \rb 3 e f
} }
As you can see, there are two other differences with \time
:
- I was unable to make
\Time 6/8
work, so I had to settle for a space instead (6/8 is lexed as a pair but not accepted by the pair?
predicate) — I did not try too hard either, if anyone has a solution for this, feel free to comment;
\rb
and \sb
invocations do not set the last duration in the same way R
or s
would do, so the note after the \rb
call takes its duration from the note before it (here 4.). (I would call this a feature, since it is quite rare to want to reuse a multi-bar rest duration for a note!).