From a736b537c32e3b07a22ebedf3eacfeb46c57be25 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 4 Feb 2004 15:00:15 +0000 Subject: [PATCH] * lily/parser.yy (part_combined_music): remove old PC cruft. * ly/engraver-init.ly: remove old PC cruft. * Documentation/user/refman.itely (The Lyrics context): note about extender lines. * scm/part-combiner.scm (determine-split-list): many bugfixes. * lily/new-part-combine-iterator.cc (kill_mmrest): new function. * input/regression/new-part-combine-solo-global.ly: new file. * scm/part-combiner.scm: rewrite. --- ChangeLog | 8 +- Documentation/user/refman.itely | 13 +- VERSION | 4 +- ...-part-combine-a2.ly => part-combine-a2.ly} | 0 ...-global.ly => part-combine-solo-global.ly} | 0 ...t-combine-solo.ly => part-combine-solo.ly} | 0 ...t-combine-text.ly => part-combine-text.ly} | 0 .../{new-part-combine.ly => part-combine.ly} | 0 lily/a2-engraver.cc | 215 -------- lily/include/part-combine-music-iterator.hh | 0 lily/my-lily-lexer.cc | 1 - lily/new-part-combine-iterator.cc | 1 - lily/parser.yy | 15 +- lily/part-combine-music-iterator.cc | 513 ------------------ lily/thread-devnull-engraver.cc | 58 -- lily/voice-devnull-engraver.cc | 116 ---- ly/engraver-init.ly | 6 - scm/define-music-types.scm | 10 - scm/define-translator-properties.scm | 35 +- scm/part-combiner.scm | 2 +- 20 files changed, 24 insertions(+), 973 deletions(-) rename input/regression/{new-part-combine-a2.ly => part-combine-a2.ly} (100%) rename input/regression/{new-part-combine-solo-global.ly => part-combine-solo-global.ly} (100%) rename input/regression/{new-part-combine-solo.ly => part-combine-solo.ly} (100%) rename input/regression/{new-part-combine-text.ly => part-combine-text.ly} (100%) rename input/regression/{new-part-combine.ly => part-combine.ly} (100%) delete mode 100644 lily/a2-engraver.cc delete mode 100644 lily/include/part-combine-music-iterator.hh delete mode 100644 lily/part-combine-music-iterator.cc delete mode 100644 lily/thread-devnull-engraver.cc delete mode 100644 lily/voice-devnull-engraver.cc diff --git a/ChangeLog b/ChangeLog index 527d4fdc26..13ff20532d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,13 @@ 2004-02-04 Han-Wen Nienhuys + * lily/parser.yy (part_combined_music): remove old PC cruft. + + * ly/engraver-init.ly: remove old + PC cruft. + + * Documentation/user/refman.itely (The Lyrics context): note about + extender lines. - * lily/multi-measure-rest-engraver.cc (process_music): extra check to allow 0-length mmrest events. diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index ccae49f6d6..ddebd09cf1 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -3435,7 +3435,9 @@ Internals: @internalsref{LyricEvent}, @internalsref{HyphenEvent}, and @refbugs -The definition of lyrics mode is too complex. +The definition of lyrics mode is too complex. + + @node The Lyrics context @subsection The Lyrics context @@ -3548,6 +3550,12 @@ Melismata are not detected automatically, and extender lines must be inserted by hand. +For proper processing of extender lines, the +@internalsref{LyricsVoice} and @internalsref{Voice} should be +linked. This can be achieved either by using @code{\lyricsto} or by +setting corresponding names for both contexts. The latter is explained +in @ref{More stanzas}. + @node More stanzas @subsection More stanzas @@ -3556,7 +3564,8 @@ inserted by hand. The lyrics should be aligned with the note heads of the melody. To achieve this, each line of lyrics should be marked to correspond with -the melodic line. +the melodic line. This is done automatically when @code{\lyricsto}, +but it can also be done manually. To this end, give the @internalsref{Voice} context an identity: @example diff --git a/VERSION b/VERSION index 3eb1608264..1c463fd07a 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=1 -PATCH_LEVEL=17 -MY_PATCH_LEVEL=hwn1 +PATCH_LEVEL=18 +MY_PATCH_LEVEL= diff --git a/input/regression/new-part-combine-a2.ly b/input/regression/part-combine-a2.ly similarity index 100% rename from input/regression/new-part-combine-a2.ly rename to input/regression/part-combine-a2.ly diff --git a/input/regression/new-part-combine-solo-global.ly b/input/regression/part-combine-solo-global.ly similarity index 100% rename from input/regression/new-part-combine-solo-global.ly rename to input/regression/part-combine-solo-global.ly diff --git a/input/regression/new-part-combine-solo.ly b/input/regression/part-combine-solo.ly similarity index 100% rename from input/regression/new-part-combine-solo.ly rename to input/regression/part-combine-solo.ly diff --git a/input/regression/new-part-combine-text.ly b/input/regression/part-combine-text.ly similarity index 100% rename from input/regression/new-part-combine-text.ly rename to input/regression/part-combine-text.ly diff --git a/input/regression/new-part-combine.ly b/input/regression/part-combine.ly similarity index 100% rename from input/regression/new-part-combine.ly rename to input/regression/part-combine.ly diff --git a/lily/a2-engraver.cc b/lily/a2-engraver.cc deleted file mode 100644 index e50fffae20..0000000000 --- a/lily/a2-engraver.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - a2-engraver.cc -- implement A2_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2000--2003 Jan Nieuwenhuizen -*/ - -#include "engraver.hh" -#include "item.hh" -#include "note-head.hh" -#include "stem.hh" -#include "slur.hh" -#include "translator-group.hh" -#include "side-position-interface.hh" -#include "directional-element-interface.hh" -#include "multi-measure-rest.hh" -#include "tie.hh" - -class A2_engraver : public Engraver -{ - TRANSLATOR_DECLARATIONS(A2_engraver); - -protected: - virtual void acknowledge_grob (Grob_info); - virtual void process_acknowledged_grobs (); - virtual void stop_translation_timestep (); -private: - Item* text_; - enum State { SOLO, SPLIT_INTERVAL, UNIRHYTHM, UNISILENCE, UNISON } state_; -}; - - - -A2_engraver::A2_engraver () -{ - text_ = 0; - state_ = UNISILENCE; -} - -void -A2_engraver::process_acknowledged_grobs () -{ - if (!to_boolean (get_property ("combineParts"))) - return ; - if (!text_) - { - SCM unison = get_property ("unison"); - SCM solo = get_property ("solo"); - SCM solo_adue = get_property ("soloADue"); - - if (solo_adue == SCM_BOOL_T - && ((solo == SCM_BOOL_T && state_ != SOLO) - || (unison == SCM_BOOL_T && state_ != UNISON - && daddy_trans_->id_string_.left_string (3) == "one"))) - { - text_ = make_item ("TextScript"); - Side_position_interface::set_axis (text_, Y_AXIS); - announce_grob(text_, SCM_EOL); - - Direction dir = UP; - SCM text = SCM_EOL; - if (solo == SCM_BOOL_T) - { - state_ = SOLO; - if (daddy_trans_->id_string_.left_string (3) == "one") - { - text = get_property ("soloText"); - } - else - { - text = get_property ("soloIIText"); - dir = DOWN; - } - } - else if (unison == SCM_BOOL_T) - { - state_ = UNISON; - if (daddy_trans_->id_string_.left_string (3) == "one") - text = get_property ("aDueText"); - } - - set_grob_direction (text_, dir); - text_->set_grob_property ("text", text); - } - } -} - -void -A2_engraver::acknowledge_grob (Grob_info i) -{ - if (!to_boolean (get_property ("combineParts"))) - return ; - - if (text_) - { - if (Note_head::has_interface (i.grob_)) - { - Grob*t = text_; - Side_position_interface::add_support (t, i.grob_); - if (Side_position_interface::get_axis (t) == X_AXIS - && !t->get_parent (Y_AXIS)) - t->set_parent (i.grob_, Y_AXIS); - } - if (Stem::has_interface (i.grob_)) - { - Side_position_interface::add_support (text_, i.grob_); - } - } - - SCM unisilence = get_property ("unisilence"); - SCM unison = get_property ("unison"); - SCM unirhythm = get_property ("unirhythm"); - SCM solo = get_property ("solo"); - SCM split_interval = get_property ("split-interval"); - SCM solo_adue = get_property ("soloADue"); - - State previous_state = state_; - if (unisilence == SCM_BOOL_T) - /* - state_ = UNISILENCE; - */ - ; - else if (solo == SCM_BOOL_T) - state_ = SOLO; - else if (unison == SCM_BOOL_T) - state_ = UNISON; - else if (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T) - state_ = SPLIT_INTERVAL; - else if (unirhythm) - state_ = UNIRHYTHM; - - Direction d = CENTER; - if (daddy_trans_->id_string_.left_string (3) == "one") - d = UP; - else if (daddy_trans_->id_string_.left_string (3) == "two") - d = DOWN; - - /* Must only set direction for VoiceCombines, not for StaffCombines: - we can't detect that here, so we use yet another property */ - if (!to_boolean (get_property ("noDirection")) - && (Stem::has_interface (i.grob_) - || Slur::has_interface (i.grob_) - || Tie::has_interface (i.grob_) - /* Usually, dynamics are removed by *_devnull_engravers for - the second voice. On the one hand, we don't want all - dynamics for the first voice to be placed above the - staff. On the other hand, colliding of scripts may be - worse. So, we don't set directions for these when we're - playing solo. */ - || (i.grob_->internal_has_interface (ly_symbol2scm - ("dynamic-interface")) - && state_ != SOLO) - || (i.grob_->internal_has_interface (ly_symbol2scm - ("text-interface")) - && state_ != SOLO) - )) - { - /* When in solo a due mode, and we have solo, every grob in - other thread gets annihilated, so we don't set dir. - - Maybe that should be optional? */ - if ((solo != SCM_BOOL_T && solo_adue == SCM_BOOL_T) - - /* When not same rhythm, we set dir */ - && (unirhythm != SCM_BOOL_T - /* When both have rests, but previously played something - different, we set dir */ - || ((unisilence == SCM_BOOL_T && previous_state != UNISON)) - /* When same rhythm, and split stems, but not same pitch - or not solo a du mode, we set dir */ - || (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T - && (unison != SCM_BOOL_T || solo_adue != SCM_BOOL_T)))) - { - - /* Blunt axe method: every grob gets a propertysetting. */ - i.grob_->set_grob_property ("direction", scm_int2num (d)); - } - } - - /* Should we have separate state variable for being "rest - while other has solo?" */ - if (Multi_measure_rest::has_interface (i.grob_) && d) - if (state_ == UNIRHYTHM - && unisilence != SCM_BOOL_T) - { - i.grob_->set_grob_property ("staff-position", scm_int2num (d * 6)); - } -} - -void -A2_engraver::stop_translation_timestep () -{ - if (text_) - { - typeset_grob (text_); - text_ = 0; - } -} - -ENTER_DESCRIPTION(A2_engraver, -/* descr */ "Part combine engraver for orchestral scores. " -"The markings @emph{a2}, @emph{Solo} and @emph{Solo II}, are " -"created by this engraver. It also acts upon instructions of the part " -"combiner. Another thing that the this engraver, is forcing of stem, " -"slur and tie directions, always when both threads are not identical; " -"up for the musicexpr called @code{one}, down for the musicexpr called " -"@code{two}. " -, -/* creats*/ "TextScript", -/* accepts */ "", -/* acks */ "multi-measure-rest-interface " -"slur-interface stem-interface tie-interface note-head-interface dynamic-interface text-interface" -,/* reads */ "combineParts noDirection soloADue soloText soloIIText aDueText split-interval unison solo unisilence unirhythm", -/* write */ ""); diff --git a/lily/include/part-combine-music-iterator.hh b/lily/include/part-combine-music-iterator.hh deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 9eead743d7..c2ee25616e 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -60,7 +60,6 @@ static Keyword_ent the_key_tab[]={ {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, - {"newpartcombine", NEWPARTCOMBINE}, {"notes", NOTES}, {"octave", OCTAVE}, {"once", ONCE}, diff --git a/lily/new-part-combine-iterator.cc b/lily/new-part-combine-iterator.cc index 37a978030a..872941f444 100644 --- a/lily/new-part-combine-iterator.cc +++ b/lily/new-part-combine-iterator.cc @@ -6,7 +6,6 @@ (c) 2004 Han-Wen Nienhuys */ -#include "part-combine-music-iterator.hh" #include "translator-group.hh" #include "event.hh" #include "music-sequence.hh" diff --git a/lily/parser.yy b/lily/parser.yy index 277365e90f..a611eebca9 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -283,7 +283,6 @@ yylex (YYSTYPE *s, void * v) %token OVERRIDE SET REVERT %token PAPER %token PARTCOMBINE -%token NEWPARTCOMBINE %token PARTIAL %token PITCHNAMES %token PROPERTY @@ -1114,20 +1113,10 @@ re_rhythmed_music: ; part_combined_music: - PARTCOMBINE STRING Music Music { - Music * p= MY_MAKE_MUSIC("PartCombineMusic"); - p->set_mus_property ("what", scm_string_to_symbol ($2)); - p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED)); - - scm_gc_unprotect_object ($3->self_scm ()); - scm_gc_unprotect_object ($4->self_scm ()); - - $$ = p; - } - | NEWPARTCOMBINE Music Music { + PARTCOMBINE Music Music { static SCM proc; if (!proc) - proc = scm_c_eval_string ("make-new-part-combine-music"); + proc = scm_c_eval_string ("make-part-combine-music"); SCM res = scm_call_1 (proc, gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED)); diff --git a/lily/part-combine-music-iterator.cc b/lily/part-combine-music-iterator.cc deleted file mode 100644 index 6ce902c4c8..0000000000 --- a/lily/part-combine-music-iterator.cc +++ /dev/null @@ -1,513 +0,0 @@ -/* - part-combine-music-iterator.cc -- implement Part_combine_music_iterator - - source file of the GNU LilyPond music typesetter - - (c) 2000--2003 Jan Nieuwenhuizen - */ - -#include "part-combine-music-iterator.hh" -#include "translator-group.hh" -#include "event.hh" -#include "music-sequence.hh" -#include "lily-guile.hh" -#include "warn.hh" -#include "music-iterator.hh" - -class Part_combine_music_iterator : public Music_iterator -{ -public: - VIRTUAL_COPY_CONS (Music_iterator); - Part_combine_music_iterator (); - - enum State { UNKNOWN, UNRELATED=1, SOLO1=2, SOLO2=4, UNIRHYTHM=8, UNISON=16, UNISILENCE=32, SPLIT_INTERVAL=64 }; - DECLARE_SCHEME_CALLBACK(constructor, ()); -protected: - virtual void derived_substitute (Translator_group*f, Translator_group*t) ; - - virtual void derived_mark () const; - Part_combine_music_iterator (Part_combine_music_iterator const &); - virtual void construct_children (); - virtual Moment pending_moment () const; - virtual void do_quit(); - virtual void process (Moment); - virtual SCM get_pending_events (Moment)const; - virtual Music_iterator *try_music_in_children (Music *) const; - virtual bool ok () const; - -private: - void change_to (Music_iterator*, SCM, String); - int get_state (Moment m); - - Music_iterator * first_iter_; - Music_iterator * second_iter_; - Moment first_until_; - Moment second_until_; - int state_; - String suffix_; -}; - - -Part_combine_music_iterator::Part_combine_music_iterator () -{ - first_iter_ = 0; - second_iter_ = 0; - first_until_ = 0; - second_until_ = 0; - state_ = 0; -} - -void -Part_combine_music_iterator::derived_mark () const -{ - if (first_iter_) - scm_gc_mark (first_iter_->self_scm()); - if (second_iter_) - scm_gc_mark(second_iter_->self_scm()); -} - -void -Part_combine_music_iterator::derived_substitute (Translator_group*f, - Translator_group*t) -{ - if (first_iter_) - first_iter_->substitute_outlet (f,t); - if (second_iter_) - second_iter_->substitute_outlet (f,t); -} - -void -Part_combine_music_iterator::do_quit () -{ - if (first_iter_) - first_iter_->quit(); - if (second_iter_) - second_iter_->quit(); -} - -Part_combine_music_iterator::Part_combine_music_iterator (Part_combine_music_iterator const &src) - : Music_iterator (src) -{ - first_iter_ = 0; - second_iter_ = 0; - - if(src.first_iter_) - first_iter_ = src.first_iter_->clone (); - if (src.second_iter_) - second_iter_ = src.second_iter_->clone (); - - first_until_ = src.first_until_; - second_until_ = src.second_until_; - state_ = src.state_; - suffix_ = src.suffix_; - - if (first_iter_) - scm_gc_unprotect_object (first_iter_->self_scm()); - if (second_iter_) - scm_gc_unprotect_object (second_iter_->self_scm()); -} - -Moment -Part_combine_music_iterator::pending_moment () const -{ - Moment p; - p.set_infinite (1); - if (first_iter_->ok ()) - p = p pending_moment (); - - if (second_iter_->ok ()) - p = p pending_moment (); - return p; -} - -bool -Part_combine_music_iterator::ok () const -{ - return first_iter_->ok () || second_iter_->ok (); -} - - -void -Part_combine_music_iterator::construct_children () -{ - SCM lst = get_music ()->get_mus_property ("elements"); - - first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst)))); - second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst)))); -} - -void -Part_combine_music_iterator::change_to (Music_iterator *it, SCM to_type, - String to_id) -{ - Translator_group * current = it->report_to (); - Translator_group * last = 0; - - /* - Cut & Paste from from Auto_change_iterator from Change_iterator (ugh). - - TODO: abstract this function - */ - - /* find the type of translator that we're changing. - - If \translator Staff = bass, then look for Staff = * - */ - while (current && !current->is_alias (to_type)) - { - last = current; - current = current->daddy_trans_; - } - - if (current && current->id_string_ == to_id) - { - String msg; - msg += _ ("Can't switch translators, I'm there already"); - } - - if (current) - if (last) - { - Translator_group * dest = - it->report_to ()->find_create_translator (to_type, to_id, SCM_EOL); - current->remove_translator (last); - dest->add_used_group_translator (last); - } - else - { - /* - We could change the current translator's id, but that would make - errors hard to catch - - last->translator_id_string_ = get_change ()->change_to_id_string_; - */ - error (_f ("I'm one myself: `%s'", ly_symbol2string (to_type).to_str0 ())); - } - else - error (_f ("none of these in my family: `%s'", to_id.to_str0 ())); -} - - -// SCM*, moet / kan dat niet met set_x ofzo? -static void -get_music_info (Moment m, Music_iterator* iter, SCM *pitches, SCM *durations) -{ - if (iter->ok ()) - { - for (SCM i = iter->get_pending_events (m); gh_pair_p (i); i = ly_cdr (i)) - { - Music *m = unsmob_music (ly_car (i)); - SCM p = m->get_mus_property ("pitch"); - SCM d = m->get_mus_property ("duration"); - if (unsmob_pitch (p)) - *pitches = gh_cons (p, *pitches); - if (unsmob_duration (d)) - *durations = gh_cons (d, *durations); - } - } -} - -int -Part_combine_music_iterator::get_state (Moment) -{ - int state = UNKNOWN; - - Music *p = get_music (); - - SCM w = p->get_mus_property ("what"); - - - Translator_group *first_translator = first_iter_->report_to ()->find_create_translator (w, "one" + suffix_, SCM_EOL); - - SCM s = first_translator->get_property ("changeMoment"); - if (!gh_pair_p (s)) - return state; - - Moment change_mom = *unsmob_moment (ly_car (s)); - Moment diff_mom = *unsmob_moment (ly_cdr (s)); - - Moment now = pending_moment (); - - if (!now.main_part_.mod_rat (change_mom.main_part_)) - { - SCM interval = SCM_BOOL_F; - if (first_until_ < now) - first_until_ = now; - if (second_until_ < now) - second_until_ = now; - - Moment first_mom = first_until_; - Moment second_mom = second_until_; - Moment diff_until = diff_mom + now; - - - bool first = true; - Music_iterator *first_iter = first_iter_->clone (); - Music_iterator *second_iter = second_iter_->clone (); - - Moment last_pending (-1); - Moment pending = now; - while (now < diff_until - && (first_iter->ok () || second_iter->ok ()) - - // urg, this is a hack, haven't caught this case yet - && (pending != last_pending)) - { - if (!second_iter->ok ()) - pending = first_iter->pending_moment (); - else if (!first_iter->ok ()) - pending = second_iter->pending_moment (); - else - pending = first_iter->pending_moment () pending_moment (); - last_pending = pending; - - SCM first_pitches = SCM_EOL; - SCM first_durations = SCM_EOL; - get_music_info (pending, first_iter, - &first_pitches, &first_durations); - - SCM second_pitches = SCM_EOL; - SCM second_durations = SCM_EOL; - get_music_info (pending, second_iter, - &second_pitches, &second_durations); - - if (first_pitches != SCM_EOL && second_pitches != SCM_EOL) - { - scm_sort_list_x (first_pitches, Pitch::less_p_proc); - scm_sort_list_x (second_pitches, Pitch::less_p_proc); - - interval = gh_int2scm (unsmob_pitch (ly_car (first_pitches))->steps () - - unsmob_pitch (ly_car (scm_last_pair (second_pitches)))->steps ()); - } - - if (first_durations != SCM_EOL) - { - scm_sort_list_x (first_durations, - Duration::less_p_proc); - first_mom += unsmob_duration (ly_car (first_durations))->get_length (); - } - - if (second_durations != SCM_EOL) - { - scm_sort_list_x (second_durations, - Duration::less_p_proc); - second_mom += unsmob_duration (ly_car (second_durations))->get_length (); - } - - if (first_pitches != SCM_EOL && second_pitches == SCM_EOL - && ! (second_until_ > now)) - { - state |= UNRELATED; - state &= ~UNISILENCE; - if (! (state & ~ (UNRELATED | SOLO1 | UNISILENCE))) - state |= SOLO1; - } - else - state &= ~SOLO1; - - if (first_pitches == SCM_EOL && second_pitches != SCM_EOL - && ! (first_until_ > now)) - { - state |= UNRELATED; - state &= ~UNISILENCE; - if (! (state & ~ (UNRELATED | SOLO2 | UNISILENCE))) - state |= SOLO2; - } - else - state &= ~SOLO2; - - if (gh_equal_p (first_durations, second_durations)) - { - state &= ~UNISILENCE; - if (! (state & ~ (UNIRHYTHM | UNISON))) - state |= UNIRHYTHM; - } - else - state &= ~ (UNIRHYTHM | UNISILENCE); - - if (first_pitches != SCM_EOL - && gh_equal_p (first_pitches, second_pitches)) - { - state &= ~UNISILENCE; - if (! (state & ~ (UNIRHYTHM | UNISON))) - state |= UNISON; - } - else - state &= ~ (UNISON); - - if (first_pitches == SCM_EOL && second_pitches == SCM_EOL) - { - if (! (state & ~ (UNIRHYTHM | UNISILENCE))) - state |= UNISILENCE; - } - else if (!state) - state |= UNRELATED; - else - state &= ~ (UNISILENCE); - - if (gh_number_p (interval)) - { - SCM s = first_translator->get_property ("splitInterval"); - int i = gh_scm2int (interval); - if (gh_pair_p (s) - && gh_number_p (ly_car (s)) - && gh_number_p (ly_cdr (s)) - && i >= gh_scm2int (ly_car (s)) - && i <= gh_scm2int (ly_cdr (s))) - { - if (! (state & ~ (SPLIT_INTERVAL | UNIRHYTHM | UNISON))) - state |= SPLIT_INTERVAL; - } - else - state &= ~ (SPLIT_INTERVAL); - } - - if (first && first_pitches != SCM_EOL) - first_until_ = first_mom; - if (first && second_pitches != SCM_EOL) - second_until_ = second_mom; - first = false; - - if (first_iter->ok ()) - first_iter->skip (pending); - if (second_iter->ok ()) - second_iter->skip (pending); - now = pending; - } - scm_gc_unprotect_object (first_iter->self_scm ()); - scm_gc_unprotect_object (second_iter->self_scm ()); - } - - return state; -} - -static Music* abort_req = NULL; - -void -Part_combine_music_iterator::process (Moment m) -{ - - /* - TODO: - - Use three named contexts (be it Thread or Voice): one, two, solo. - Let user pre-set (pushproperty) stem direction, remove - dynamic-engraver, and such. - - **** Tried this, but won't work: - -s Consider thread switching: threads "one", "two" and "both". - User can't pre-set the (most important) stem direction at - thread level! - */ - - if (suffix_.is_empty ()) - suffix_ = first_iter_->report_to () - ->daddy_trans_->id_string_.cut_string (3, INT_MAX); - - int state = get_state (m); - if (state) - state_ = state; - else - state = state_; - - Music *p =get_music (); - - - bool previously_combined_b = first_iter_->report_to ()->daddy_trans_ - == second_iter_->report_to ()->daddy_trans_; - - bool combine_b = previously_combined_b; - - if (! (state & UNIRHYTHM) - || (state & SPLIT_INTERVAL) - || (state & (SOLO1 | SOLO2))) - combine_b = false; - else if (state & (UNIRHYTHM | UNISILENCE)) - combine_b = true; - - /* - When combining, abort all running spanners - */ - - if (!abort_req) - { - abort_req = make_music_by_name (ly_symbol2scm ("AbortEvent")); - } - - if (combine_b && combine_b != previously_combined_b) - { - if (second_iter_ && second_iter_->ok ()) - second_iter_->try_music (abort_req); - } - SCM w = p->get_mus_property ("what"); - if (combine_b != previously_combined_b) - change_to (second_iter_, w, (combine_b ? "one" : "two") - + suffix_); - - Translator_group *first_translator = first_iter_->report_to ()->find_create_translator (w, "one" + suffix_, SCM_EOL); - Translator_group *second_translator = second_iter_->report_to ()->find_create_translator (w, "two" + suffix_, SCM_EOL); - - - /* Hmm */ - first_translator->set_property ("combineParts", SCM_BOOL_T); - second_translator ->set_property ("combineParts", SCM_BOOL_T); - - - /* hmm */ - SCM b = (state & UNIRHYTHM) ? SCM_BOOL_T : SCM_BOOL_F; - first_translator->set_property ("unirhythm", b); - second_translator->set_property ("unirhythm", b); - - b = (state & SPLIT_INTERVAL) ? SCM_BOOL_T : SCM_BOOL_F; - first_translator->set_property ("split-interval", b); - second_translator->set_property ("split-interval", b); - - b = (state & UNISILENCE) ? SCM_BOOL_T : SCM_BOOL_F; - first_translator->set_property ("unisilence", b); - second_translator->set_property ("unisilence", b); - - // difference in definition... - //b = ((state & UNISON) ? SCM_BOOL_T : SCM_BOOL_F; - b = ((state & UNISON) && (state & UNIRHYTHM)) ? SCM_BOOL_T : SCM_BOOL_F; - first_translator->set_property ("unison", b); - second_translator->set_property ("unison", b); - - SCM b1 = (state & SOLO1) ? SCM_BOOL_T : SCM_BOOL_F; - SCM b2 = (state & SOLO2) ? SCM_BOOL_T : SCM_BOOL_F; - first_translator->set_property ("solo", b1); - second_translator->set_property ("solo", b2); - - /* Can't these be computed? */ - first_translator->set_property ("othersolo", b2); - second_translator->set_property ("othersolo", b1); - - if (first_iter_->ok ()) - first_iter_->process (m); - - if (second_iter_->ok ()) - second_iter_->process (m); -} - -Music_iterator* -Part_combine_music_iterator::try_music_in_children (Music *m) const -{ - Music_iterator * i = first_iter_->try_music (m); - if (i) - return i; - else - return second_iter_->try_music (m); -} - - -SCM -Part_combine_music_iterator::get_pending_events (Moment m)const -{ - SCM s = SCM_EOL; - if (first_iter_) - s = gh_append2 (s,first_iter_->get_pending_events (m)); - if (second_iter_) - s = gh_append2 (second_iter_->get_pending_events (m),s); - return s; -} - -IMPLEMENT_CTOR_CALLBACK (Part_combine_music_iterator); diff --git a/lily/thread-devnull-engraver.cc b/lily/thread-devnull-engraver.cc deleted file mode 100644 index 442b9db1d4..0000000000 --- a/lily/thread-devnull-engraver.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - thread-devnull-engraver.cc -- implement Thread_devnull_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2000--2003 Jan Nieuwenhuizen -*/ - -#include "engraver.hh" -#include "item.hh" -#include "event.hh" -#include "translator-group.hh" - -class Thread_devnull_engraver : public Engraver -{ -public: - TRANSLATOR_DECLARATIONS(Thread_devnull_engraver); - -protected: - virtual void acknowledge_grob (Grob_info); -}; - - - -void -Thread_devnull_engraver::acknowledge_grob (Grob_info i) -{ - SCM s = get_property ("devNullThread"); - - if (s == ly_symbol2scm ("always") - || (s == SCM_EOL - && to_boolean (get_property ("soloADue")) - && ((daddy_trans_->id_string_.left_string (3) == "two" - && (to_boolean (get_property ("unison")) - || to_boolean (get_property ("unisilence")))) - - /* Maybe this should be optional? */ - || to_boolean (get_property ("othersolo"))))) - { - i.grob_->suicide (); - } -} -Thread_devnull_engraver::Thread_devnull_engraver(){} - -ENTER_DESCRIPTION(Thread_devnull_engraver, -/* descr */ "Kill elements whenever we are Voice called `two' and either " -"unison, unisilence or soloADue is set.@footnote{On unix systems, the " -"file @file{/dev/null} is special device: anything written to it is " -"discarded.}. This engraver works closely together with the part " -"combiner. When the part combiner notices that two threads are " -"identical, it tells the @code{Thread_devnull_engraver} to discard " -"everything in the second thread. " -, -/* creats*/ "", -/* accepts */ "", -/* acks */ "grob-interface", -/* reads */ "", -/* write */ ""); diff --git a/lily/voice-devnull-engraver.cc b/lily/voice-devnull-engraver.cc deleted file mode 100644 index 81e99a03ad..0000000000 --- a/lily/voice-devnull-engraver.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - voice-devnull-engraver.cc -- implement Voice_devnull_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2000--2003 Jan Nieuwenhuizen -*/ - -#include "engraver.hh" -#include "item.hh" -#include "event.hh" -#include "translator-group.hh" - -class Voice_devnull_engraver : public Engraver -{ -public: - TRANSLATOR_DECLARATIONS(Voice_devnull_engraver); - -protected: - virtual bool try_music (Music *m); - virtual void acknowledge_grob (Grob_info); -}; - - -/* - -ARGH . - - -This really sucks. - - */ -static char const *eat_spanners[] = { - "beam", - "crescendo", - "decrescendo", - "rest", - "slur", - 0 -}; - -bool -Voice_devnull_engraver::try_music (Music *m) -{ - SCM s = get_property ("devNullVoice"); - - if (gh_equal_p (s, ly_symbol2scm ("always")) - || (s == SCM_EOL - && daddy_trans_->id_string_.left_string (3) == "two" - && (to_boolean (get_property ("unison")) - || to_boolean (get_property ("unisilence"))))) - { - if (m->is_mus_type ("span-event")) - { - SCM t = m->get_mus_property ("span-type"); - - for (char const **p = eat_spanners; *p; p++) - { - if (t == scm_makfrom0str (*p)) - return true; - } - } - /* Ugh. Should eat other events, script etc. too. */ - else if (m->is_mus_type ("tie-event")) - return true; - } - return false; -} - -static char const *junk_interfaces[] = { - "beam-interface", - "dynamic-interface", - "hairpin-interface", - "multi-measure-rest-interface", - "script-interface", - "slur-interface", - "text-interface", - "text-item-interface", - "text-script-interface", - "text-spanner-interface", - "tie-interface", - 0 -}; - -void -Voice_devnull_engraver::acknowledge_grob (Grob_info i) -{ - SCM s = get_property ("devNullVoice"); - - if (s == ly_symbol2scm ("always") - || (s == SCM_EOL - && to_boolean (get_property ("soloADue")) - && ((daddy_trans_->id_string_.left_string (3) == "two" - && (to_boolean (get_property ("unison")) - || to_boolean (get_property ("unisilence")))) - - /* Maybe this should be optional? */ - || to_boolean (get_property ("othersolo"))))) - - for (char const **p = junk_interfaces; *p; p++) - if (i.grob_->internal_has_interface (ly_symbol2scm (*p))) - { - i.grob_->suicide (); - return; - } -} - -Voice_devnull_engraver::Voice_devnull_engraver(){} - -ENTER_DESCRIPTION(Voice_devnull_engraver, -/* descr */ "Kill off certain items and spanners if we're Voice `two' and unison or unisilence is set.", -/* creats*/ "", -/* accepts */ "general-music", /*UGH.*/ -/* acks */ "grob-interface", -/* reads */ "", -/* write */ ""); diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 47de3c9cf0..adaf969bd8 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -151,8 +151,6 @@ localKeySignature = #'() \consists "Font_size_engraver" - % must come before all - \consists "Voice_devnull_engraver" \consists "Output_property_engraver" \consists "Arpeggio_engraver" \consists "Multi_measure_rest_engraver" @@ -191,7 +189,6 @@ \consists "Slur_engraver" \consists "Tie_engraver" \consists "Tuplet_engraver" - \consists "A2_engraver" \consists "Skip_event_swallow_translator" \accepts Thread % bug if you leave out this! @@ -207,7 +204,6 @@ style of individual note heads. " \consists "Font_size_engraver" - \consists "Thread_devnull_engraver" \consists "Note_heads_engraver" \consists "Rest_engraver" @@ -442,8 +438,6 @@ AncientRemoveEmptyStaffContext = \translator { soloIIText = #"Solo II" aDueText = #"a2" soloADue = ##t - splitInterval = #'(0 . 1) - changeMoment = #`(,(ly:make-moment 0 0) . ,(ly:make-moment 1 512)) systemStartDelimiter =#'SystemStartBar melismaBusyProperties = #default-melisma-properties diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index c845f602cb..6b31bd7524 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -301,21 +301,11 @@ SYNTAX (types . (general-music layout-instruction)) (iterator-ctor . , Push_property_iterator::constructor) )) - (PartCombineMusic . ( (description . "Combine two parts on a staff, either merged or as separate voices.") - (internal-class-name . "Simultaneous_music") - (types . (general-music part-combine-music)) - (iterator-ctor . ,Part_combine_music_iterator::constructor) - )) - (NewPartCombineMusic - . ( - (description . "Combine two parts on a staff, either merged or -as separate voices.") - (internal-class-name . "Simultaneous_music") (types . (general-music part-combine-music)) (iterator-ctor . ,New_pc_iterator::constructor) diff --git a/scm/define-translator-properties.scm b/scm/define-translator-properties.scm index d8e8eb70a3..617a51fa26 100644 --- a/scm/define-translator-properties.scm +++ b/scm/define-translator-properties.scm @@ -149,13 +149,6 @@ Use at your own risk. This property contains the grobs for which END-MOMENT >= the central C, measured in half staffspaces. Usually determined by looking at clefPosition and clefGlyph.") -(translator-property-description - 'changeMoment moment-pair? - "duration that voices are examined for differences, when -part-combining. Usually unset or zero when combining threads into one -voice, and 1 (or the duration of one measure) when combining voices -into one staff.") - (translator-property-description 'chordNameFunction procedure? "The function that converts lists of pitches to chord names.") @@ -189,7 +182,6 @@ stafflines, the value 0 puts the clef on the middle staffline; a positive value shifts it up, a negative value shifts it down. The unit of this distance is the half staff space.") -(translator-property-description 'combineParts boolean? "try to combine parts?") (translator-property-description 'connectArpeggios boolean? " If set, connect all arpeggios that are found. In this way, you can make arpeggios that cross staves. @@ -209,26 +201,7 @@ This variable is typically read at Score level, so overriding Staff.defaultBarType will have no effect. ") -(translator-property-description 'devNullThread symbol? "User control of Thread_devnull_engraver: one of -@table @samp -@item (), or unset -Behave in normal way: remove one set of grobs when in unisolo. -@item always: -Remove any grob that comes along. -@item never: -Do nothing. -@end table -") -(translator-property-description 'devNullVoice symbol? "User control of Voice_devnull_engraver: one of -@table @samp -@item (), or unset -Behave in normal way: remove spanners when in unisolo. -@item always: -Remove any spanners that come along. -@item never: -Do nothing. -@end table -") + (translator-property-description 'decrescendoSpanner symbol? "Type of spanner to be used for decrescendi. One of: @samp{hairpin}, @samp{line}, @samp{dashed-line}, @samp{dotted-line}. If unset, hairpin type is used.") (translator-property-description 'dynamicAbsoluteVolumeFunction procedure? " @@ -348,7 +321,6 @@ this function is called with current context and a list of music objects. The list of contains entries with start times, music objects and whether they're processed in this context.") -(translator-property-description 'noDirection boolean? "Don't set directions by a2-engraver when part-combining.") (translator-property-description 'originalCentralCPosition integer? "Used for temporary overriding central C in octavation brackets. ") @@ -403,8 +375,6 @@ help with debugging large scores.") (translator-property-description 'soloIIText string? "text for begin of solo for voice ``two'' when part-combining.") (translator-property-description 'soloText string? "text for begin of solo when part-combining.") (translator-property-description 'sparseTies boolean? "only create one tie per chord.") -(translator-property-description 'splitInterval number-pair? "part-combiner will separate its two voices (or threads) when interval between the two voices is contained in this range.") -(translator-property-description 'split-interval boolean? "set if part-combiner separated voices based on splitInterval.") (translator-property-description 'squashedPosition integer? " Vertical position of squashing for Pitch_squash_engraver.") (translator-property-description 'stringOneTopmost boolean? "Whether the 1st string is printed on the @@ -463,9 +433,6 @@ context Voice imes 2/3 @{ @@end lilypond @end example .") -(translator-property-description 'unirhythm boolean? "set if unirhythm is detected by the part combiner.") -(translator-property-description 'unisilence boolean? "set if unisilence is detected by the part combiner.") -(translator-property-description 'unison boolean? "set if unisono is detected by the part combiner. .") (translator-property-description 'verticalAlignmentChildCallback procedure? "what callback to add to children of a vertical alignment. It determines what alignment procedure is used on the alignment diff --git a/scm/part-combiner.scm b/scm/part-combiner.scm index 5730a7e005..3d3c796cf2 100644 --- a/scm/part-combiner.scm +++ b/scm/part-combiner.scm @@ -257,7 +257,7 @@ Voice-state objects (define-public (make-new-part-combine-music music-list) (let* - ((m (make-music-by-name 'NewPartCombineMusic)) + ((m (make-music-by-name 'PartCombineMusic)) (m1 (context-spec-music (car music-list) 'Voice "one")) (m2 (context-spec-music (cadr music-list) 'Voice "two")) (props '((denies Thread) -- 2.39.2