]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add support for tempo ranges
authorValentin Villenave <valentin@villenave.net>
Tue, 30 Nov 2010 20:24:40 +0000 (21:24 +0100)
committerValentin Villenave <valentin@villenave.net>
Tue, 30 Nov 2010 20:24:40 +0000 (21:24 +0100)
This commit
 - extends the parser to accept the following syntax:
     \tempo numA ~ numB
 - changes the 'tempoUnitCount property to accept either
a number or a pair (in which case tempoWholesPerMinutes
will be set by averaging the two numbers)
 - adapts the format-metronome-markup translation function
to print the tempo range properly
 - adds a metronome-range.ly regtest
 - adds relevant display-lily methods, and updates this
regtest as well.

input/regression/display-lily-tests.ly
input/regression/metronome-range.ly [new file with mode: 0644]
lily/metronome-engraver.cc
lily/parser.yy
scm/c++.scm
scm/define-context-properties.scm
scm/define-music-display-methods.scm
scm/lily.scm
scm/ly-syntax-constructors.scm
scm/song.scm
scm/translation-functions.scm

index 426b61771bee5e5c35010b73a1611dd6fb422741..c28ebf7e3bf15263341e92e62a1120080c149723 100644 (file)
@@ -164,6 +164,9 @@ stderr of this run."
 \test "" ##[ \mark \default #]                 % MarkEvent
 \test "" ##[ \mark "Allegro" #]
 \test "" ##[ \tempo 4 = 120 #]                 % MetronomeChangeEvent
+\test "" ##[ \tempo 4 = 108 ~ 116 #]
+\test "" ##[ \tempo "Allegro" 4 = 132 #]
+\test "" ##[ \tempo "Andante" #]
 
 %% key, time, clef, bar
 \test "" ##[ \key \default #]                  % KeyChangeEvent
diff --git a/input/regression/metronome-range.ly b/input/regression/metronome-range.ly
new file mode 100644 (file)
index 0000000..e5456ab
--- /dev/null
@@ -0,0 +1,15 @@
+\version "2.13.41"
+
+\header {
+  texidoc = "
+Tempo ranges are supported.  By default, numbers are
+printed with an en-dash character, separated by thin-spaces.
+"
+}
+
+\relative c'' {
+  \tempo 4 = 66 ~ 72
+  c1 c
+  \set Score.tempoUnitCount = #(cons 124 132)
+  c1 c
+}
index d55455f23d36533c6e1131971ed8b0d9a53b9ab7..0a41fc97abdb61fb1dde875722a7a565716b55a6 100644 (file)
@@ -160,7 +160,7 @@ Metronome_mark_engraver::process_music ()
   SCM duration = get_property ("tempoUnitDuration");
   SCM text = get_property ("tempoText");
 
