lilypond-user
[Top][All Lists]
Advanced

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

Re: Scheme predicative types


From: Aaron Hill
Subject: Re: Scheme predicative types
Date: Fri, 18 Sep 2020 03:16:38 -0700
User-agent: Roundcube Webmail/1.4.2

On 2020-09-18 2:01 am, Martín Rincón Botero wrote:
[ . . . ] The thing I couldn't adapt from your script
is the Text part, when the user writes a new tempo with a construction like
\tempo "Allegro". I suppose I have to somehow put my \once \override
TextSpanner #'(bound-details right text) in some sort of conditional so
that when the user puts a text, it displays a text, when it's a metronome, a metronome :-), but I couldn't figure out how to adapt what you already
had.

You could do things with conditionals, but it might make better sense to simply use a null markup when an element is not present. Consider:

%%%%
\version "2.20.0"

#(define (tempo? arg)
   (and (ly:music? arg)
        (not (null? (extract-typed-music arg 'tempo-change-event)))))

tempoTextSpan =
#(define-scheme-function
   (leftmarkup tempo lefthalign righthalign)
   (markup? tempo? number? number?)
   (set! tempo (first (extract-typed-music tempo 'tempo-change-event)))
   (let ((tempo-unit (ly:prob-property tempo 'tempo-unit #f))
         (metronome-count (ly:prob-property tempo 'metronome-count #f))
         (text (ly:prob-property tempo 'text #f))
         )
     (set! tempo-unit
       (if (ly:duration? tempo-unit)
           #{ \markup {
             \note #(ly:duration->string tempo-unit) #UP
               } #}
           #{ \markup \null #} ))
     (set! metronome-count
       (cond ((number-pair? metronome-count)
              #{ \markup { = \concat {
                 #(format #f "~d" (car metronome-count)) -
                 #(format #f "~d" (cdr metronome-count)) } } #})
             ((number? metronome-count)
              #{ \markup { =
                 #(format #f "~d" metronome-count) } #})
             (else #{ \markup \null #})))
     (set! text
       (if (markup? text)
           #{ \markup \abs-fontsize #11 \upright #text #}
           #{ \markup \null #}))
     #{
\once \override TextSpanner.bound-details.left-broken.text = ##f
\once \override TextSpanner.bound-details.right-broken.text = ##f
\once \override TextSpanner #'(bound-details left text) = \markup \halign
#lefthalign \abs-fontsize #11 #leftmarkup
\once \override TextSpanner #'(bound-details right text) = \markup \halign #righthalign \line { #text \abs-fontsize #10 \general-align #Y #DOWN #tempo-unit
\abs-fontsize #11 \upright #metronome-count }
     #}))

{
  \tempoTextSpan "accel." \tempo 4 = 80 #LEFT #RIGHT
  c'4\startTextSpan 4 4 4 2 2 d'1\stopTextSpan R1
  \tempoTextSpan "rall." \tempo "Adagio" 4 = 65-70 #LEFT #CENTER
  d'4\startTextSpan 4 4 4 2 2 e'1\stopTextSpan R1
  \tempoTextSpan "rit." \tempo \markup \box "Grave" #LEFT #LEFT
  e'4\startTextSpan 4 4 4 2 2 f'1\stopTextSpan R1 \bar "|."
}
%%%%

The advantage of the above approach is that the final markup is really nothing more than a concatenation of the elements.


I also wasn't successful in adding \once \omit Score.MetronomeMark
\tempo #tempo-unit = #metronome-count, so that the MIDI can pick up the new
tempo mark, if a metronome is given (probably because the new tempo is
converted to a markup and can't be used as a "real" tempo definition
anymore?).

This is not going to be easy to solve. You need to know when then \stopTextSpan occurs so that the \tempo command applies at that moment. However that information is entirely unknown at the time of \tempoTextSpan.

I would suggest handling MIDI tempo manually, that way you can issue as many \tempo commands as needed to properly simulate the accel, rall, and rit instructions.

Otherwise, this whole thing really looks like a job for a custom engraver/performer.


-- Aaron Hill

Attachment: tempo-text-span.cropped.png
Description: PNG image


reply via email to

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