From: Han-Wen Nienhuys Date: Mon, 8 Jan 2007 12:34:15 +0000 (+0100) Subject: Fix #129, #228, #7 X-Git-Tag: release/2.11.10-1~3 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=7b5eff9b8de6992d309a959c13425aa91fb7d3a6;p=lilypond.git Fix #129, #228, #7 Store length property in generated tuplet start event. Simplify Time_scaled_music_iterator. --- diff --git a/THANKS b/THANKS index c15d646d2b..5b0def30cf 100644 --- a/THANKS +++ b/THANKS @@ -23,6 +23,7 @@ Mike Amundsen BUG HUNTERS/SUGGESTIONS +Alard de Boer Bertalan Fodor Benjamin Drung Cameron Horsburgh diff --git a/input/regression/part-combine-tuplet-end.ly b/input/regression/part-combine-tuplet-end.ly new file mode 100644 index 0000000000..b6bf5978d1 --- /dev/null +++ b/input/regression/part-combine-tuplet-end.ly @@ -0,0 +1,19 @@ +\header { + + texidoc = "End tuplets events are sent to the starting context, so +even after a switch, a tuplet ends correctly." + +} + +\version "2.10.8" + +\new Staff << + \partcombine + \relative c'' { + r2 + \times 2/3 { g8[ g g] } + \times 2/3 { g[ g g] } g1 + } + \relative c'' { R1 g1 } +>> + diff --git a/input/regression/part-combine-tuplet-single.ly b/input/regression/part-combine-tuplet-single.ly new file mode 100644 index 0000000000..879e163d69 --- /dev/null +++ b/input/regression/part-combine-tuplet-single.ly @@ -0,0 +1,22 @@ + +\header { + texidoc = "Tuplets in combined parts only print one bracket." + } + +\paper { ragged-right = ##T } + +\version "2.10.10" + +\score { + << + \new Staff { + \partcombine + \relative c'' { + \times 2/3 { d4 d d ~ } d2 + } + \relative c'' { + \times 2/3 { b4 a g ~ } g2 + } + } + >> +} diff --git a/input/regression/part-combine-tuplet.ly b/input/regression/part-combine-tuplet.ly deleted file mode 100644 index b6bf5978d1..0000000000 --- a/input/regression/part-combine-tuplet.ly +++ /dev/null @@ -1,19 +0,0 @@ -\header { - - texidoc = "End tuplets events are sent to the starting context, so -even after a switch, a tuplet ends correctly." - -} - -\version "2.10.8" - -\new Staff << - \partcombine - \relative c'' { - r2 - \times 2/3 { g8[ g g] } - \times 2/3 { g[ g g] } g1 - } - \relative c'' { R1 g1 } ->> - diff --git a/input/regression/quote-tuplet-end.ly b/input/regression/quote-tuplet-end.ly new file mode 100644 index 0000000000..cbf4752d1f --- /dev/null +++ b/input/regression/quote-tuplet-end.ly @@ -0,0 +1,22 @@ +\header +{ + texidoc ="Tuplet bracket ends properly when quoting." +} + +\version "2.11.10" + +\paper { ragged-right = ##t } + +\addQuote x { + \times 2/3 { a'8 a' a' } a'4 a'2 | +} + +\new Staff << + \set Staff.quotedEventTypes = #'(note-event tuplet-span-event) + \new Voice = "cue" { s1 } + \new Voice { + \cueDuring #"x" #1 { r4 } + c'4 + \cueDuring #"x" #1 { r2 } + } +>> diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index 973a1d8c5e..ca33ea7867 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -12,6 +12,7 @@ #include "international.hh" #include "music.hh" #include "music-wrapper-iterator.hh" +#include "stream-event.hh" /* Iterates \times, by sending TupletSpanEvents at the start/end of each @@ -30,6 +31,9 @@ protected: virtual void construct_children (); virtual void derived_mark () const; virtual Moment pending_moment () const; + + Music *create_event (Direction d); + private: /* tupletSpannerDuration */ @@ -39,34 +43,47 @@ private: Moment next_split_mom_; /* Recycle start/stop events if tupletSpannerDuration is set. */ - Music *start_; - Music *stop_; - - bool done_first_; + SCM synthesized_events_; Context_handle tuplet_handler_; }; +Music* +Time_scaled_music_iterator::create_event (Direction d) +{ + SCM ev_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), + ly_symbol2scm ("TupletSpanEvent"), + scm_from_int (d)); + + Music *mus = get_music (); + + Music *ev = unsmob_music (ev_scm); + ev->set_spot (*mus->origin ()); + if (d == START) + { + ev->set_property ("numerator", mus->get_property ("numerator")); + ev->set_property ("denominator", mus->get_property ("denominator")); + ev->set_property ("tweaks", mus->get_property ("tweaks")); + ev->set_property ("length", spanner_duration_.smobbed_copy ()); + } + + synthesized_events_ = scm_cons (ev_scm, synthesized_events_); + return ev; +} + + Time_scaled_music_iterator::Time_scaled_music_iterator () { spanner_duration_ = next_split_mom_ = 0; - done_first_ = 0; + synthesized_events_ = SCM_EOL; } Moment Time_scaled_music_iterator::pending_moment () const { - if (!done_first_) - return Moment (0); - Moment next_mom = Music_wrapper_iterator::pending_moment (); - - if (spanner_duration_.to_bool () && - next_mom.main_part_ > next_split_mom_) - { - next_mom = next_split_mom_; - } + next_mom = min (next_mom, next_split_mom_); return next_mom; } @@ -75,75 +92,44 @@ Time_scaled_music_iterator::pending_moment () const void Time_scaled_music_iterator::process (Moment m) { - if (!done_first_) - { - done_first_ = true; - descend_to_bottom_context (); - report_event (start_); - tuplet_handler_.set_context (get_outlet()); - } - if (spanner_duration_.to_bool () && m.main_part_ == next_split_mom_) { descend_to_bottom_context (); - stop_->send_to_context (tuplet_handler_.get_outlet ()); - - tuplet_handler_.set_context (get_outlet ()); - report_event (start_); + if (tuplet_handler_.get_outlet()) + create_event (STOP)->send_to_context (tuplet_handler_.get_outlet ()); + + if (m.main_part_ < music_get_length ().main_part_) + { + tuplet_handler_.set_context (get_outlet ()); + report_event (create_event (START)); - next_split_mom_ += spanner_duration_; - /* avoid sending events twice at the end */ - if (next_split_mom_ == get_music ()->get_length ().main_part_) - next_split_mom_.set_infinite (1); + next_split_mom_ += spanner_duration_; + } + else + { + tuplet_handler_.set_context (0); + } } - Music_wrapper_iterator::process(m); if (child_iter_ && child_iter_->ok ()) descend_to_child (child_iter_->get_outlet ()); - if (m.main_part_ == music_get_length ().main_part_) - { - stop_->send_to_context (tuplet_handler_.get_outlet ()); - tuplet_handler_.set_context (0); - } } void Time_scaled_music_iterator::construct_children () { - /* - Inheritance trickery: - Time_scaled_music_iterator::construct_children initialises start_ - and stop_, and calls Sequential_music::construct_children, which - in turn calls Time_scaled_music_iterator::get_music which reads - start_ and stop_. - */ - - Music *mus = get_music (); - Input *origin = mus->origin (); - - SCM tuplet_symbol = ly_symbol2scm ("TupletSpanEvent"); - SCM start_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START)); - start_ = unsmob_music (start_scm); - start_->set_spot (*origin); - start_->set_property ("numerator", mus->get_property ("numerator")); - start_->set_property ("denominator", mus->get_property ("denominator")); - start_->set_property ("tweaks", mus->get_property ("tweaks")); - - - SCM stop_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP)); - stop_ = unsmob_music (stop_scm); - stop_->set_spot (*origin); - Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration")); - if (mp) { spanner_duration_ = mp->main_part_; - next_split_mom_ = spanner_duration_; } - + else + { + spanner_duration_ = music_get_length (); + } + Music_wrapper_iterator::construct_children (); if (child_iter_ && child_iter_->ok ()) @@ -153,11 +139,7 @@ Time_scaled_music_iterator::construct_children () void Time_scaled_music_iterator::derived_mark () const { - if (start_) - scm_gc_mark (start_->self_scm ()); - if (stop_) - scm_gc_mark (stop_->self_scm ()); - + scm_gc_mark (synthesized_events_); Music_wrapper_iterator::derived_mark (); } diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index fd280e127e..3d904ac765 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -15,6 +15,7 @@ #include "tuplet-bracket.hh" #include "warn.hh" #include "item.hh" +#include "moment.hh" #include "translator.icc" @@ -26,6 +27,9 @@ struct Tuplet_description bool full_length_; bool full_length_note_; + Moment stop_moment_; + Moment start_moment_; + Moment length_; Tuplet_description () { @@ -64,21 +68,51 @@ Tuplet_engraver::listen_tuplet_span (Stream_event *ev) { Tuplet_description d; d.event_ = ev; + + d.length_ = robust_scm2moment (d.event_->get_property ("length"), + Moment (0)); + d.start_moment_ = now_mom (); + d.stop_moment_ = now_mom () + d.length_; + + for (vsize i=0; i < new_tuplets_.size (); i++) + { + /* + discard duplicates. + */ + if (new_tuplets_[i].stop_moment_ == d.stop_moment_) + return; + } + new_tuplets_.push_back (d); } - else if (dir == STOP && tuplets_.size ()) + else if (dir == STOP) + { + if (tuplets_.size ()) { stopped_tuplets_.push_back (tuplets_.back ()); tuplets_.pop_back (); } + else + ev->origin ()->warning (_f ("No tuplet to end")); + } else - programming_error (_f ("direction of %s invalid: %d", - "tuplet-span-event", int (dir))); + ev->origin ()->programming_error ("direction tuplet-span-event_ invalid."); } void Tuplet_engraver::process_music () { + /* + This may happen if the end of a tuplet is part of a quoted voice. + */ + Moment now = now_mom(); + for (vsize i = tuplets_.size (); i --; ) + { + stopped_tuplets_.push_back (tuplets_[i]); + if (tuplets_[i].stop_moment_ == now) + tuplets_.erase (tuplets_.begin () + i); + } + for (vsize i = 0; i < stopped_tuplets_.size (); i++) { Spanner *bracket = stopped_tuplets_[i].bracket_; @@ -102,6 +136,7 @@ Tuplet_engraver::process_music () number->set_bound (RIGHT, stopped_tuplets_[i].bracket_->get_bound (LEFT)); } + // todo: scrap last_tuplets_, use stopped_tuplets_ only. // clear stopped_tuplets_ at start_translation_timestep last_tuplets_.push_back (bracket); @@ -131,6 +166,8 @@ Tuplet_engraver::process_music () tuplets_[i].event_->self_scm ()); tuplets_[i].number_->set_object ("bracket", tuplets_[i].bracket_->self_scm ()); tuplets_[i].bracket_->set_object ("tuplet-number", tuplets_[i].number_->self_scm ()); + tuplets_[i].stop_moment_.grace_part_ = 0; + if (i < tuplets_.size () - 1 && tuplets_[i + 1].bracket_) Tuplet_bracket::add_tuplet_bracket (tuplets_[i].bracket_, tuplets_[i + 1].bracket_);