/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2004--2010 Han-Wen Nienhuys
+ Copyright (C) 2004--2011 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
#include "music-sequence.hh"
#include "warn.hh"
-typedef enum Outlet_type
+enum Outlet_type
{
CONTEXT_ONE, CONTEXT_TWO,
CONTEXT_SHARED, CONTEXT_SOLO,
CONTEXT_NULL, NUM_OUTLETS
};
-static const char *outlet_names_[NUM_OUTLETS] =
+static const char *outlet_names_[NUM_OUTLETS] =
{"one", "two", "shared", "solo", "null"};
class Part_combine_iterator : public Music_iterator
DECLARE_LISTENER (set_busy);
bool busy_;
bool notice_busy_;
-
+
bool try_process (Music_iterator *i, Moment m);
-
+
Music_iterator *first_iter_;
Music_iterator *second_iter_;
Moment start_moment_;
SCM split_list_;
- Stream_event *unisono_event_;
+ Stream_event *unisono_event_;
Stream_event *solo_one_event_;
Stream_event *solo_two_event_;
- Stream_event *mmrest_event_;
-
+ Stream_event *mmrest_event_;
+
enum Status
{
APART,
split_list_ = SCM_EOL;
state_ = APART;
playing_state_ = APART;
+
+ busy_ = false;
+ notice_busy_ = false;
}
void
return first_iter_->ok () || second_iter_->ok ();
}
-void
-Part_combine_iterator::chords_together ()
-{
- if (state_ == TOGETHER)
- return;
- else
- {
- playing_state_ = TOGETHER;
- state_ = TOGETHER;
-
- substitute_both (CONTEXT_SHARED, CONTEXT_SHARED);
- }
-}
-
-void
-Part_combine_iterator::kill_mmrest (int in)
-{
-
- if (!mmrest_event_)
- {
- mmrest_event_ = new Stream_event (ly_symbol2scm ("multi-measure-rest-event"));
- mmrest_event_->set_property ("duration", SCM_EOL);
- mmrest_event_->unprotect ();
- }
-
- handles_[in].get_outlet ()->event_source ()->broadcast (mmrest_event_);
-}
-
-void
-Part_combine_iterator::solo1 ()
-{
- if (state_ == SOLO1)
- return;
- else
- {
- state_ = SOLO1;
- substitute_both (CONTEXT_SOLO, CONTEXT_NULL);
-
- kill_mmrest (CONTEXT_TWO);
- kill_mmrest (CONTEXT_SHARED);
-
- if (playing_state_ != SOLO1)
- {
- if (!solo_one_event_)
- {
- solo_one_event_ = new Stream_event (ly_symbol2scm ("solo-one-event"));
- solo_one_event_->unprotect ();
- }
-
- first_iter_->get_outlet ()->event_source ()->broadcast (solo_one_event_);
- }
- playing_state_ = SOLO1;
- }
-}
-
void
Part_combine_iterator::substitute_both (Outlet_type to1,
Outlet_type to2)
}
}
+void
+Part_combine_iterator::kill_mmrest (int in)
+{
+
+ if (!mmrest_event_)
+ {
+ mmrest_event_ = new Stream_event (ly_symbol2scm ("multi-measure-rest-event"));
+ mmrest_event_->set_property ("duration", SCM_EOL);
+ mmrest_event_->unprotect ();
+ }
+
+ handles_[in].get_outlet ()->event_source ()->broadcast (mmrest_event_);
+}
+
void
Part_combine_iterator::unisono (bool silent)
{
unisono_event_ = new Stream_event (ly_symbol2scm ("unisono-event"));
unisono_event_->unprotect ();
}
-
+
Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
->get_outlet ();
}
}
+void
+Part_combine_iterator::solo1 ()
+{
+ if (state_ == SOLO1)
+ return;
+ else
+ {
+ state_ = SOLO1;
+ substitute_both (CONTEXT_SOLO, CONTEXT_NULL);
+
+ kill_mmrest (CONTEXT_TWO);
+ kill_mmrest (CONTEXT_SHARED);
+
+ if (playing_state_ != SOLO1)
+ {
+ if (!solo_one_event_)
+ {
+ solo_one_event_ = new Stream_event (ly_symbol2scm ("solo-one-event"));
+ solo_one_event_->unprotect ();
+ }
+
+ first_iter_->get_outlet ()->event_source ()->broadcast (solo_one_event_);
+ }
+ playing_state_ = SOLO1;
+ }
+}
+
void
Part_combine_iterator::solo2 ()
{
solo_two_event_ = new Stream_event (ly_symbol2scm ("solo-two-event"));
solo_two_event_->unprotect ();
}
-
+
second_iter_->get_outlet ()->event_source ()->broadcast (solo_two_event_);
playing_state_ = SOLO2;
}
}
}
+void
+Part_combine_iterator::chords_together ()
+{
+ if (state_ == TOGETHER)
+ return;
+ else
+ {
+ playing_state_ = TOGETHER;
+ state_ = TOGETHER;
+
+ substitute_both (CONTEXT_SHARED, CONTEXT_SHARED);
+ }
+}
+
void
Part_combine_iterator::apart (bool silent)
{
set_context (two);
second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
+
+ /* Mimic all settings of voiceOne/voiceTwo for the two separate voices...*/
+ /* FIXME: Is there any way to use the definition of \voiceOne/\voiceTwo
+ directly??? */
char const *syms[]
= {
"Stem",
execute_pushpop_property (two, sym,
ly_symbol2scm ("direction"), scm_from_int (-1));
}
+ /* Handle horizontal shifts for crossing notes */
+ execute_pushpop_property (one, ly_symbol2scm ("NoteColumn"),
+ ly_symbol2scm ("horizontal-shift"), scm_from_int (0));
+ execute_pushpop_property (two, ly_symbol2scm ("NoteColumn"),
+ ly_symbol2scm ("horizontal-shift"), scm_from_int (1));
+ /* 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));
+
}
IMPLEMENT_LISTENER (Part_combine_iterator, set_busy);
notice_busy_ = true;
i->process (m);
-
+
notice_busy_ = false;
return busy_;
}