\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
--- /dev/null
+\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
+}
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_)
%type <scm> step_number
%type <scm> step_numbers
%type <scm> string
+%type <scm> tempo_range
%type <score> score_block
%type <score> score_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) );
}
;
+tempo_range:
+ bare_unsigned {
+ $$ = scm_from_int ($1);
+ }
+ | bare_unsigned '~' bare_unsigned {
+ $$ = scm_cons (scm_from_int ($1), scm_from_int ($3));
+ }
+ ;
+
/*
UTILITIES
}
;
-
exclamations:
{ $$ = 0; }
| exclamations '!' { $$ ++; }
(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)))
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.")
(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
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
(,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")
'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
(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)))))))
(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)