/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2004--2012 Han-Wen Nienhuys
+ Copyright (C) 2004--2015 Han-Wen Nienhuys
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
{
APART,
TOGETHER,
- SOLO1,
- SOLO2,
+ SOLO,
UNISONO,
UNISILENCE,
};
Status state_;
- Status playing_state_;
- /*
- Should be SOLO1 or SOLO2
- */
- Status last_playing_;
+ // For states in which it matters, this is the relevant part,
+ // e.g. 1 for Solo I, 2 for Solo II.
+ int chosen_part_;
+
+ // States for generating partcombine text.
+ enum PlayingState
+ {
+ PLAYING_OTHER,
+ PLAYING_UNISONO,
+ PLAYING_SOLO1,
+ PLAYING_SOLO2,
+ } playing_state_;
+
+ int last_playing_;
/*
TODO: this is getting off hand...
void solo1 ();
void solo2 ();
void apart (bool silent);
- void unisono (bool silent);
+ void unisono (bool silent, int newpart);
};
void
horizontalShiftOne_ = scm_from_int (0);
horizontalShiftTwo_ = scm_from_int (1);
state_ = APART;
- playing_state_ = APART;
- last_playing_ = APART;
+ chosen_part_ = 1;
+ playing_state_ = PLAYING_OTHER;
+ last_playing_ = 0;
busy_ = false;
notice_busy_ = false;
}
void
-Part_combine_iterator::unisono (bool silent)
+Part_combine_iterator::unisono (bool silent, int newpart)
{
Status newstate = (silent) ? UNISILENCE : UNISONO;
- if (newstate == state_)
+ if ((newstate == state_) and (newpart == chosen_part_))
return;
else
{
- /*
- 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.
- */
- Outlet_type c1 = (last_playing_ == SOLO2) ? CONTEXT_NULL : CONTEXT_SHARED;
- Outlet_type c2 = (last_playing_ == SOLO2) ? CONTEXT_SHARED : CONTEXT_NULL;
+ Outlet_type c1 = (newpart == 2) ? CONTEXT_NULL : CONTEXT_SHARED;
+ Outlet_type c2 = (newpart == 2) ? CONTEXT_SHARED : CONTEXT_NULL;
substitute_both (c1, c2);
- kill_mmrest ((last_playing_ == SOLO2) ? CONTEXT_ONE : CONTEXT_TWO);
+ kill_mmrest ((newpart == 2) ? CONTEXT_ONE : CONTEXT_TWO);
kill_mmrest (CONTEXT_SHARED);
- if (playing_state_ != UNISONO
+ if (playing_state_ != PLAYING_UNISONO
&& newstate == UNISONO)
{
if (!unisono_event_)
unisono_event_->unprotect ();
}
- Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
+ Context *out = (newpart == 2 ? second_iter_ : first_iter_)
->get_outlet ();
out->event_source ()->broadcast (unisono_event_);
- playing_state_ = UNISONO;
+ playing_state_ = PLAYING_UNISONO;
}
state_ = newstate;
+ chosen_part_ = newpart;
}
}
void
Part_combine_iterator::solo1 ()
{
- if (state_ == SOLO1)
+ if ((state_ == SOLO) && (chosen_part_ == 1))
return;
else
{
- state_ = SOLO1;
+ state_ = SOLO;
+ chosen_part_ = 1;
substitute_both (CONTEXT_SOLO, CONTEXT_NULL);
kill_mmrest (CONTEXT_TWO);
kill_mmrest (CONTEXT_SHARED);
- if (playing_state_ != SOLO1)
+ if (playing_state_ != PLAYING_SOLO1)
{
if (!solo_one_event_)
{
first_iter_->get_outlet ()->event_source ()->broadcast (solo_one_event_);
}
- playing_state_ = SOLO1;
+ playing_state_ = PLAYING_SOLO1;
}
}
void
Part_combine_iterator::solo2 ()
{
- if (state_ == SOLO2)
+ if ((state_ == SOLO) and (chosen_part_ == 2))
return;
else
{
- state_ = SOLO2;
-
+ state_ = SOLO;
+ chosen_part_ = 2;
substitute_both (CONTEXT_NULL, CONTEXT_SOLO);
- if (playing_state_ != SOLO2)
+ if (playing_state_ != PLAYING_SOLO2)
{
if (!solo_two_event_)
{
}
second_iter_->get_outlet ()->event_source ()->broadcast (solo_two_event_);
- playing_state_ = SOLO2;
+ playing_state_ = PLAYING_SOLO2;
}
}
}
return;
else
{
- playing_state_ = TOGETHER;
+ playing_state_ = PLAYING_OTHER;
state_ = TOGETHER;
substitute_both (CONTEXT_SHARED, CONTEXT_SHARED);
Part_combine_iterator::apart (bool silent)
{
if (!silent)
- playing_state_ = APART;
+ playing_state_ = PLAYING_OTHER;
if (state_ == APART)
return;
SCM lst = get_music ()->get_property ("elements");
Context *one = handles_[CONTEXT_ONE].get_context ();
set_context (one);
- first_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_car (lst))));
+ first_iter_ = Music_iterator::unsmob (get_iterator (Music::unsmob (scm_car (lst))));
Context *two = handles_[CONTEXT_TWO].get_context ();
set_context (two);
- second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
+ second_iter_ = Music_iterator::unsmob (get_iterator (Music::unsmob (scm_cadr (lst))));
Context *shared = handles_[CONTEXT_SHARED].get_context ();
set_context (shared);
"DynamicLineSpanner",
"Tie",
"Dots",
+ "MultiMeasureRest",
"Rest",
"Slur",
"TextScript",
ly_symbol2scm ("horizontal-shift"), horizontalShiftOne_);
execute_pushpop_property (two, ly_symbol2scm ("NoteColumn"),
ly_symbol2scm ("horizontal-shift"), horizontalShiftTwo_);
- /* Also handle MultiMeasureRest positions for voice 1/2 */
- execute_pushpop_property (one, ly_symbol2scm ("MultiMeasureRest"),
- ly_symbol2scm ("staff-position"), scm_from_int (4));
- execute_pushpop_property (two, ly_symbol2scm ("MultiMeasureRest"),
- ly_symbol2scm ("staff-position"), scm_from_int (-4));
}
if (!notice_busy_)
return;
- Stream_event *e = unsmob_stream_event (se);
+ Stream_event *e = Stream_event::unsmob (se);
if (e->in_event_class ("note-event") || e->in_event_class ("cluster-note-event"))
busy_ = true;
for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_))
{
- splitm = unsmob_moment (scm_caar (split_list_));
+ splitm = Moment::unsmob (scm_caar (split_list_));
if (splitm && *splitm + start_moment_ > now)
break;
|| tag == ly_symbol2scm ("apart-spanner"))
apart (tag == ly_symbol2scm ("apart-silence"));
else if (tag == ly_symbol2scm ("unisono"))
- unisono (false);
+ {
+ // Continue to use the most recently used part because we might have
+ // killed mmrests in the other part.
+ unisono (false, (last_playing_ == 2) ? 2 : 1);
+ }
else if (tag == ly_symbol2scm ("unisilence"))
- unisono (true);
+ {
+ // as for unisono
+ unisono (true, (last_playing_ == 2) ? 2 : 1);
+ }
+ else if (tag == ly_symbol2scm ("silence1"))
+ unisono (true, 1);
+ else if (tag == ly_symbol2scm ("silence2"))
+ unisono (true, 2);
else if (tag == ly_symbol2scm ("solo1"))
solo1 ();
else if (tag == ly_symbol2scm ("solo2"))
if (first_iter_->ok ())
{
if (try_process (first_iter_, m))
- last_playing_ = SOLO1;
+ last_playing_ = 1;
}
if (second_iter_->ok ())
{
if (try_process (second_iter_, m))
- last_playing_ = SOLO2;
+ last_playing_ = 2;
}
}