X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpart-combine-iterator.cc;h=adbc2beb32d18f1e01848c3400d79939eaacc9df;hb=4084f5affb220e6de38399e5e016be9759521045;hp=2a85da80375a877b3d7fb4990c487cbc7b6fac4f;hpb=68f8545bd6a0221ee1100336e4ad49399a7ffaa4;p=lilypond.git diff --git a/lily/part-combine-iterator.cc b/lily/part-combine-iterator.cc index 2a85da8037..adbc2beb32 100644 --- a/lily/part-combine-iterator.cc +++ b/lily/part-combine-iterator.cc @@ -1,26 +1,38 @@ /* - new-part-combine-music-iterator.cc -- implement Part_combine_iterator + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2004--2011 Han-Wen Nienhuys - (c) 2004--2006 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "context.hh" #include "dispatcher.hh" #include "lily-guile.hh" -#include "listener.hh" #include "music.hh" #include "music-iterator.hh" #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 + 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 @@ -32,7 +44,6 @@ public: protected: virtual void derived_substitute (Context *f, Context *t); virtual void derived_mark () const; - Part_combine_iterator (Part_combine_iterator const &); virtual void construct_children (); virtual Moment pending_moment () const; @@ -46,15 +57,20 @@ private: 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 *solo_one_event_; + Stream_event *solo_two_event_; + Stream_event *mmrest_event_; + enum Status { APART, @@ -109,11 +125,19 @@ Part_combine_iterator::do_quit () Part_combine_iterator::Part_combine_iterator () { + mmrest_event_ = 0; + unisono_event_ = 0; + solo_two_event_ = 0; + solo_one_event_= 0; + first_iter_ = 0; second_iter_ = 0; split_list_ = SCM_EOL; state_ = APART; playing_state_ = APART; + + busy_ = false; + notice_busy_ = false; } void @@ -123,6 +147,17 @@ Part_combine_iterator::derived_mark () const scm_gc_mark (first_iter_->self_scm ()); if (second_iter_) scm_gc_mark (second_iter_->self_scm ()); + + Stream_event *ptrs[] = { + unisono_event_, + mmrest_event_, + solo_two_event_, + solo_one_event_, + 0 + }; + for (int i = 0; ptrs[i]; i++) + if (ptrs[i]) + scm_gc_mark (ptrs[i]->self_scm ()); } void @@ -152,58 +187,6 @@ Part_combine_iterator::ok () const 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) -{ - static Stream_event *mmrest; - if (!mmrest) - { - mmrest = new Stream_event (ly_symbol2scm ("multi-measure-rest-event")); - mmrest->set_property ("duration", SCM_EOL); - } - - handles_[in].get_outlet ()->event_source ()->broadcast (mmrest); -} - -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) - { - static Stream_event *event; - if (!event) - event = new Stream_event (ly_symbol2scm ("solo1-event")); - - first_iter_->get_outlet ()->event_source ()->broadcast (event); - } - playing_state_ = SOLO1; - } -} - void Part_combine_iterator::substitute_both (Outlet_type to1, Outlet_type to2) @@ -226,6 +209,20 @@ Part_combine_iterator::substitute_both (Outlet_type to1, } } +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) { @@ -250,20 +247,49 @@ Part_combine_iterator::unisono (bool silent) if (playing_state_ != UNISONO && newstate == UNISONO) { - static Stream_event *event; - if (!event) - event = new Stream_event (ly_symbol2scm ("unisono-event")); + if (!unisono_event_) + { + unisono_event_ = new Stream_event (ly_symbol2scm ("unisono-event")); + unisono_event_->unprotect (); + } Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_) ->get_outlet (); - out->event_source ()->broadcast (event); + out->event_source ()->broadcast (unisono_event_); playing_state_ = UNISONO; } state_ = newstate; } } +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 () { @@ -277,16 +303,32 @@ Part_combine_iterator::solo2 () if (playing_state_ != SOLO2) { - static Stream_event *event; - if (!event) - event = new Stream_event (ly_symbol2scm ("solo2-event")); + if (!solo_two_event_) + { + solo_two_event_ = new Stream_event (ly_symbol2scm ("solo-two-event")); + solo_two_event_->unprotect (); + } - second_iter_->get_outlet ()->event_source ()->broadcast (event); + 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) { @@ -328,6 +370,10 @@ Part_combine_iterator::construct_children () 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", @@ -350,6 +396,17 @@ Part_combine_iterator::construct_children () 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); @@ -366,7 +423,8 @@ Part_combine_iterator::set_busy (SCM se) } /* -* Processes a moment in an iterator, and returns whether any new music was reported. + Processes a moment in an iterator, and returns whether any new music + was reported. */ bool Part_combine_iterator::try_process (Music_iterator *i, Moment m) @@ -375,7 +433,7 @@ Part_combine_iterator::try_process (Music_iterator *i, Moment m) notice_busy_ = true; i->process (m); - + notice_busy_ = false; return busy_; }