From b480b873c8cc686765c1f188be696636c2018adc Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Tue, 3 Feb 2004 01:06:08 +0000 Subject: [PATCH] * scm/music-functions.scm (determine-split-list): further analysis. * lily/script-engraver.cc (try_music): discard duplicate articulations. * input/regression/new-part-combine-solo.ly: new file * input/regression/new-part-combine-a2.ly: new file. * ly/performer-init.ly: add Devnull * scripts/convert-ly.py (FatalConversionError.sub_acc): add rule for \musicglyph #"accidental-*" (conv): \newpartcombine rule. --- ChangeLog | 19 +++++ VERSION | 2 +- input/regression/new-part-combine-a2.ly | 16 ++++ input/regression/new-part-combine-solo.ly | 22 ++++++ input/regression/new-part-combine-text.ly | 3 +- lily/new-part-combine-iterator.cc | 92 +++++++++++++++-------- lily/script-engraver.cc | 11 +++ ly/performer-init.ly | 5 ++ scm/define-grobs.scm | 1 + scm/music-functions.scm | 65 +++++++++++----- scm/new-markup.scm | 20 +++++ scripts/convert-ly.py | 29 +++++++ 12 files changed, 231 insertions(+), 54 deletions(-) create mode 100644 input/regression/new-part-combine-a2.ly create mode 100644 input/regression/new-part-combine-solo.ly diff --git a/ChangeLog b/ChangeLog index 5f15606ff7..17d9fec648 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2004-02-03 Han-Wen Nienhuys + + * scm/music-functions.scm (determine-split-list): further analysis. + + * lily/script-engraver.cc (try_music): discard duplicate + articulations. + + * input/regression/new-part-combine-solo.ly: new file + + * input/regression/new-part-combine-a2.ly: new file. + + * ly/performer-init.ly: add Devnull + + * scripts/convert-ly.py (FatalConversionError.sub_acc): add rule + for \musicglyph #"accidental-*" + (conv): \newpartcombine rule. + 2004-02-03 Jan Nieuwenhuizen * scripts/filter-lilypond-book.py: Handle @lilypondfile, bugfixes. @@ -9,6 +26,8 @@ 2004-02-02 Han-Wen Nienhuys + * scm/new-markup.scm (doubleflat): add accidental markups. + * VERSION: release 2.1.17 * Documentation/user/refman.itely (Automatic part combining): diff --git a/VERSION b/VERSION index 126932f63d..3eb1608264 100644 --- a/VERSION +++ b/VERSION @@ -2,5 +2,5 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=1 PATCH_LEVEL=17 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=hwn1 diff --git a/input/regression/new-part-combine-a2.ly b/input/regression/new-part-combine-a2.ly new file mode 100644 index 0000000000..ad91a0b26f --- /dev/null +++ b/input/regression/new-part-combine-a2.ly @@ -0,0 +1,16 @@ + +\header { + texidoc ="The a2 string is only printed on notes, not on rests, +and only after chords, solo or polyphony." + } + +vone = \notes \relative a' { R1*2 g2 r2 g2 r2 a4 r4 g + } +vtwo = \notes \relative a' { R1*2 g2 r2 g2 r2 f4 r4 g } + +\score { + << \property Score.skipBars = ##t + \newpartcombine \vone \vtwo + >> +} + diff --git a/input/regression/new-part-combine-solo.ly b/input/regression/new-part-combine-solo.ly new file mode 100644 index 0000000000..50cb4eb820 --- /dev/null +++ b/input/regression/new-part-combine-solo.ly @@ -0,0 +1,22 @@ + +\header { texidoc = + + "A solo string can only be printed when a note + starts. Hence, in this example, there is no Solo-2 although the + 2nd voice has a dotted quarter, while the first voice has a rest. + +A Solo indication is only printed once; (shared) rests do not require +reprinting a solo indication. + +" + } + +vone = \notes \relative a' { g4 r8 g8 g8 r8 g8 r8 } +vtwo = \notes \relative g' { e4. e8 r2 } + +\score { + << \property Score.skipBars = ##t + \newpartcombine \vone \vtwo + >> +} + diff --git a/input/regression/new-part-combine-text.ly b/input/regression/new-part-combine-text.ly index 89a65309b3..09d4b78ad6 100644 --- a/input/regression/new-part-combine-text.ly +++ b/input/regression/new-part-combine-text.ly @@ -3,13 +3,14 @@ texidoc ="The new part combiner: Detect a2, solo1, solo2 and print texts accordingly. + " } -vone = \notes \relative a' { R1 a4 r4 r r a a a a } +vone = \notes \relative a' { R1 a2 r4 r a a a a } vtwo = \notes \relative a' { R1 f4 f4 f4 f f f a a } \score { diff --git a/lily/new-part-combine-iterator.cc b/lily/new-part-combine-iterator.cc index c98761aa9d..d41eab19c6 100644 --- a/lily/new-part-combine-iterator.cc +++ b/lily/new-part-combine-iterator.cc @@ -1,10 +1,10 @@ /* - 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" @@ -40,14 +40,16 @@ protected: private: Music_iterator * first_iter_; Music_iterator * second_iter_; - bool is_shared_ ; + SCM split_list_; - enum { + enum Status { APART, TOGETHER, SOLO1, SOLO2, - UNISONO, - } state_; + UNISONO, UNISILENCE, + }; + Status state_; + Status playing_state_; Interpretation_context_handle one_; Interpretation_context_handle two_; @@ -55,20 +57,20 @@ private: Interpretation_context_handle shared_; void chords_together (); - void apart (); void solo1 (); void solo2 (); - void unisono (); + 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 @@ -148,6 +150,7 @@ New_pc_iterator::chords_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 ()); @@ -171,21 +174,26 @@ New_pc_iterator::solo1 () second_iter_->substitute_outlet (two_.report_to (), null_.report_to ()); second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ()); - static Music* event; - if (!event) - event = make_music_by_name (ly_symbol2scm ("SoloOneEvent")); + if (playing_state_ != SOLO1) + { + static Music* event; + if (!event) + event = make_music_by_name (ly_symbol2scm ("SoloOneEvent")); - first_iter_-> try_music_in_children (event); + first_iter_-> try_music_in_children (event); + } + playing_state_ = SOLO1; } } void -New_pc_iterator::unisono () +New_pc_iterator::unisono (bool silent) { - if (state_ == UNISONO) - return; + Status newstate = (silent) ? UNISILENCE : UNISONO; + + if (newstate == state_) + return; else { - state_ = UNISONO; first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ()); first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ()); @@ -193,12 +201,17 @@ New_pc_iterator::unisono () 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")); - static Music* event; - if (!event) - event = make_music_by_name (ly_symbol2scm ("UnisonoEvent")); - - first_iter_-> try_music_in_children (event); + first_iter_-> try_music_in_children (event); + playing_state_ = UNISONO; + } + state_ = newstate; } } @@ -210,23 +223,31 @@ New_pc_iterator::solo2 () 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 ()); - static Music* event; - if (!event) - event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent")); + if (playing_state_ != SOLO2) + { + static Music* event; + if (!event) + event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent")); - second_iter_-> try_music_in_children (event); + second_iter_-> try_music_in_children (event); + playing_state_ = SOLO2; + } } } void -New_pc_iterator::apart () +New_pc_iterator::apart (bool silent) { + if (!silent) + playing_state_ = APART; + if (state_ == APART) return; else @@ -260,6 +281,10 @@ New_pc_iterator::construct_children () 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"), @@ -320,10 +345,13 @@ New_pc_iterator::process (Moment m) if (tag == ly_symbol2scm ("chords")) chords_together (); - else if (tag == ly_symbol2scm ("apart")) - apart (); + else if (tag == ly_symbol2scm ("apart") + || tag == ly_symbol2scm ("apart-silence")) + apart (tag == ly_symbol2scm ("apart-silence")); else if (tag == ly_symbol2scm ("unisono")) - unisono (); + unisono (false); + else if (tag == ly_symbol2scm ("unisilence")) + unisono (true); else if (tag == ly_symbol2scm ("solo1")) solo1 (); else if (tag == ly_symbol2scm ("solo2")) diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 3324488400..553561fe7a 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -43,9 +43,20 @@ Script_engraver::try_music (Music *r) { if (r->is_mus_type ("articulation-event")) { + /* + Discard double articulations. + This is necessary for part-combining. + */ + for (int j = 0; j < scripts_.size (); j++) + if (gh_equal_p (scripts_[j]. event_->get_mus_property ("articulation-type"), + r->get_mus_property ("articulation-type") + )) + return true; + Script_tuple t; t.event_ =r; scripts_.push (t); + return true; } return false; diff --git a/ly/performer-init.ly b/ly/performer-init.ly index e35ecdf74f..25d9d362cd 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -55,6 +55,11 @@ \consists "Swallow_performer" } +\translator { + \type "Performer_group_performer" + \name "Devnull" + \consists "Swallow_performer" +} \translator { \type "Performer_group_performer" \name "TabStaff" diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 435adc0378..4889b0d876 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1089,6 +1089,7 @@ (Y-offset-callbacks . (,Side_position_interface::aligned_side)) (X-offset-callbacks . (,Self_alignment_interface::aligned_on_self)) (direction . 1) + (extra-offset . (-1 . 0)) (padding . 0.5) (staff-padding . 0.5) (script-priority . 200) diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 1b9297509f..2d3b1197e4 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -825,17 +825,11 @@ Rest can contain a list of beat groupings ;; -;; due to a bug in the GUILE evaluator, -;; stack traces result in core dumps. -;; therefore we retain debugging code. -;; - -;; -;; todo: this is too hairy. +;; todo: this function is rather too hairy and too long. ;; (define-public (determine-split-list evl1 evl2) "EVL1 and EVL2 should be ascending" - + (define pc-debug #f) (define ev1 (list->vector evl1)) (define ev2 (list->vector evl2)) (define (when v i) @@ -1020,40 +1014,70 @@ Rest can contain a list of beat groupings ;; (define (analyse-solo12 i1 i2 ri) + (define (put x) + (set-cdr! (vector-ref result ri) x) ) (cond ((= ri (vector-length result)) '()) ((= i1 (vector-length ev1)) '()) ((= i2 (vector-length ev2)) '()) (else (let* - ( + ((now (when result ri)) (m1 (when ev1 i1)) (m2 (when ev2 i2)) - (notes1 (get-note-evs ev1 i1)) + (notes1 (get-note-evs ev1 + (if (ly:momentlist result)) diff --git a/scm/new-markup.scm b/scm/new-markup.scm index 4aa774a692..efbcdd8748 100644 --- a/scm/new-markup.scm +++ b/scm/new-markup.scm @@ -461,6 +461,26 @@ Also set markup-signature and markup-keyword object properties." (def-markup-command typewriter (markup?) (font-markup 'font-family 'typewriter)) +(def-markup-command (doublesharp paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals-4"))) +(def-markup-command (threeqsharp paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals-3"))) +(def-markup-command (sharp paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals-2"))) +(def-markup-command (semisharp paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals-1"))) +(def-markup-command (natural paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals-0"))) +(def-markup-command (semiflat paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals--1"))) +(def-markup-command (flat paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals--2"))) +(def-markup-command (threeqflat paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals--3"))) +(def-markup-command (doubleflat paper props) () + (interpret-markup paper props (markup #:musicglyph "accidentals--4"))) + + (def-markup-command (column paper props mrkups) (markup-list?) (stack-lines -1 0.0 (cdr (chain-assoc 'baseline-skip props)) diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py index 7ef3e908cb..22f0ce9c9e 100644 --- a/scripts/convert-ly.py +++ b/scripts/convert-ly.py @@ -1722,6 +1722,35 @@ def conv (str): conversions.append (((2,1,15), conv, """LyricsVoice . instr(ument) -> vocalName""")) +def conv (str): + def sub_acc (m): + d = { + '4': 'doublesharp', + '3': 'threeqsharp', + '2': 'sharp', + '1': 'semisharp', + '0': 'natural', + '-1': 'semiflat', + '-2': 'flat', + '-3': 'threeqflat', + '-4': 'doubleflat'} + return '\\%s' % d[m.group (1)] + + str = re.sub (r'\\musicglyph\s*#"accidentals-([0-9-]+)"', + sub_acc, str) + return str + +conversions.append (((2,1,16), conv, """\\musicglyph #"accidentals-NUM" -> \\sharp/flat/etc.""")) + + +def conv (str): + str = re.sub (r'\\context\s+Voice\s*=\s*one\s*\\partcombine\s+Voice\s*\\context\s+Thread\s*=\s*one(.*)\s*' + + r'\\context\s+Thread\s*=\s*two', + '\\\\newpartcombine\n\\1\n', str) + return str + +conversions.append (((2,1,17), conv, """\\partcombine -> \\newpartcombine""")) + ################################ # END OF CONVERSIONS ################################ -- 2.39.2