-  if ( ( (unsmob_duration (duration) && scm_is_number (count))
+  if ( ( (unsmob_duration (duration) && scm_is_true (count))
         || Text_interface::is_markup (text) )
       && !(ly_is_equal (count, last_count_)
           && ly_is_equal (duration, last_duration_)
index 38e3e93b101d5ba40aeb2457b81df4eab8d1894a..94dacc5d3eebc2491fc96bd34c68eee5b658ece5 100644 (file)
@@ -437,6 +437,7 @@ If we give names, Bison complains.
 %type <scm> step_number
 %type <scm> step_numbers
 %type <scm> string
+%type <scm> tempo_range
 
 %type <score> score_block
 %type <score> score_body
@@ -906,14 +907,14 @@ output_def_body:
        ;
 
 tempo_event:
-       TEMPO steno_duration '=' bare_unsigned  {
-               $$ = MAKE_SYNTAX ("tempo", @$, SCM_BOOL_F, $2, scm_from_int ($4));
+       TEMPO steno_duration '=' tempo_range    {
+               $$ = MAKE_SYNTAX ("tempo", @$, SCM_BOOL_F, $2, $4);
        }
-       | TEMPO string steno_duration '=' bare_unsigned {
-               $$ = MAKE_SYNTAX ("tempo", @$, make_simple_markup($2), $3, scm_from_int ($5));
+       | TEMPO string steno_duration '=' tempo_range   {
+               $$ = MAKE_SYNTAX ("tempo", @$, make_simple_markup($2), $3, $5);
        }
-       | TEMPO full_markup steno_duration '=' bare_unsigned    {
-               $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, scm_from_int ($5));
+       | TEMPO full_markup steno_duration '=' tempo_range      {
+               $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, $5);
        }
        | TEMPO string {
                $$ = MAKE_SYNTAX ("tempoText", @$, make_simple_markup($2) );
@@ -2289,6 +2290,15 @@ step_number:
        }
        ;
 
+tempo_range:
+       bare_unsigned {
+               $$ = scm_from_int ($1);
+       }
+       | bare_unsigned '~' bare_unsigned {
+               $$ = scm_cons (scm_from_int ($1), scm_from_int ($3));
+       }
+       ;
+
 /*
        UTILITIES
 
@@ -2360,7 +2370,6 @@ unsigned_number:
        }
        ;
 
-
 exclamations:
                { $$ = 0; }
        | exclamations '!'      { $$ ++; }
index 7f28900917643c17fd0a5f0993601802a957097d..204f813d4736388030db061ed5eea3927ec62cf6 100644 (file)
@@ -47,6 +47,9 @@
 (define-public (string-or-pair? x)
   (or (string? x) (pair? x)))
 
+(define-public (number-or-pair? x)
+  (or (number? x) (pair? x)))
+
 (define-public (cheap-list? x)
   (or (pair? x) (null? x)))
 
index 8a22e2d36aba5e38cf7feab807d8487a77f9e96e..f758c04ca1a09085f57323163b6d3029a3d963f3 100644 (file)
@@ -461,7 +461,7 @@ staff position of a tablature note head.  Called with two arguments:
 the context and the string.")
      (tempoHideNote ,boolean? "Hide the note=count in tempo marks.")
      (tempoText ,markup? "Text for tempo marks.")
-     (tempoUnitCount ,number? "Count for specifying tempo.")
+     (tempoUnitCount ,number-or-pair? "Count for specifying tempo.")
      (tempoUnitDuration ,ly:duration? "Unit for specifying tempo.")
      (tempoWholesPerMinute ,ly:moment? "The tempo in whole notes per
 minute.")
index 3b896a245017f6aa463fcb8d412b0dcd495aa617..515fc92d38402787e3748b0011b436273bff02f2 100644 (file)
@@ -934,7 +934,11 @@ Otherwise, return #f."
                (format #f "\\tempo ~a ~a = ~a"
                        (scheme-expr->lily-string ?unit-text)
                        (duration->lily-string ?unit-duration #:force-duration #t)
-                       ?unit-count))
+                       (if (number-pair? ?unit-count)
+                           (format #f "~a ~~ ~a"
+                                   (car ?unit-count)
+                                   (cdr ?unit-count))
+                           ?unit-count)))
        (with-music-match (expr (music 'ContextSpeccedMusic
                    element (music 'SequentialMusic
                              elements ((music 'PropertyUnset
@@ -949,7 +953,11 @@ Otherwise, return #f."
                                          symbol 'tempoUnitCount)))))
                        (format #f "\\tempo ~a = ~a"
                                (duration->lily-string ?unit-duration #:force-duration #t)
-                               ?unit-count))
+                               (if (number-pair? ?unit-count)
+                                   (format #f "~a ~~ ~a"
+                                           (car ?unit-count)
+                                           (cdr ?unit-count))
+                                   ?unit-count)))
        (with-music-match (expr (music 'ContextSpeccedMusic
                            element (music 'SequentialMusic
                                      elements ((music 'PropertySet
index 0a7e4d0d13135efe204005907cb1017ff503237d..d4a0b238465dc652a1b0df4e5319931152656ca6 100644 (file)
@@ -502,6 +502,7 @@ LilyPond safe mode.  The syntax is the same as `define*-public'."
     (,markup-list? . "markup list")
     (,moment-pair? . "pair of moment objects")
     (,number-or-grob? . "number or grob")
+    (,number-or-pair? . "number or pair")
     (,number-or-string? . "number or string")
     (,number-pair? . "pair of numbers")
     (,rhythmic-location? . "rhythmic location")
index 92276e745f1ca9fbc31e367b6d02fa7633e82d2e..c34f5c9dd1dc81864acc7d2f143e7ba0d1e5dc7a 100644 (file)
              'element (ly:music-transpose music pitch)))
 
 (define-ly-syntax-simple (tempo text duration tempo)
-  (let ((props (list
-                 (make-property-set 'tempoWholesPerMinute
-                       (ly:moment-mul (ly:make-moment tempo 1)
-                                      (ly:duration-length duration)))
-                 (make-property-set 'tempoUnitDuration duration)
-                 (make-property-set 'tempoUnitCount tempo))))
-    (set! props (cons 
-            (if text (make-property-set 'tempoText text)
-                     (make-property-unset 'tempoText)) 
-            props))
+  (let* ((range-tempo? (pair? tempo))
+        (tempo-count (if range-tempo?
+                         (round (/ (+ (car tempo) (cdr tempo)) 2))
+                         tempo))
+        (props (list
+                (make-property-set 'tempoWholesPerMinute
+                                   (ly:moment-mul (ly:make-moment tempo-count 1)
+                                                  (ly:duration-length duration)))
+                (make-property-set 'tempoUnitDuration duration)
+                (make-property-set 'tempoUnitCount tempo))))
+    (set! props (cons
+                (if text (make-property-set 'tempoText text)
+                     (make-property-unset 'tempoText))
+                props))
     (context-spec-music
-      (make-sequential-music props)
-      'Score)))
+     (make-sequential-music props)
+     'Score)))
 
 (define-ly-syntax-simple (tempoText text)
   (context-spec-music
index 410b3c89df99361cd1b9d75f4fdd11b6ab9bab8a..88b4423702bb0037b33155f97257bdb0f1f14480 100644 (file)
                      (duration->number (ly:music-property tempo-spec 'tempo-unit))))
                  ((music-name? tempo-spec 'SequentialMusic)
                   (* (property-value
-                      (find-child tempo-spec (lambda (elt) (music-property? elt 'tempoUnitCount))))
+                      (find-child tempo-spec (lambda (elt)
+                                              (let ((tempo (music-property? elt 'tempoUnitCount)))
+                                                (if (pair? tempo)
+                                                    (round (/ (+ (car tempo) (cdr tempo)) 2))
+                                                    tempo)))))
                      (duration->number
                       (property-value
                        (find-child tempo-spec (lambda (elt) (music-property? elt 'tempoUnitDuration)))))))
index 62a408ce9652da38c2320c22d4b3240edec572a1..67653bc49a8da4709cd2ad5219c77b43eeca9b4c 100644 (file)
                                                     (ly:duration-dot-count dur)
                                                     1))
                        #f))
-         (note-markup (if (and (not hide-note) (number? count) (> count 0) )
+        (count-markup (cond ((number? count)
+                             (if (> count 0)
+                                 (make-simple-markup (number->string count))
+                                 #f))
+                            ((pair? count)
+                             (make-concat-markup
+                              (list
+                               (make-simple-markup (number->string (car count)))
+                               (make-simple-markup " ")
+                               (make-simple-markup "–")
+                               (make-simple-markup " ")
+                               (make-simple-markup (number->string (cdr count))))))
+                            (else #f)))
+         (note-markup (if (and (not hide-note) count-markup)
                          (make-concat-markup
                           (list
                            (make-general-align-markup Y DOWN note-mark)
                            (make-simple-markup " ")
                            (make-simple-markup "=")
                            (make-simple-markup " ")
-                           (make-simple-markup (number->string count))))
+                           count-markup))
                          #f))
          (text-markup (if (not (null? text))
                          (make-bold-markup text)