X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fquote-iterator.cc;h=de3993b3eff4e47384fd1b161e416844330c06d8;hb=f61bd6a69dec63300c68fc9455bd54d6a6067696;hp=0dc72104854192d25f9d84cf80fec49302307f0f;hpb=304b5f3aa7eee7b0ff8d4ba7526a1410735f6e74;p=lilypond.git diff --git a/lily/quote-iterator.cc b/lily/quote-iterator.cc index 0dc7210485..de3993b3ef 100644 --- a/lily/quote-iterator.cc +++ b/lily/quote-iterator.cc @@ -11,18 +11,18 @@ #include "event.hh" #include "music-sequence.hh" #include "lily-guile.hh" -#include "music-iterator.hh" -#include "music.hh" -#include "input.hh" +#include "music-wrapper-iterator.hh" #include "warn.hh" - -class Quote_iterator : public Music_iterator +class Quote_iterator : public Music_wrapper_iterator { public: Quote_iterator (); - + Moment vector_moment (int idx) const; + Interpretation_context_handle quote_outlet_; + Moment start_moment_; + Moment stop_moment_; SCM event_vector_; int event_idx_; int end_idx_ ; @@ -30,49 +30,58 @@ public: SCM transposed_musics_; DECLARE_SCHEME_CALLBACK (constructor, ()); - + bool quote_ok () const; + bool accept_music_type (Music*) const; protected: - virtual void derived_mark (); + virtual void derived_mark () const; virtual void construct_children (); virtual Moment pending_moment () const; virtual void process (Moment); virtual bool ok () const; }; +bool +Quote_iterator::accept_music_type (Music *mus) const +{ + SCM accept = get_outlet()->get_property ("quotedEventTypes"); + for (SCM s = mus->get_property ("types"); + scm_is_pair (s); s = scm_cdr (s)) + { + if (scm_memq (scm_car (s), accept) != SCM_BOOL_F) + return true; + } + + return false; +} + + void -Quote_iterator::derived_mark () +Quote_iterator::derived_mark () const { scm_gc_mark (transposed_musics_ ); } Quote_iterator::Quote_iterator () { + transposed_musics_ = SCM_EOL; event_vector_ = SCM_EOL; event_idx_ = 0; end_idx_ = 0; } -bool -moment_less (SCM a, SCM b) -{ - return *unsmob_moment (a) < *unsmob_moment (b); -} - int binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b)) { - int lo; - int hi; - lo = 0; - hi = SCM_VECTOR_LENGTH (vec); + int lo = 0; + int hi = SCM_VECTOR_LENGTH (vec); /* binary search */ do { int cmp = (lo + hi) / 2; - SCM when = gh_caar (SCM_VECTOR_REF (vec, cmp)); + SCM when = scm_caar (SCM_VECTOR_REF (vec, cmp)); bool result = (*is_less) (key, when); if (result) hi = cmp; @@ -88,53 +97,110 @@ binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b)) void Quote_iterator::construct_children () { - SCM dur = get_music ()->get_property ("duration"); - if (!unsmob_duration (dur)) - return ; - - set_translator (get_outlet ()->get_default_interpreter ()); - - Moment now = get_outlet ()->now_mom (); - Moment stop = now + unsmob_duration (dur)->get_length (); + Music_wrapper_iterator::construct_children (); - start_moment_ = now; - event_vector_ = get_music ()->get_property ("quoted-events"); + SCM name = get_music ()->get_property ("quoted-context-type"); + SCM id = get_music ()->get_property ("quoted-context-id"); - if (gh_vector_p (event_vector_)) + if (scm_is_string (id) + && scm_is_symbol (name)) + { + Context *cue_context = get_outlet()->find_create_context (name, + ly_scm2string (id), SCM_EOL); + quote_outlet_.set_context (cue_context); + } + else { - event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less); - end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less); + quote_outlet_.set_context (get_outlet ()); } + + + event_vector_ = get_music ()->get_property ("quoted-events"); + + /* + We have to delay initting event_idx_ , since we have to + take starting grace notes into account. Those may offset + event_idx_. + */ + event_idx_ = -1; } bool Quote_iterator::ok () const { - return (event_idx_ <= end_idx_); + return + Music_wrapper_iterator::ok() + || quote_ok (); } +bool +Quote_iterator::quote_ok () const +{ + return (event_idx_ >= 0 + && ly_c_vector_p (event_vector_) + && event_idx_ <= end_idx_ + + /* + Don't quote the grace notes leading to an unquoted note. + */ + && vector_moment (event_idx_).main_part_ < stop_moment_.main_part_ + ); +} Moment Quote_iterator::pending_moment () const { - SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_); - return *unsmob_moment (gh_caar (entry)) - start_moment_; + Rational infty; + infty.set_infinite (1); + Moment m (infty); + + if (Music_wrapper_iterator::ok()) + m = m now_mom ().smobbed_copy (), + &moment_less); + start_moment_ = get_outlet ()->now_mom () - music_start_mom(); + stop_moment_ = start_moment_ + get_music()->get_length (); + + end_idx_ = binsearch_scm_vector (event_vector_, + stop_moment_.smobbed_copy (), + &moment_less); + } + m += start_moment_; - while (event_idx_ < end_idx_) + while (event_idx_ <= end_idx_) { - entry = SCM_VECTOR_REF (event_vector_, event_idx_); - - Moment em = *unsmob_moment (gh_caar (entry)); - + Moment em = vector_moment (event_idx_); if (em > m) return ; @@ -144,18 +210,24 @@ Quote_iterator::process (Moment m) event_idx_++; } - if (gh_pair_p (entry)) + if (quote_ok ()) { - Pitch * quote_pitch = unsmob_pitch (gh_cdar (entry)); + SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_); + Pitch * quote_pitch = unsmob_pitch (scm_cdar (entry)); + + /* + The pitch that sounds like central C + */ Pitch * me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition")); - for (SCM s = gh_cdr (entry); gh_pair_p (s); s = gh_cdr (s)) + for (SCM s = scm_cdr (entry); scm_is_pair (s); s = scm_cdr (s)) { - SCM ev_acc = gh_car (s); + SCM ev_acc = scm_car (s); - - Music * mus = unsmob_music (gh_car (ev_acc)); - if (mus) + Music * mus = unsmob_music (scm_car (ev_acc)); + if (!mus) + programming_error ("need music in quote."); + else if (accept_music_type (mus)) { if (quote_pitch || me_pitch) { @@ -165,26 +237,23 @@ Quote_iterator::process (Moment m) if (me_pitch) mp = *me_pitch; - Pitch diff = interval (mp, qp); + Pitch diff = pitch_interval (qp, mp); - SCM copy = ly_deep_mus_copy (mus->self_scm ()); + SCM copy = ly_music_deep_copy (mus->self_scm ()); mus = unsmob_music (copy); - transposed_musics_ = gh_cons (copy, transposed_musics_); + transposed_musics_ = scm_cons (copy, transposed_musics_); mus->transpose (diff); } - - bool b = get_outlet ()->try_music (mus); - + bool b = quote_outlet_.get_outlet ()->try_music (mus); if (!b) mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name ())); } - else - programming_error ("need music in quote."); } + + event_idx_ ++; } - event_idx_ ++; } IMPLEMENT_CTOR_CALLBACK (Quote_iterator);