/*
- new-part-combine-music-iterator.cc -- implement New_pc_iterator
+ new-part-combine-music-iterator.cc -- implement New_pc_iterator
- source file of the GNU LilyPond music typesetter
+ source file of the GNU LilyPond music typesetter
- (c) 2004 Han-Wen Nienhuys
- */
+ (c) 2004 Han-Wen Nienhuys
+*/
#include "part-combine-music-iterator.hh"
#include "translator-group.hh"
private:
Music_iterator * first_iter_;
Music_iterator * second_iter_;
- bool is_shared_ ;
+
SCM split_list_;
+ enum Status {
+ APART, TOGETHER,
+ SOLO1, SOLO2,
+ UNISONO, UNISILENCE,
+ };
+ Status state_;
+ Status playing_state_;
+
Interpretation_context_handle one_;
Interpretation_context_handle two_;
+ Interpretation_context_handle null_;
Interpretation_context_handle shared_;
- void together ();
- void apart ();
+ void chords_together ();
+ void solo1 ();
+ void solo2 ();
+ void apart (bool silent);
+ void unisono (bool silent);
};
New_pc_iterator::New_pc_iterator ()
{
- is_shared_ =false;
first_iter_ = 0;
second_iter_ = 0;
split_list_ = SCM_EOL;
+ state_ = APART;
+ playing_state_ = APART;
}
void
void
New_pc_iterator::derived_substitute (Translator_group*f,
- Translator_group*t)
+ Translator_group*t)
{
if (first_iter_)
first_iter_->substitute_outlet (f,t);
}
void
-New_pc_iterator::together ()
+New_pc_iterator::chords_together ()
{
- first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
- second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+ if (state_ == TOGETHER)
+ return;
+ else
+ {
+ playing_state_ = TOGETHER;
+ state_ = TOGETHER;
+ first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+ first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+ second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+ second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+ }
}
+
void
-New_pc_iterator::apart ()
+New_pc_iterator::solo1 ()
{
- first_iter_->substitute_outlet (shared_.report_to (),one_.report_to ());
- second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());
+ if (state_ == SOLO1)
+ return;
+ else
+ {
+ state_ = SOLO1;
+ first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+ first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+
+ second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
+ second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+
+ if (playing_state_ != SOLO1)
+ {
+ static Music* event;
+ if (!event)
+ event = make_music_by_name (ly_symbol2scm ("SoloOneEvent"));
+
+ first_iter_-> try_music_in_children (event);
+ }
+ playing_state_ = SOLO1;
+ }
}
+void
+New_pc_iterator::unisono (bool silent)
+{
+ Status newstate = (silent) ? UNISILENCE : UNISONO;
+
+ if (newstate == state_)
+ return;
+ else
+ {
+
+ first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+ first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+ second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
+ second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+
+ if (playing_state_ != UNISONO
+ && newstate == UNISONO)
+ {
+ static Music* event;
+ if (!event)
+ event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
+
+ first_iter_-> try_music_in_children (event);
+ playing_state_ = UNISONO;
+ }
+ state_ = newstate;
+ }
+}
+
+void
+New_pc_iterator::solo2 ()
+{
+ if (state_ == SOLO2)
+ return;
+ else
+ {
+ state_ = SOLO2;
+
+ second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+ second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+
+ first_iter_->substitute_outlet (one_.report_to (), null_.report_to ());
+ first_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+
+ if (playing_state_ != SOLO2)
+ {
+ static Music* event;
+ if (!event)
+ event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent"));
+
+ second_iter_-> try_music_in_children (event);
+ playing_state_ = SOLO2;
+ }
+ }
+}
+
+void
+New_pc_iterator::apart (bool silent)
+{
+ if (!silent)
+ playing_state_ = APART;
+
+ if (state_ == APART)
+ return;
+ else
+ {
+ state_ = APART;
+
+ first_iter_->substitute_outlet (null_.report_to (), one_.report_to ());
+ first_iter_->substitute_outlet (shared_.report_to (), one_.report_to ());
+
+ second_iter_->substitute_outlet (null_.report_to (), two_.report_to ());
+ second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ()); }
+}
void
New_pc_iterator::construct_children ()
split_list_ = get_music ()->get_mus_property ("split-list");
SCM lst = get_music ()->get_mus_property ("elements");
+ SCM props = scm_list_n (scm_list_n (ly_symbol2scm ("denies"), ly_symbol2scm ("Thread"), SCM_UNDEFINED),
+ scm_list_n (ly_symbol2scm ("consists"), ly_symbol2scm ("Rest_engraver"), SCM_UNDEFINED),
+ scm_list_n (ly_symbol2scm ("consists"), ly_symbol2scm ("Note_heads_engraver"), SCM_UNDEFINED),
+ SCM_UNDEFINED);
+
Translator_group *tr
= report_to ()->find_create_translator (ly_symbol2scm ("Voice"),
- "shared", SCM_EOL);
+ "shared",props);
- tr->execute_pushpop_property (ly_symbol2scm ("NoteHead"),
- ly_symbol2scm ("font-size"), gh_int2scm (3));
-
-
shared_ .set_translator (tr);
set_translator (tr);
+ Translator_group *null
+ = report_to ()->find_create_translator (ly_symbol2scm ("Devnull"),
+ "", SCM_EOL);
+
+ if (!null)
+ programming_error ("No Devnull found?");
+
+ null_.set_translator (null);
Translator_group *one = tr->find_create_translator (ly_symbol2scm ("Voice"),
- "one", SCM_EOL);
+ "one", props);
one_.set_translator (one);
- one->execute_pushpop_property (ly_symbol2scm ("Stem"),
- ly_symbol2scm ("direction"), gh_int2scm (1));
set_translator (one);
first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst))));
Translator_group *two = tr->find_create_translator (ly_symbol2scm ("Voice"),
- "two", SCM_EOL);
+ "two", props);
two_.set_translator (two);
- two_.report_to ()->execute_pushpop_property (ly_symbol2scm ("Stem"),
- ly_symbol2scm ("direction"), gh_int2scm (-1));
set_translator (two);
second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst))));
set_translator (tr);
+
+
+ char const * syms[] = {
+ "Stem",
+ "DynamicLineSpanner",
+ "Tie",
+ "Dots",
+ "Slur",
+ "TextScript",
+ "Script",
+ 0
+ };
+
+ for (char const**p = syms; *p; p++)
+ {
+ SCM sym = ly_symbol2scm (*p);
+ one->execute_pushpop_property (sym,
+ ly_symbol2scm ("direction"), gh_int2scm (1));
+
+ two->execute_pushpop_property (sym,
+ ly_symbol2scm ("direction"), gh_int2scm (-1));
+ }
+
}
void
if (*splitm > now)
break ;
- if (gh_cdar (split_list_) == ly_symbol2scm ("together"))
- together ();
- else if (gh_cdar (split_list_) == ly_symbol2scm ("apart"))
- apart ();
+ SCM tag = gh_cdar (split_list_);
+
+ if (tag == ly_symbol2scm ("chords"))
+ chords_together ();
+ else if (tag == ly_symbol2scm ("apart")
+ || tag == ly_symbol2scm ("apart-silence")
+ || tag == ly_symbol2scm ("apart-spanner"))
+ apart (tag == ly_symbol2scm ("apart-silence"));
+ else if (tag == ly_symbol2scm ("unisono"))
+ unisono (false);
+ else if (tag == ly_symbol2scm ("unisilence"))
+ unisono (true);
+ else if (tag == ly_symbol2scm ("solo1"))
+ solo1 ();
+ else if (tag == ly_symbol2scm ("solo2"))
+ solo2 ();
else
- programming_error ("Unknown split directive.");
+ {
+ String s = "Unknown split directive: "
+ + (gh_symbol_p (tag) ? ly_symbol2string (tag) : String ("not a symbol"));
+ programming_error (s);
+ }
}
if (first_iter_->ok ())