source file of the GNU LilyPond music typesetter
- (c) 2004 Han-Wen Nienhuys
+ (c) 2004--2005 Han-Wen Nienhuys
*/
#include "context.hh"
#include "lily-guile.hh"
#include "warn.hh"
#include "music-iterator.hh"
-#include "interpretation-context-handle.hh"
class Part_combine_iterator : public Music_iterator
{
SCM split_list_;
enum Status {
- APART, TOGETHER,
- SOLO1, SOLO2,
- UNISONO, UNISILENCE,
+ APART,
+ TOGETHER,
+ SOLO1,
+ SOLO2,
+ UNISONO,
+ UNISILENCE,
};
Status state_;
Status playing_state_;
+ /*
+ Should be SOLO1 or SOLO2
+ */
+ Status last_playing_;
+
/*
TODO: this is getting of hand...
*/
};
+static Music *busy_playing_event;
+
+void
+Part_combine_iterator::do_quit ()
+{
+ if (first_iter_)
+ first_iter_->quit ();
+ if (second_iter_)
+ second_iter_->quit ();
+
+ null_.set_context (0);
+ one_ .set_context (0);
+ two_.set_context (0);
+ shared_.set_context (0);
+ solo_.set_context (0);
+
+}
+
Part_combine_iterator::Part_combine_iterator ()
{
first_iter_ = 0;
split_list_ = SCM_EOL;
state_ = APART;
playing_state_ = APART;
+
+ if (!busy_playing_event)
+ {
+ busy_playing_event
+ = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent"));
+ }
}
void
Context *t)
{
if (first_iter_)
- first_iter_->substitute_outlet (f,t);
- if (second_iter_)
- second_iter_->substitute_outlet (f,t);
-}
-
-void
-Part_combine_iterator::do_quit ()
-{
- if (first_iter_)
- first_iter_->quit ();
- if (second_iter_)
- second_iter_->quit ();
+ first_iter_->substitute_outlet (f, t);
- null_.set_translator (0);
- one_ .set_translator (0);
- two_.set_translator (0);
- shared_.set_translator (0);
- solo_.set_translator (0);
}
Moment
void
Part_combine_iterator::substitute_both (Context * to1,
- Context * to2)
+ Context * to2)
{
- Context *tos[] = {to1,to2};
+ Context *tos[] = {to1, to2};
Music_iterator *mis[] = {first_iter_, second_iter_};
Interpretation_context_handle *hs[] = {
&null_,
return;
else
{
- substitute_both (shared_.get_outlet (), null_.get_outlet ());
-
- kill_mmrest (two_.get_outlet ());
+ /*
+ If we're coming from SOLO2 state, we might have kill mmrests
+ in the 1st voice, so in that case, we use the second voice
+ as a basis for events.
+ */
+ Context *c1 = (last_playing_ == SOLO2) ? null_.get_outlet() : shared_.get_outlet();
+ Context *c2 = (last_playing_ == SOLO2) ? shared_.get_outlet() : null_.get_outlet();
+ substitute_both (c1, c2);
+ kill_mmrest ((last_playing_ == SOLO2)
+ ? one_.get_outlet () : two_.get_outlet ());
kill_mmrest (shared_.get_outlet ());
if (playing_state_ != UNISONO
if (!event)
event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
- first_iter_-> try_music_in_children (event);
+ (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
+ ->try_music_in_children (event);
playing_state_ = UNISONO;
}
state_ = newstate;
Context *tr
= get_outlet ()->find_create_context (ly_symbol2scm ("Voice"),
- "shared",props);
+ "shared", props);
- shared_.set_translator (tr);
+ shared_.set_context (tr);
/*
If we don't, we get a new staff for every Voice.
*/
- set_translator (tr);
+ set_context (tr);
Context *solo_tr
= get_outlet ()->find_create_context (ly_symbol2scm ("Voice"),
- "solo",props);
+ "solo", props);
- solo_ .set_translator (solo_tr);
+ solo_ .set_context (solo_tr);
Context *null
= get_outlet ()->find_create_context (ly_symbol2scm ("Devnull"),
if (!null)
programming_error ("No Devnull found?");
- null_.set_translator (null);
+ null_.set_context (null);
Context *one = tr->find_create_context (ly_symbol2scm ("Voice"),
"one", props);
- one_.set_translator (one);
+ one_.set_context (one);
- set_translator (one);
- first_iter_ = unsmob_iterator (get_iterator (unsmob_music (ly_car (lst))));
+ set_context (one);
+ first_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_car (lst))));
Context *two = tr->find_create_context (ly_symbol2scm ("Voice"),
"two", props);
- two_.set_translator (two);
- set_translator (two);
- second_iter_ = unsmob_iterator (get_iterator (unsmob_music (ly_cadr (lst))));
+ two_.set_context (two);
+ set_context (two);
+ second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
- set_translator (tr);
+ set_context (tr);
char const * syms[] = {
Moment now = get_outlet ()->now_mom ();
Moment *splitm = 0;
- for (; is_pair (split_list_); split_list_ = ly_cdr (split_list_))
+ for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_))
{
- splitm = unsmob_moment (ly_caar (split_list_));
+ splitm = unsmob_moment (scm_caar (split_list_));
if (splitm && *splitm + start_moment_ > now)
break ;
- SCM tag = ly_cdar (split_list_);
+ SCM tag = scm_cdar (split_list_);
if (tag == ly_symbol2scm ("chords"))
chords_together ();
solo1 ();
else if (tag == ly_symbol2scm ("solo2"))
solo2 ();
- else if (is_symbol (tag))
+ else if (scm_is_symbol (tag))
{
String s = "Unknown split directive: "
- + (is_symbol (tag) ? ly_symbol2string (tag) : String ("not a symbol"));
+ + (scm_is_symbol (tag) ? ly_symbol2string (tag) : String ("not a symbol"));
programming_error (s);
}
}
-
+
if (first_iter_->ok ())
- first_iter_->process (m);
+ {
+ first_iter_->process (m);
+ if (first_iter_->try_music_in_children (busy_playing_event))
+ last_playing_ = SOLO1;
+ }
if (second_iter_->ok ())
- second_iter_->process (m);
+ {
+ second_iter_->process (m);
+ if (first_iter_->try_music_in_children (busy_playing_event))
+ last_playing_ = SOLO2;
+ }
}
Music_iterator*