2 quote-iterator.cc -- implement 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-iterator.hh"
20 class Quote_iterator : public Music_iterator
24 Moment vector_moment (int idx) const;
31 SCM transposed_musics_;
33 DECLARE_SCHEME_CALLBACK (constructor, ());
35 bool accept_music_type (Music*) const;
37 virtual void derived_mark () const;
38 virtual void construct_children ();
39 virtual Moment pending_moment () const;
40 virtual void process (Moment);
41 virtual bool ok () const;
45 Quote_iterator::accept_music_type (Music *mus) const
47 SCM accept = get_outlet()->get_property ("quotedEventTypes");
48 for (SCM s = mus->get_property ("types");
49 scm_is_pair (s); s = scm_cdr (s))
51 if (scm_memq (scm_car (s), accept) != SCM_BOOL_F)
60 Quote_iterator::derived_mark () const
62 scm_gc_mark (transposed_musics_ );
65 Quote_iterator::Quote_iterator ()
67 transposed_musics_ = SCM_EOL;
68 event_vector_ = SCM_EOL;
74 moment_less (SCM a, SCM b)
76 return *unsmob_moment (a) < *unsmob_moment (b);
81 binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b))
84 int hi = SCM_VECTOR_LENGTH (vec);
89 int cmp = (lo + hi) / 2;
91 SCM when = scm_caar (SCM_VECTOR_REF (vec, cmp));
92 bool result = (*is_less) (key, when);
105 Quote_iterator::construct_children ()
107 SCM dur = get_music ()->get_property ("duration");
108 if (!unsmob_duration (dur))
111 set_translator (get_outlet ()->get_default_interpreter ());
113 Moment now = get_outlet ()->now_mom ();
114 Moment stop = now + unsmob_duration (dur)->get_length ();
117 event_vector_ = get_music ()->get_property ("quoted-events");
119 if (ly_c_vector_p (event_vector_))
121 event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
122 end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
126 get_music ()->origin()->warning (_("No events found for \\quote"));
132 Quote_iterator::ok () const
134 return ly_c_vector_p (event_vector_) && (event_idx_ <= end_idx_);
138 Quote_iterator::pending_moment () const
140 return vector_moment (event_idx_) - start_moment_;
144 Quote_iterator::vector_moment (int idx) const
146 SCM entry = SCM_VECTOR_REF (event_vector_, idx);
147 return *unsmob_moment (scm_caar (entry));
152 Quote_iterator::process (Moment m)
155 while (event_idx_ <= end_idx_)
157 Moment em = vector_moment (event_idx_);
167 if (event_idx_ <= end_idx_)
169 SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
170 Pitch * quote_pitch = unsmob_pitch (scm_cdar (entry));
173 The pitch that sounds like central C
175 Pitch * me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition"));
177 for (SCM s = scm_cdr (entry); scm_is_pair (s); s = scm_cdr (s))
179 SCM ev_acc = scm_car (s);
181 Music * mus = unsmob_music (scm_car (ev_acc));
183 programming_error ("need music in quote.");
184 else if (accept_music_type (mus))
186 if (quote_pitch || me_pitch)
194 Pitch diff = pitch_interval (qp, mp);
196 SCM copy = ly_deep_mus_copy (mus->self_scm ());
197 mus = unsmob_music (copy);
198 transposed_musics_ = scm_cons (copy, transposed_musics_);
201 mus->transpose (diff);
205 bool b = get_outlet ()->try_music (mus);
208 mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name ()));
215 IMPLEMENT_CTOR_CALLBACK (Quote_iterator);