2 quote-iterator.cc -- implement New_quote_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
12 #include "music-sequence.hh"
13 #include "lily-guile.hh"
14 #include "music-wrapper-iterator.hh"
18 #include "interpretation-context-handle.hh"
20 class New_quote_iterator : public Music_wrapper_iterator
23 New_quote_iterator ();
24 Moment vector_moment (int idx) const;
25 Interpretation_context_handle quote_outlet_;
32 SCM transposed_musics_;
34 DECLARE_SCHEME_CALLBACK (constructor, ());
36 bool accept_music_type (Music*) const;
38 virtual void derived_mark () const;
39 virtual void construct_children ();
40 virtual Moment pending_moment () const;
41 virtual void process (Moment);
42 virtual bool ok () const;
46 New_quote_iterator::accept_music_type (Music *mus) const
48 SCM accept = get_outlet()->get_property ("quotedEventTypes");
49 for (SCM s = mus->get_property ("types");
50 scm_is_pair (s); s = scm_cdr (s))
52 if (scm_memq (scm_car (s), accept) != SCM_BOOL_F)
61 New_quote_iterator::derived_mark () const
63 scm_gc_mark (transposed_musics_ );
66 New_quote_iterator::New_quote_iterator ()
68 transposed_musics_ = SCM_EOL;
69 event_vector_ = SCM_EOL;
76 binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b))
79 int hi = SCM_VECTOR_LENGTH (vec);
84 int cmp = (lo + hi) / 2;
86 SCM when = scm_caar (SCM_VECTOR_REF (vec, cmp));
87 bool result = (*is_less) (key, when);
100 New_quote_iterator::construct_children ()
102 Music_wrapper_iterator::construct_children ();
104 SCM name = get_music ()->get_property ("quoted-context-type");
105 SCM id = get_music ()->get_property ("quoted-context-id");
107 Context *cue_context = get_outlet()->find_create_context (name,
108 ly_scm2string (id), SCM_EOL);
109 quote_outlet_.set_context (cue_context);
111 Moment now = get_outlet ()->now_mom ();
112 Moment stop = now + get_music()->get_length ();
115 event_vector_ = get_music ()->get_property ("quoted-events");
117 if (ly_c_vector_p (event_vector_))
119 event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
120 end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
124 get_music ()->origin()->warning (_("No events found for \\quote"));
130 New_quote_iterator::ok () const
133 Music_wrapper_iterator::ok()
134 && ly_c_vector_p (event_vector_) && (event_idx_ <= end_idx_);
138 New_quote_iterator::pending_moment () const
141 Music_wrapper_iterator::pending_moment()
143 vector_moment (event_idx_) - start_moment_;
147 New_quote_iterator::vector_moment (int idx) const
149 SCM entry = SCM_VECTOR_REF (event_vector_, idx);
150 return *unsmob_moment (scm_caar (entry));
155 New_quote_iterator::process (Moment m)
157 Music_wrapper_iterator::process (m);
160 while (event_idx_ <= end_idx_)
162 Moment em = vector_moment (event_idx_);
172 if (event_idx_ <= end_idx_)
174 SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
175 Pitch * quote_pitch = unsmob_pitch (scm_cdar (entry));
178 The pitch that sounds like central C
180 Pitch * me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition"));
182 for (SCM s = scm_cdr (entry); scm_is_pair (s); s = scm_cdr (s))
184 SCM ev_acc = scm_car (s);
186 Music * mus = unsmob_music (scm_car (ev_acc));
188 programming_error ("need music in quote.");
189 else if (accept_music_type (mus))
191 if (quote_pitch || me_pitch)
199 Pitch diff = pitch_interval (qp, mp);
201 SCM copy = ly_deep_mus_copy (mus->self_scm ());
202 mus = unsmob_music (copy);
204 transposed_musics_ = scm_cons (copy, transposed_musics_);
205 mus->transpose (diff);
208 bool b = quote_outlet_.get_outlet ()->try_music (mus);
210 mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name ()));
217 IMPLEMENT_CTOR_CALLBACK (New_quote_iterator);