[Top][All Lists]

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

Re: Another time model (related to the usability thread)

From: Keith OHara
Subject: Re: Another time model (related to the usability thread)
Date: Mon, 30 Dec 2013 19:15:56 +0000 (UTC)
User-agent: Loom/3.14 (

Kieren MacMillan <kieren_macmillan <at>> writes:

> > If you insert a bar, you'd have to change R1*32 to R1*33 by hand. Or, 
if you
> > change the 10th out of the 32 bars into a 3/4 measure, I believe you 
> > then have to change R1*32 to "R1*9 R2. R1*22" -- highly error prone.
> \pushToTag was designed (by David K, and paid for in part by a bounty 
from me) to solve exactly that problem.
> Now all one needs is a function to take skips (e.g., from a global 
variable) and turn them into
> multi-measure-rests — which is probably relatively easy to do — and 
there's no more problem.  =)

The \pushToTag function does not insert skips of the correct length.
It inserts existing pieces of music into other music without adjusting
lengths, nor computing any lengths.

It would be helpful for LilyPond to compute rest-lengths for us.
I am playing around with the idea of eventually making R1\until#'coda  
repeat itself until LilyPond sees 'coda somewhere in the score.

Here is a toy version, using the existing input R1\tag#'coda
It requires "\alignTo \global {..}" where \global contains a
sequence with the tags at the desired times.

global = << {
  \tag #'intro \mark"intro"
  \time 4/4 \repeat unfold 5 s1
  \bar"||" \time 3/4 s4*3*5
  \tag #'verse \mark"verse"
  \bar"||" \time 2/4 s4*2*5
  \tag #'bridge \mark"bridge"
  \bar"||" \time 2/2 s1*5
  \tag #'coda \mark"coda"
  \bar"||" \time 9/8 s8*9*5
  \bar "|." }
  \relative c'' {
    \repeat unfold 65 c4
    \repeat unfold 15 c4.
  } >>

<<\new Staff \global
  \new Staff \alignTo \global \transpose c c' {
    \repeat unfold 3 b1
    b2 b2
    d'2. d'4. R1 } >>

%=====with this included before the input above=========
\version "2.16"
% vim: filetype=lilypond:
alignTo = #(define-music-function
(parser location conductor music) (ly:music? ly:music?)
"Lengthen any note or rest in the sequence MUSIC just before each tag
that matches a tag in the sequence CONDUCTOR, so that the tags occur
at the same times from to the beginnings of MUSIC and CONDUCTOR."
(define (find-sequence music)
  (or (fold-some-music
        (lambda (x) (music-is-of-type? x 'sequential-music))
        (lambda (x e1) (or e1 ; use the first nonempty sequence
                 (let ((es (ly:music-property x 'elements)))
                             (if (null? es) #f es))))
        (ly:input-warning (ly:music-property music 'origin)
               "alignTo: cannot find sequential music")
(let loop ((aligner (find-sequence conductor))
           (alignee (find-sequence music))
           (time-left (ly:music-length conductor)))
  (case (length alignee)
    ((0) music)
    ((1) (ly:music-set-property! (car alignee) 'duration
                 (make-duration-of-length time-left))
      (let* ((a (first alignee)) ; music that might be lengthened,
             (b (second alignee)) ; if this music is tagged
             (tag (ly:music-property b 'tags))
             (tail (and (not (null? tag))
                          (lambda (x)
                            (not (null? (lset-intersection
                               eq? tag
                               (ly:music-property x 'tags)))))
        (if tail
          (let ((tail-length (ly:music-length
                               (make-sequential-music tail))))
            (if (ly:moment<? time-left tail-length)
              (ly:input-warning (ly:music-property b 'origin)
                "alignTo: already beyond conductor's tag ~a"
                      eq? tag
                 (ly:music-property (car tail) 'tags)))
                a 'duration (make-duration-of-length
                              (ly:moment-sub time-left
        (loop (or tail aligner)
              (cdr alignee)
              (ly:moment-sub time-left
                             (ly:music-length a))))))))

reply via email to

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