From c5e69d8a504f0d62759c0a2a2dadbc36b86eb049 Mon Sep 17 00:00:00 2001 From: hanwen Date: Tue, 16 Jul 2002 23:41:14 +0000 Subject: [PATCH] 2002-07-17 Han-Wen * lily/parser.yy (Repeated_music): shift duration log for tremolo repeats, instead of klutzing around. * lily/chord-tremolo-engraver.cc (acknowledge_grob): set X parent of stem tremolo grobs. * scm/music-functions.scm (shift-duration-log): new function, add to duration log of all notes. * lily/duration.cc: add compression factor arguments to make-duration. compression-factor, dot-count, duration-log: add scheme functions. * lily/mark-engraver.cc (process_music): allow \mark to take a number as argument as well. 2002-07-16 Han-Wen * lily/rest.cc (after_line_breaking): only translate the whole rest if we have more than 1 staff line * lily/parser.yy (property_def): only allow #Scheme as \property argument. --- .cvsignore | 33 ++++++----- ChangeLog | 26 +++++++++ Documentation/user/refman.itely | 6 +- input/regression/chord-tremolo.ly | 7 +-- input/regression/rhythmic-staff.ly | 4 +- lily/chord-tremolo-engraver.cc | 88 ++++++++++-------------------- lily/chord-tremolo-iterator.cc | 3 +- lily/duration.cc | 78 ++++++++++++++++++++++++-- lily/include/duration.hh | 5 +- lily/include/musical-request.hh | 9 ++- lily/mark-engraver.cc | 3 +- lily/music.cc | 2 +- lily/note-heads-engraver.cc | 2 - lily/parser.yy | 32 +++++++---- lily/rest.cc | 2 +- lily/spacing-engraver.cc | 1 + ly/property-init.ly | 6 +- scm/c++.scm | 6 +- scm/grob-description.scm | 2 +- scm/lily.scm | 2 +- scm/music-functions.scm | 41 ++++++++++++++ 21 files changed, 243 insertions(+), 115 deletions(-) diff --git a/.cvsignore b/.cvsignore index 58fa7ee215..a9116890cd 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,15 +1,3 @@ -GNUmakefile -TAGS -autom4te.cache -configure -config.cache -config.h -config.log -config.make -config.status -.dstreamrc -.gdbinit -*~ #* *.aux *.dvi @@ -26,11 +14,28 @@ config.status *.tex *.txt *[0-9]pk +*~ +.dstreamrc +.gdbinit +GNUmakefile +TAGS +afm +autom4te.cache +config.cache +config.h +config.log +config.make +config.status +configure +fonts +l +log +ls-R ly2dvi.dir out out-www -afm +rc share +stepmake tfm tfm.[0-9] -stepmake diff --git a/ChangeLog b/ChangeLog index b3ec0df4d3..581e57e0aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2002-07-17 Han-Wen + + * lily/parser.yy (Repeated_music): shift duration log for tremolo + repeats, instead of klutzing around. + + * lily/chord-tremolo-engraver.cc (acknowledge_grob): set X parent + of stem tremolo grobs. + + * scm/music-functions.scm (shift-duration-log): new function, add + to duration log of all notes. + + * lily/duration.cc: add compression factor arguments to + make-duration. + compression-factor, dot-count, duration-log: add scheme functions. + + * lily/mark-engraver.cc (process_music): allow \mark to take a + number as argument as well. + +2002-07-16 Han-Wen + + * lily/rest.cc (after_line_breaking): only translate the whole + rest if we have more than 1 staff line + + * lily/parser.yy (property_def): only allow #Scheme as \property + argument. + 2002-07-16 Han-Wen Nienhuys * VERSION: release 1.5.68 diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 7f7f7007a3..e39eccc2c1 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -3182,12 +3182,12 @@ a tone. The first version will print sharps and the second version will print flats. @lilypond[singleline, verbatim] -mus =\notes { \key e \major c d e f } +mus =\notes { \key d \major cis d fis g } \score { \notes \context Staff { \clef "F" \mus \clef "G" - \transpose des'' \mus - \transpose cis'' \mus + \transpose g'' \mus + \transpose f'' \mus }} @end lilypond diff --git a/input/regression/chord-tremolo.ly b/input/regression/chord-tremolo.ly index c45d6df58b..c773cf2d76 100644 --- a/input/regression/chord-tremolo.ly +++ b/input/regression/chord-tremolo.ly @@ -18,12 +18,11 @@ stems. \repeat "tremolo" 8 { d16 e } \repeat "tremolo" 4 { d e } \repeat "tremolo" 2 { d e } - \repeat "tremolo" 1 { d e } - \repeat "tremolo" 1 { d e } + c4 \break \repeat "tremolo" 4 { f'8 e } - \repeat "tremolo" 2 { f e } - \repeat "tremolo" 1 { f e } + \repeat "tremolo" 2 { f e } + c4 c4 c4 c4 c4 c4 c4 c4 c4 c4 c4 c4 c4 diff --git a/input/regression/rhythmic-staff.ly b/input/regression/rhythmic-staff.ly index 9b9b6e1162..55b7b64eb7 100644 --- a/input/regression/rhythmic-staff.ly +++ b/input/regression/rhythmic-staff.ly @@ -1,11 +1,11 @@ \header { - texidoc = "In rhythmic staffs, stems should go up, and bar lines have the size for a 5 line staff" + texidoc = "In rhythmic staffs, stems should go up, and bar lines have the size for a 5 line staff. The whole note hangs from the rhythmic staff." } \score { \notes \context RhythmicStaff { - r4 c4. c8 r8 c8 | c2 r2 + r4 c4. c8 r8 c8 | c2 r2 | r1 } } diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc index 43e66eb4a3..2bf00410fb 100644 --- a/lily/chord-tremolo-engraver.cc +++ b/lily/chord-tremolo-engraver.cc @@ -48,13 +48,10 @@ protected: /// moment (global time) where beam started. Moment start_mom_; Moment stop_mom_; - + int flags_i_ ; /// location within measure where beam started. Moment beam_start_location_; - int note_head_i_; - int dots_i_; - bool sequential_body_b_; Spanner * beam_p_; Spanner * finished_beam_p_; @@ -72,8 +69,7 @@ Chord_tremolo_engraver::Chord_tremolo_engraver () { beam_p_ = finished_beam_p_ = 0; repeat_ =0; - note_head_i_ = 0; - dots_i_ = 0; + flags_i_ = 0; stem_tremolo_ = 0; sequential_body_b_ = false; } @@ -92,10 +88,10 @@ Chord_tremolo_engraver::try_music (Music * m) stop_mom_ = start_mom_ + l; sequential_body_b_ = dynamic_cast (rp->body ()); - // ugh. should generate triplet beams. - note_head_i_ = int (ceil (double(l.den ()) / l.num ())); - dots_i_ = intlog2 (1+l.num ()) -1 ; // 1->0, 3->1, 7->2 - note_head_i_ = note_head_i_ repeat_count ())); + flags_i_ = intlog2 ((total_dur / note_dur).num ()); + return true; } @@ -112,7 +108,6 @@ Chord_tremolo_engraver::process_music () beam_p_ = new Spanner (get_property ("Beam")); beam_p_->set_grob_property ("chord-tremolo", SCM_BOOL_T); - SCM smp = get_property ("measurePosition"); Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); @@ -121,13 +116,13 @@ Chord_tremolo_engraver::process_music () } else if (!sequential_body_b_ && !stem_tremolo_) { - int flags = intlog2 (note_head_i_ * repeat_->repeat_count ()) -2; - if (flags) + + if (flags_i_) { stem_tremolo_ = new Item (get_property ("StemTremolo")); announce_grob(stem_tremolo_, repeat_->self_scm()); stem_tremolo_->set_grob_property ("flag-count", - gh_int2scm (flags)); + gh_int2scm (flags_i_)); } } @@ -158,59 +153,36 @@ Chord_tremolo_engraver::typeset_beam () void Chord_tremolo_engraver::acknowledge_grob (Grob_info info) { - if (beam_p_) + if (beam_p_ && Stem::has_interface (info.grob_l_)) { - if (Stem::has_interface (info.grob_l_)) - { - Grob * s = info.grob_l_; - int f = Stem::duration_log (s); - f = (f > 2) ? f - 2 : 1; - Stem::set_beaming (s, f, LEFT); - Stem::set_beaming (s, f, RIGHT); + Grob * s = info.grob_l_; + Stem::set_beaming (s, flags_i_, LEFT); + Stem::set_beaming (s, flags_i_, RIGHT); - SCM d = s->get_grob_property ("direction"); - if (Stem::duration_log (s) != 1) - { - int gap_i =Stem::duration_log (s) - ((Stem::duration_log (s) >? 2) - 2); - beam_p_->set_grob_property ("gap", gh_int2scm (gap_i)); - } - s->set_grob_property ("direction", d); + SCM d = s->get_grob_property ("direction"); + if (Stem::duration_log (s) != 1) + { + beam_p_->set_grob_property ("gap", gh_double2scm (0.8)); + } + s->set_grob_property ("direction", d); - if (dynamic_cast (info.music_cause ())) - { - Beam::add_stem (beam_p_, s); - } + if (dynamic_cast (info.music_cause ())) + { + Beam::add_stem (beam_p_, s); + } + else + { + String s = _ ("stem must have Rhythmic structure"); + if (info.music_cause ()) + info.music_cause ()->origin ()->warning (s); else - { - String s = _ ("stem must have Rhythmic structure"); - if (info.music_cause ()) - info.music_cause ()->origin ()->warning (s); - else - ::warning (s); - } + ::warning (s); } } else if (stem_tremolo_ && Stem::has_interface (info.grob_l_)) { Stem_tremolo::set_stem (stem_tremolo_, info.grob_l_); - - info.grob_l_->set_grob_property ("duration-log", gh_int2scm (intlog2 (note_head_i_))); - } - - - if (repeat_ && Note_head::has_interface (info.grob_l_)) - { - info.grob_l_->set_grob_property ("duration-log", gh_int2scm (intlog2 (note_head_i_))); - if (dots_i_ > 0) - { - Item * d = new Item (get_property ("Dots")); - Rhythmic_head::set_dots (info.grob_l_, d); - - d->set_grob_property ("dot-count", gh_int2scm (dots_i_)); - - d->set_parent (info.grob_l_, Y_AXIS); - announce_grob (d, SCM_EOL); - } + stem_tremolo_->set_parent (info.grob_l_,X_AXIS); } } diff --git a/lily/chord-tremolo-iterator.cc b/lily/chord-tremolo-iterator.cc index 9228afb104..e3364847d0 100644 --- a/lily/chord-tremolo-iterator.cc +++ b/lily/chord-tremolo-iterator.cc @@ -21,7 +21,7 @@ void Chord_tremolo_iterator::construct_children () { Repeated_music * rep = dynamic_cast (music_l ()); - factor_ = Moment (Rational(1, rep->repeat_count ())); + factor_ = Moment (Rational(1, 1)); child_iter_p_ = get_iterator_p (rep->body ()); } @@ -53,7 +53,6 @@ Chord_tremolo_iterator::process (Moment m) child_iter_p_->process (factor_ * m); } - Moment Chord_tremolo_iterator::pending_moment () const { diff --git a/lily/duration.cc b/lily/duration.cc index 28b41a0210..43dea75b30 100644 --- a/lily/duration.cc +++ b/lily/duration.cc @@ -1,6 +1,6 @@ /* - duration.cc -- implement Duration, Plet, - + duration.cc -- implement Duration + source file of the LilyPond music typesetter (c) 1997--2002 Jan Nieuwenhuizen @@ -10,6 +10,7 @@ #include +#include "misc.hh" #include "lily-proto.hh" #include "string.hh" #include "moment.hh" @@ -133,15 +134,16 @@ Duration::less_p (SCM p1, SCM p2) return SCM_BOOL_F; } - LY_DEFINE(make_duration, - "make-duration", 2, 0, 0, (SCM length, SCM dotcount), + "make-duration", 2, 2, 0, (SCM length, SCM dotcount, + SCM num, SCM den), " @var{length} is the negative logarithm (base 2) of the duration: 1 is a half note, 2 is a quarter note, 3 is an eighth note, etc. The number of dots after the note is given by @var{dotcount}. +The duration factor is optionally given by @var{num} and @var{den}. A duration is a musical duration, i.e. a length of time described by a power of two (whole, half, quarter, etc.) and a number of augmentation @@ -151,11 +153,79 @@ dots. { SCM_ASSERT_TYPE(gh_number_p(length), length, SCM_ARG1, __FUNCTION__, "integer"); SCM_ASSERT_TYPE(gh_number_p(dotcount), dotcount, SCM_ARG2, __FUNCTION__, "integer"); + + bool compress = false; + if (num != SCM_UNDEFINED) + { + SCM_ASSERT_TYPE(gh_number_p(num), length, SCM_ARG3, __FUNCTION__, "integer"); + compress = true; + } + else + num = gh_int2scm (1); + + if (den != SCM_UNDEFINED) + SCM_ASSERT_TYPE(gh_number_p(den), length, SCM_ARG4, __FUNCTION__, "integer"); + else + den = gh_int2scm (1); Duration p (gh_scm2int (length), gh_scm2int (dotcount)); + if (compress) + p = p.compressed (Rational (gh_scm2int (num), gh_scm2int (den))); + return p.smobbed_copy (); } + + +LY_DEFINE(duration_log, + "duration-log", 1, 0, 0, (SCM dur), + " +Extract the duration log from @var{dur}" +) +{ + SCM_ASSERT_TYPE(unsmob_duration(dur), dur, SCM_ARG1, __FUNCTION__, "duration"); + + return gh_int2scm (unsmob_duration (dur)->duration_log ()); +} + + +LY_DEFINE(dot_count_log, + "duration-dot-count", 1, 0, 0, (SCM dur), + " +Extract the dot count from @var{dur}" +) +{ + SCM_ASSERT_TYPE(unsmob_duration(dur), dur, SCM_ARG1, __FUNCTION__, "duration"); + + return gh_int2scm (unsmob_duration (dur)->dot_count ()); +} + + +LY_DEFINE(ly_intlog2, + "intlog2", 1, 0, 0, (SCM d), + " +Extract the dot count from @var{dur}" +) +{ + SCM_ASSERT_TYPE(gh_number_p (d), d, SCM_ARG1, __FUNCTION__, "integer"); + + int l = intlog2 (gh_scm2int (d)); + + return gh_int2scm (l); +} + +LY_DEFINE(compression_factor, + "duration-factor", 1, 0, 0, (SCM dur), + " +Extract the compression factor from @var{dur}. Return as a pair." +) +{ + SCM_ASSERT_TYPE(unsmob_duration(dur), dur, SCM_ARG1, __FUNCTION__, "duration"); + Rational r =unsmob_duration (dur)->factor (); + + return gh_cons(gh_int2scm (r.num()),gh_int2scm (r.den ())); +} + SCM Duration::smobbed_copy ()const { diff --git a/lily/include/duration.hh b/lily/include/duration.hh index 49fe93e243..654db0db8b 100644 --- a/lily/include/duration.hh +++ b/lily/include/duration.hh @@ -26,8 +26,7 @@ public: Duration compressed (Rational) const; Rational length_mom () const ; - - + Rational factor () const { return factor_; } int duration_log ()const; int dot_count () const; @@ -36,7 +35,7 @@ public: SCM smobbed_copy () const; DECLARE_SCHEME_CALLBACK (less_p, (SCM a, SCM b)); DECLARE_SIMPLE_SMOBS (Duration,); - + private: /// Logarithm of the base duration. int durlog_i_; diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh index e383dcaa3c..efcde57b4f 100644 --- a/lily/include/musical-request.hh +++ b/lily/include/musical-request.hh @@ -37,9 +37,14 @@ public: struct Tremolo_req : public Request { VIRTUAL_COPY_CONS (Music); Tremolo_req (); +}; + +struct Chord_tremolo_notify_req : public Request +{ - void set_type (int); - int get_type () const; + Rational factor_; + VIRTUAL_COPY_CONS(Chord_tremolo_notify_req); + Chord_tremolo_notify_req(); }; diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index ed8b7be05a..f495cf9501 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -139,9 +139,8 @@ Mark_engraver::process_music () text_p_->set_grob_property ("text",m); else { - if (!gh_string_p (m)) + if (!gh_string_p (m) && !gh_number_p (m)) m = get_property ("rehearsalMark"); - ; if (gh_number_p (m)) { diff --git a/lily/music.cc b/lily/music.cc index db7b1f4d65..7b9e88a769 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -220,7 +220,7 @@ LY_DEFINE(ly_get_mus_property, "Get the property @var{sym} of music expression @var{mus}.") { Music * sc = unsmob_music (mus); - SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "grob"); + SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music"); SCM_ASSERT_TYPE(gh_symbol_p(sym), sym, SCM_ARG2, __FUNCTION__, "symbol"); return sc->internal_get_mus_property (sym); diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 7d48f15939..802c2278ed 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -136,8 +136,6 @@ Note_heads_engraver::stop_translation_timestep () void Note_heads_engraver::start_translation_timestep () { - - } diff --git a/lily/parser.yy b/lily/parser.yy index e7d9d6498a..f0aa450c82 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -301,7 +301,7 @@ yylex (YYSTYPE *s, void * v_l) %type chord_note chord_inversion chord_bass %type duration_length fraction -%type embedded_scm scalar +%type embedded_scm %type Music Sequential_music Simultaneous_music %type relative_music re_rhythmed_music part_combined_music %type property_def translator_change @@ -745,9 +745,22 @@ Repeated_music: SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor")); SCM result = gh_call1 (func, $2); + if (gh_equal_p ($2, ly_str02scm ("tremolo"))) + { + /* + we can not get durations and other stuff correct down the line, so we have to + add to the duration log here. + + TODO: do dots. + */ + SCM func = scm_primitive_eval (ly_symbol2scm ("shift-duration-log")); + gh_call2 (func, r->self_scm (), gh_int2scm(-intlog2 ($3))); + } + set_music_properties (r, result); r->set_spot (*$4->origin ()); + $$ = r; } ; @@ -1025,7 +1038,7 @@ translator_change: ; property_def: - PROPERTY STRING '.' STRING '=' scalar { + PROPERTY STRING '.' STRING '=' embedded_scm { Music *t = set_property_music (scm_string_to_symbol ($4), $6); Context_specced_music *csm = new Context_specced_music (SCM_EOL); @@ -1104,13 +1117,6 @@ property_def: } ; -scalar: - string { $$ = $1; } - | bare_int { $$ = gh_int2scm ($1); } - | embedded_scm { $$ = $1; } - ; - - request_chord: pre_requests { THIS->push_spot (); @@ -1304,11 +1310,17 @@ verbose_command_req: Mark_req * m = new Mark_req; $$ = m; } - | MARK scalar { + | MARK STRING { Mark_req *m = new Mark_req; m->set_mus_property ("label", $2); $$ = m; + } + | MARK bare_unsigned { + String s(to_str ($2)); + Mark_req *m = new Mark_req; + m->set_mus_property ("label", gh_int2scm ($2)); + $$ = m; } | PENALTY SCM_T { Break_req * b = new Break_req; diff --git a/lily/rest.cc b/lily/rest.cc index efd28765da..953fcf5449 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -21,7 +21,7 @@ Rest::after_line_breaking (SCM smob) { Grob *me = unsmob_grob (smob); int bt = gh_scm2int (me->get_grob_property ("duration-log")); - if (bt == 0) + if (bt == 0 && Staff_symbol_referencer::line_count (me) > 1) { me->translate_axis (Staff_symbol_referencer::staff_space (me) , Y_AXIS); } diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index 9aa5e5421d..fcb5d5c8dc 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -136,6 +136,7 @@ Spacing_engraver::stop_translation_timestep () { starter = starter string (ly-get-mus-property mus 'denominator)) )) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(define (shift-duration-log music shift ) + "Recurse through music, adding SHIFT to duration-log to any note +encountered. This scales the music up by a factor 2^k." + (let* ((es (ly-get-mus-property music 'elements)) + (e (ly-get-mus-property music 'element)) + (n (ly-music-name music)) + (f (lambda (x) (shift-duration-log x shift))) + ) + (if (or (equal? n "Note_req") + (equal? n "Rest_req")) + (let* ( + (d (ly-get-mus-property music 'duration)) + (cp (duration-factor d)) + (nd (make-duration (+ shift (duration-log d)) + (duration-dot-count d) + (car cp) + (cdr cp))) + + ) + (ly-set-mus-property music 'duration nd) + )) + + (if (pair? es) + (ly-set-mus-property + music 'elements + (map f es))) + + (if (music? e) + (ly-set-mus-property + music 'element + (f e))) + music)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (unfold-repeats music) " This function replaces all repeats with unfold repeats. It was @@ -18,6 +56,9 @@ written by Rune Zedeler. " (if (equal? n "Repeated_music") (begin + (if (equal? (ly-get-mus-property 'type music) 'tremolo) + (shift-duration-log music (- (intlog2 (ly-get-mus-property 'repeat-count music)))) + ) (ly-set-mus-property music 'length Repeated_music::unfolded_music_length) (ly-set-mus-property -- 2.39.5