From 70901d9472b25cdfd0f889b9f8624188c42dcb95 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 20 Aug 2000 23:50:46 +0200 Subject: [PATCH] release: 1.3.80 =========== * Created Thread_devnull_engraver and Voice_devnull_engraver iso single A2_devnull_engraver in Thread context. It seems however that the hack in A2_devnull_engraver works better. * Coriolan fixes. * Slur attachment fix for chords where case slurdir != stemdir. * Made various fixes for (line-)broken slurs. * Fixed slur_height (), which fixes most ugly slurs (Yeah!). * Fixed some silly url reversals in FAQ. * Finished Coriolan music entry (again); entered second viola part. * Updated Coriolan to use part combiner on Voice level for wind parts and on Staff level for violi and bassi. * Part-combiner now uses duration inquiry, which fixes rhythm-related bugs in determining solo/a2. Also, rests are taken into account. * Another crude fix for almost unexplainable (with a gdb that dumps core on ly_display_scm) all-zero control points slurs. * Fixed slurs that crossed through stems and note heads. Note that beautifying of ugly slurs is still broken. * Made crude fixes slurs don't crash, bezier still crashes on infinitely steep slurs (eg flauti-part *with* slur_engraver). 1.3.79. --- CHANGES | 30 +++-- VERSION | 4 +- debian/changelog | 15 +++ debian/control | 4 +- debian/control.foka | 4 +- debian/copyright | 4 +- debian/rules | 2 +- input/bugs/almost.ly | 0 input/bugs/monstrous.ly | 0 input/bugs/slur.ly | 0 input/test/multistanza.ly | 5 +- lily/include/lyric-phrasing-engraver.hh | 22 ++-- lily/lyric-phrasing-engraver.cc | 151 +++++++++++---------- lily/melisma-engraver.cc | 6 +- lily/piano-pedal-engraver.cc | 6 +- lily/rest.cc | 1 - lily/score-element.cc | 4 +- lily/slur.cc | 4 +- ly/engraver.ly | 6 +- make/out/lilypond.lsm | 8 +- make/out/lilypond.spec | 4 +- mutopia/Coriolan/contrabasso-part.ly | 0 mutopia/Coriolan/viola-part.ly | 0 mutopia/Coriolan/violoncello-part.ly | 0 scm/generic-property.scm | 1 - scm/slur.scm | 9 +- scripts/etf2ly.py | 166 ++++++++++++++++++++---- 27 files changed, 289 insertions(+), 167 deletions(-) delete mode 100644 input/bugs/almost.ly delete mode 100644 input/bugs/monstrous.ly delete mode 100644 input/bugs/slur.ly delete mode 100644 mutopia/Coriolan/contrabasso-part.ly delete mode 100644 mutopia/Coriolan/viola-part.ly delete mode 100644 mutopia/Coriolan/violoncello-part.ly diff --git a/CHANGES b/CHANGES index 4b79edf195..30dc75fd56 100644 --- a/CHANGES +++ b/CHANGES @@ -5,24 +5,14 @@ single A2_devnull_engraver in Thread context. It seems however that the hack in A2_devnull_engraver works better. - -1.3.79.jcn4 -=========== - * Coriolan fixes. * Slur attachment fix for chords where case slurdir != stemdir. -1.3.79.jcn3 -=========== - * Made various fixes for (line-)broken slurs. * Fixed slur_height (), which fixes most ugly slurs (Yeah!). -1.3.79.jcn2 -=========== - * Fixed some silly url reversals in FAQ. * Finished Coriolan music entry (again); entered second viola part. @@ -39,15 +29,27 @@ * Fixed slurs that crossed through stems and note heads. Note that beautifying of ugly slurs is still broken. -1.3.79.jcn1 -=========== - * Made crude fixes slurs don't crash, bezier still crashes on infinitely steep slurs (eg flauti-part *with* slur_engraver). +1.3.79.gp1 +========== + +* Replaced empty melisma score element with a property + +* Renamed Voice_alist_entry -> Syllable_group in lyric-phrasing-engraver + +1.3.79.uu1 +========== + +* fixed y-position of whole rest + +* fixed sustainPedalPadding + +* etf2ly: articulation, lyrics. + 1.3.79 ====== - * etf2ly.py: Finale to LilyPond conversion. 1.3.78.jcn4 diff --git a/VERSION b/VERSION index cb3268bc65..023d39ade9 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,8 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 -PATCH_LEVEL=79 -MY_PATCH_LEVEL=jcn5 +PATCH_LEVEL=80 +MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/debian/changelog b/debian/changelog index 99461b2ef9..af625de087 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +lilypond1.3 (1.3.79-1) unstable; urgency=low + + * New upstream release. + * Added tetex-dev to Build-Depends. Thanks to bug report by fellow + developer Daniel Jacobowitz (closes: Bug#68441). + * Install two documentation files NEWS and ROADMAP. + + -- Anthony Fok Thu, 17 Aug 2000 22:57:57 -0600 + +lilypond1.3 (1.3.78-1) unstable; urgency=low + + * New upstream release. + + -- Anthony Fok Wed, 16 Aug 2000 06:32:14 -0600 + lilypond1.3 (1.3.75-1) unstable; urgency=low * New upstream release. diff --git a/debian/control b/debian/control index 30f1f8caf5..3e6d361154 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Source: lilypond1.3 -Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13) +Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin, tetex-devel, tetex-extra, flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13) Section: tex Priority: optional Maintainer: Anthony Fok @@ -18,7 +18,7 @@ Description: A program for printing sheet music. the GNU Project. . This is the developmental 1.3 branch of LilyPond. It is not intended for - use with stable projects, although 1.3.75 is most likely to be less buggy + use with stable projects, although 1.3.79 is most likely to be less buggy and much more featureful than then the old "stable" 1.2.17. . URLs: http://www.cs.uu.nl/~hanwen/lilypond/ diff --git a/debian/control.foka b/debian/control.foka index 30f1f8caf5..3e6d361154 100644 --- a/debian/control.foka +++ b/debian/control.foka @@ -1,5 +1,5 @@ Source: lilypond1.3 -Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13) +Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin, tetex-devel, tetex-extra, flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13) Section: tex Priority: optional Maintainer: Anthony Fok @@ -18,7 +18,7 @@ Description: A program for printing sheet music. the GNU Project. . This is the developmental 1.3 branch of LilyPond. It is not intended for - use with stable projects, although 1.3.75 is most likely to be less buggy + use with stable projects, although 1.3.79 is most likely to be less buggy and much more featureful than then the old "stable" 1.2.17. . URLs: http://www.cs.uu.nl/~hanwen/lilypond/ diff --git a/debian/copyright b/debian/copyright index 7f4801cbe4..10af91522a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -5,10 +5,10 @@ The development branch, lilypond1.3, is packaged separately on Tue, 9 Nov 1999 22:30:32 -0700 It was downloaded from - ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.74.tar.gz + ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.79.tar.gz It is also available at: - ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.74.tar.gz + ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.79.tar.gz For more information about GNU LilyPond, please visit: http://www.cs.uu.nl/~hanwen/lilypond/ diff --git a/debian/rules b/debian/rules index d2c9ef813e..2330b5cf67 100755 --- a/debian/rules +++ b/debian/rules @@ -85,7 +85,7 @@ binary-arch: build install dh_testdir dh_testroot cp -av lilypond-mode.el $(r)/usr/share/emacs/site-lisp/ - dh_installdocs DEDICATION TODO *.txt \ + dh_installdocs DEDICATION NEWS ROADMAP TODO *.txt \ Documentation/pictures/out/*.png \ Documentation/out/*.txt \ Documentation/*/out/[a-z]*.dvi \ diff --git a/input/bugs/almost.ly b/input/bugs/almost.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/input/bugs/monstrous.ly b/input/bugs/monstrous.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/input/bugs/slur.ly b/input/bugs/slur.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/input/test/multistanza.ly b/input/test/multistanza.ly index 8defa2bf18..71f0a50f8f 100644 --- a/input/test/multistanza.ly +++ b/input/test/multistanza.ly @@ -35,9 +35,10 @@ Global = \notes{ Soprano = \notes \relative c' { \allup - d4 | g g b b a g a b a g b a g2. + d4 | g g b b a g a b a g b a g( a )g % modified to test melisma align right - a4 | b a g b [d16 d c8] [b a] b4 % modified to test beam melisma + [a8 b] | b4 % modified to test melisma align left + a g b [d16 d c8] [b a] b4 % modified to test beam melisma % a4 | b a g b [d8 \melisma c] \melismaEnd [b \melisma a] \melismaEnd b4 d d2 d e d4( cs8 ~ )cs d2. diff --git a/lily/include/lyric-phrasing-engraver.hh b/lily/include/lyric-phrasing-engraver.hh index 44263b4ca4..e00a1c159c 100644 --- a/lily/include/lyric-phrasing-engraver.hh +++ b/lily/include/lyric-phrasing-engraver.hh @@ -15,7 +15,7 @@ #include "item.hh" #include "smobs.hh" -class Voice_alist_entry; +class Syllable_group; /** @@ -72,7 +72,7 @@ private: void record_lyric(const String &context_id, Score_element * lyric); void record_melisma(const String &context_id); void record_extender(const String &context_id, Score_element * extender); - Voice_alist_entry * lookup_context_id(const String &context_id); + Syllable_group * lookup_context_id(const String &context_id); public: Lyric_phrasing_engraver (); @@ -80,32 +80,30 @@ public: VIRTUAL_COPY_CONS (Translator); private: - /** association list of Voice_alist_entry smobs + /** association list of Syllable_group smobs */ Protected_scm voice_alist_; Score_element * any_notehead_l_; }; -class Voice_alist_entry +class Syllable_group { bool first_in_phrase_b_; Score_element * notehead_l_; Link_array lyric_list_; -// Link_array extender_list_; Score_element * longest_lyric_l_; Score_element * shortest_lyric_l_; int alignment_i_; bool melisma_b_; + Real group_translation_f_; public: static SCM make_entry(); void set_first_in_phrase(bool f); void set_notehead(Score_element * notehead); void add_lyric(Score_element * lyric); void add_extender(Score_element * extender); -// void terminate_extenders(); -// void clear_extenders(); - void set_melisma(); + void set_melisma() { melisma_b_ = true; } bool get_melisma() { return melisma_b_; } int lyric_count() { return lyric_list_.size(); } void clear(); @@ -115,13 +113,13 @@ public: int appropriate_alignment(const char *punc); Real amount_to_translate(); void next_lyric(); - void copy(Voice_alist_entry *); + void copy(Syllable_group *); private: - Voice_alist_entry(); - DECLARE_SIMPLE_SMOBS(Voice_alist_entry,); + Syllable_group(); + DECLARE_SIMPLE_SMOBS(Syllable_group,); } ; -Voice_alist_entry * unsmob_voice_entry (SCM); +Syllable_group * unsmob_voice_entry (SCM); #endif // LYRIC_PHRASING_ENGRAVER_HH diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index b9a33c0c2b..5778517c68 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -56,7 +56,7 @@ Lyric_phrasing_engraver::~Lyric_phrasing_engraver() */ } -Voice_alist_entry * +Syllable_group * Lyric_phrasing_engraver::lookup_context_id(const String &context_id) { SCM key = ly_str02scm(context_id.ch_C()); @@ -77,8 +77,8 @@ Lyric_phrasing_engraver::lookup_context_id(const String &context_id) } } // ( ( alist_entry . old_entry ) . previous_entry ) - SCM val = gh_cons(gh_cons(Voice_alist_entry::make_entry (), SCM_BOOL_F), - Voice_alist_entry::make_entry ()); + SCM val = gh_cons(gh_cons(Syllable_group::make_entry (), SCM_BOOL_F), + Syllable_group::make_entry ()); voice_alist_ = scm_acons(key, val, voice_alist_); return unsmob_voice_entry (gh_caar(val)); @@ -89,7 +89,7 @@ void Lyric_phrasing_engraver::record_notehead(const String &context_id, Score_element * notehead) { - Voice_alist_entry * v = lookup_context_id(context_id); + Syllable_group * v = lookup_context_id(context_id); v->set_notehead(notehead); if(!any_notehead_l_) any_notehead_l_ = notehead; @@ -98,7 +98,7 @@ Lyric_phrasing_engraver::record_notehead(const String &context_id, void Lyric_phrasing_engraver::record_lyric(const String &context_id, Score_element * lyric) { - Voice_alist_entry * v = lookup_context_id(context_id); + Syllable_group * v = lookup_context_id(context_id); v->add_lyric(lyric); } @@ -113,7 +113,7 @@ Lyric_phrasing_engraver::record_extender(const String &context_id, Score_element // ( key . ( (alist_entry . old_entry) . previous_entry) ) SCM previous_scm = gh_cddr(s); if(previous_scm != SCM_EOL) { - Voice_alist_entry * v = unsmob_voice_entry(previous_scm); + Syllable_group * v = unsmob_voice_entry(previous_scm); v->add_extender(extender); } } @@ -123,7 +123,7 @@ Lyric_phrasing_engraver::record_extender(const String &context_id, Score_element void Lyric_phrasing_engraver::record_melisma(const String &context_id) { - Voice_alist_entry * v = lookup_context_id(context_id); + Syllable_group * v = lookup_context_id(context_id); v->set_melisma(); } @@ -149,8 +149,14 @@ Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) /* what's its Voice context name? */ String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "Voice"); record_notehead(voice_context_id, h); + + /* is it in a melisma ? */ + if(to_boolean(i.origin_trans_l_->get_property("melismaEngraverBusy"))) { + record_melisma(voice_context_id); + } return; } + /* now try for a lyric */ if (h->has_interface (ly_symbol2scm ("lyric-syllable-interface"))) { @@ -160,25 +166,20 @@ Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) record_lyric(trim_suffix(lyric_voice_context_id), h); return; } - /* finally for a melisma */ - if(h->has_interface (ly_symbol2scm ("melisma-interface"))) { - String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "Voice"); - record_melisma(voice_context_id); - return; - } - /* How about catching any extender items and then if we have a melisma, - set the RIGHT item of the extender spanner to the melismatic note in - the corresponding context (if any). - This has the effect of finishing the extender under the last note - of the melisma, instead of extending it to the next lyric. - - Problem: the extender request is thrown at the same moment as the next lyric, - by which time we have already passed the last note of the melisma. - However, the Lyric_phrasing_engraver remembers the last note, so just - attach it to that, provided it was melismatic. If it was not melismatic, - then ignore it and let the Extender_engraver take care of it (i.e. finish at next - lyric). - */ + + /* Catch any extender items and then if we have a melisma, + set the RIGHT item of the extender spanner to the melismatic note in + the corresponding context (if any). + This has the effect of finishing the extender under the last note + of the melisma, instead of extending it to the next lyric. + + Problem: the extender request is thrown at the same moment as the next lyric, + by which time we have already passed the last note of the melisma. + However, the Lyric_phrasing_engraver remembers the last note, so just + attach it to that, provided it was melismatic. If it was not melismatic, + then ignore it and let the Extender_engraver take care of it (i.e. finish at next + lyric). + */ if(h->has_interface (ly_symbol2scm ("lyric-extender-interface"))) { String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "LyricVoice"); record_extender(trim_suffix(voice_context_id), h); @@ -224,7 +225,7 @@ void Lyric_phrasing_engraver::process_acknowledged () SCM v_entry = gh_cdar(v); // ((current . oldflag) . previous) if(!to_boolean(gh_cdar(v_entry))) { // not an old entry left over from a prior note ... - Voice_alist_entry *entry = unsmob_voice_entry(gh_caar(v_entry)); + Syllable_group *entry = unsmob_voice_entry(gh_caar(v_entry)); if(! entry->set_lyric_align(punc.ch_C(), any_notehead_l_)) warning (_ ("lyrics found without any matching notehead")); @@ -234,7 +235,7 @@ void Lyric_phrasing_engraver::process_acknowledged () warning (_ ("Huh? Melismatic note found to have associated lyrics.")); SCM previous_scm = gh_cdr(v_entry); if(previous_scm != SCM_EOL) { - Voice_alist_entry *previous = unsmob_voice_entry(previous_scm); + Syllable_group *previous = unsmob_voice_entry(previous_scm); if (previous->lyric_count()) previous->adjust_melisma_align(); } @@ -250,12 +251,12 @@ Lyric_phrasing_engraver::do_pre_move_processing () for(SCM v=voice_alist_; gh_pair_p(v); v = gh_cdr(v)) { SCM entry_scm = gh_cdar(v); // ((alist_entry . entry_is_old) . previous_entry) - Voice_alist_entry * entry = unsmob_voice_entry(gh_caar(entry_scm)); + Syllable_group * entry = unsmob_voice_entry(gh_caar(entry_scm)); // set previous_entry, set entry_is_old, and resave it to alist_ // but only change if this current was not old. if(! to_boolean(gh_cdar(entry_scm))) { - Voice_alist_entry * previous_entry = unsmob_voice_entry(gh_cdr(entry_scm)); + Syllable_group * previous_entry = unsmob_voice_entry(gh_cdr(entry_scm)); previous_entry->copy(entry); entry_scm = gh_cons(gh_cons(gh_caar(entry_scm), SCM_BOOL_T), gh_cdr(entry_scm)); voice_alist_ = scm_assoc_set_x(voice_alist_, gh_caar(v), entry_scm); @@ -269,11 +270,11 @@ Lyric_phrasing_engraver::do_pre_move_processing () /*=========================================================================================*/ -/** Voice_alist_entry is a class to be smobbed and entered as data in the association list +/** Syllable_group is a class to be smobbed and entered as data in the association list member of the Lyric_phrasing_engraver class. */ -Voice_alist_entry::Voice_alist_entry() +Syllable_group::Syllable_group() { first_in_phrase_b_=true; melisma_b_ = false; @@ -281,17 +282,18 @@ Voice_alist_entry::Voice_alist_entry() } void -Voice_alist_entry::clear() +Syllable_group::clear() { notehead_l_=0; lyric_list_.clear(); longest_lyric_l_=0; shortest_lyric_l_=0; melisma_b_ = false; + group_translation_f_ = 0.0; } void -Voice_alist_entry::copy( Voice_alist_entry *from) +Syllable_group::copy( Syllable_group *from) { notehead_l_ = from->notehead_l_; lyric_list_ = from->lyric_list_; @@ -300,16 +302,17 @@ Voice_alist_entry::copy( Voice_alist_entry *from) melisma_b_ = from->melisma_b_; alignment_i_ = from->alignment_i_; first_in_phrase_b_ = from->first_in_phrase_b_; + group_translation_f_ = from->group_translation_f_; } void -Voice_alist_entry::set_first_in_phrase(bool f) +Syllable_group::set_first_in_phrase(bool f) { first_in_phrase_b_ = f; } void -Voice_alist_entry::set_notehead(Score_element * notehead) +Syllable_group::set_notehead(Score_element * notehead) { if(!notehead_l_) { /* there should only be a single notehead, so silently ignore any extras */ @@ -318,7 +321,7 @@ Voice_alist_entry::set_notehead(Score_element * notehead) } void -Voice_alist_entry::add_lyric(Score_element * lyric) +Syllable_group::add_lyric(Score_element * lyric) { lyric_list_.push(lyric); /* record longest and shortest lyrics */ @@ -333,7 +336,7 @@ Voice_alist_entry::add_lyric(Score_element * lyric) } void -Voice_alist_entry::add_extender(Score_element * extender) +Syllable_group::add_extender(Score_element * extender) { if(notehead_l_ && melisma_b_) { dynamic_cast(extender)->set_bound (RIGHT, notehead_l_); @@ -350,14 +353,8 @@ Voice_alist_entry::add_extender(Score_element * extender) } } -void -Voice_alist_entry::set_melisma() -{ - melisma_b_ = true; -} - bool -Voice_alist_entry::set_lyric_align(const char *punc, Score_element *default_notehead_l) +Syllable_group::set_lyric_align(const char *punc, Score_element *default_notehead_l) { if(lyric_list_.size()==0) { // No lyrics: nothing to do. @@ -372,38 +369,37 @@ Voice_alist_entry::set_lyric_align(const char *punc, Score_element *default_note if(!notehead_l_) { notehead_l_ = default_notehead_l; } - Real translation = amount_to_translate(); + + group_translation_f_ = amount_to_translate(); + + // set the x alignment of each lyric for(int l = 0; l < lyric_list_.size(); l++) { - /** set the x alignment of each lyric - */ lyric = lyric_list_[l]; lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_)); - // centre on notehead ... if we have one. if(notehead_l_) { - /* set the parent of each lyric to the notehead, - set the offset callback of each lyric to centered_on_parent, - */ lyric->set_parent(notehead_l_, X_AXIS); lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS); - /* reference is on the right of the notehead; move it left half way, then centralise */ - lyric->translate_axis (translation-(notehead_l_->extent(X_AXIS)).center(), X_AXIS); + // reference is on the right of the notehead; move it left half way, and add translation + lyric->translate_axis (group_translation_f_-(notehead_l_->extent(X_AXIS)).center(), X_AXIS); } } return (notehead_l_); } +/** determine the distance to translate lyrics to get correct alignment + Rules: If alignment is centre, translate = 0 + Otherwise, + If (length of longest lyric) < 2 * (length of shortest lyric), + - centre longest lyric on notehead + Otherwise + - move so shortest lyric just reaches notehead centre +*/ Real -Voice_alist_entry::amount_to_translate() +Syllable_group::amount_to_translate() { Real translate = 0.0; if(alignment_i_ != CENTER) { - // right or left align ... - /* If length of longest lyric < 2 * length of shortest lyric, - - centre longest lyric on notehead - Otherwise - - move so shortest lyric just reaches notehead centre - */ // FIXME: do we really know the lyric extent here? Some font sizing comes later? if((longest_lyric_l_->extent(X_AXIS)).length() < (shortest_lyric_l_->extent(X_AXIS)).length() * 2 ) @@ -421,14 +417,13 @@ Voice_alist_entry::amount_to_translate() otherwise alignment is centre. */ int -Voice_alist_entry::appropriate_alignment(const char *punc) +Syllable_group::appropriate_alignment(const char *punc) { if(first_in_phrase_b_) return LEFT; Score_element * lyric; bool end_phrase = true; - /* use a property to determine what constitutes punctuation */ for(int l = 0; l < lyric_list_.size() && end_phrase; l++) { lyric = lyric_list_[l]; @@ -470,11 +465,11 @@ Voice_alist_entry::appropriate_alignment(const char *punc) back and fix the alignment when we DO know. */ void -Voice_alist_entry::adjust_melisma_align() +Syllable_group::adjust_melisma_align() { - if(notehead_l_) { - // undo what we did before ... - Real translation = -amount_to_translate(); + if(notehead_l_ && lyric_list_.size()) { + // override any previous offset adjustments + Real translation = -group_translation_f_; // melisma aligning: switch (alignment_i_) { // case LEFT: // that's all @@ -485,6 +480,8 @@ Voice_alist_entry::adjust_melisma_align() translation += (shortest_lyric_l_->extent(X_AXIS)).length(); break; } + group_translation_f_ += translation; + printf(" now %f.\n",float(group_translation_f_)); for(int l = 0; l < lyric_list_.size(); l++) { lyric_list_[l]->translate_axis (translation, X_AXIS); } @@ -493,13 +490,13 @@ Voice_alist_entry::adjust_melisma_align() bool -Voice_alist_entry::is_empty() +Syllable_group::is_empty() { return lyric_list_.size()==0; } void -Voice_alist_entry::next_lyric() +Syllable_group::next_lyric() { first_in_phrase_b_ = (alignment_i_ == RIGHT); clear(); @@ -510,25 +507,25 @@ Voice_alist_entry::next_lyric() SCM -Voice_alist_entry::mark_smob (SCM) +Syllable_group::mark_smob (SCM) { return SCM_EOL; } int -Voice_alist_entry::print_smob (SCM, SCM port, scm_print_state * ) +Syllable_group::print_smob (SCM, SCM port, scm_print_state * ) { - scm_puts ("#", port); + scm_puts ("#", port); return 1; } -IMPLEMENT_UNSMOB(Voice_alist_entry, voice_entry); -IMPLEMENT_SIMPLE_SMOBS(Voice_alist_entry); -IMPLEMENT_DEFAULT_EQUAL_P(Voice_alist_entry); +IMPLEMENT_UNSMOB(Syllable_group, voice_entry); +IMPLEMENT_SIMPLE_SMOBS(Syllable_group); +IMPLEMENT_DEFAULT_EQUAL_P(Syllable_group); SCM -Voice_alist_entry::make_entry () +Syllable_group::make_entry () { - Voice_alist_entry *vi = new Voice_alist_entry; + Syllable_group *vi = new Syllable_group; return vi->smobbed_self (); } diff --git a/lily/melisma-engraver.cc b/lily/melisma-engraver.cc index e5f7ada603..e51baf0cfb 100644 --- a/lily/melisma-engraver.cc +++ b/lily/melisma-engraver.cc @@ -10,6 +10,7 @@ #include "engraver.hh" #include "musical-request.hh" #include "score-element.hh" +#include "translator-group.hh" /** Signal existence of melismas. @@ -38,11 +39,10 @@ Melisma_engraver::do_try_music (Music *m ) || (to_boolean (tie)) || (to_boolean (beam))) { - Score_element * melisma_p = new Score_element (get_property ("basicMelismaProperties")); - announce_element (melisma_p, m); - + daddy_trans_l_->set_property("melismaEngraverBusy",SCM_BOOL_T); return true; } } + daddy_trans_l_->set_property("melismaEngraverBusy",SCM_BOOL_F); return false; } diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc index f7127c425a..6b1fd8f7c1 100644 --- a/lily/piano-pedal-engraver.cc +++ b/lily/piano-pedal-engraver.cc @@ -200,9 +200,9 @@ Piano_pedal_engraver::do_process_music () p->item_p_->add_offset_callback (Side_position::aligned_on_self, X_AXIS); p->item_p_->add_offset_callback (Side_position::centered_on_parent, X_AXIS); announce_element (p->item_p_, - p->req_l_drul_[START] - ? p->req_l_drul_[START] - : p->req_l_drul_[STOP]); + p->req_l_drul_[START] + ? p->req_l_drul_[START] + : p->req_l_drul_[STOP]); } } } diff --git a/lily/rest.cc b/lily/rest.cc index e3a1de5043..dcff306422 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -23,7 +23,6 @@ Rest::after_line_breaking (SCM smob) int bt = gh_scm2int (me->get_elt_property ("duration-log")); if (bt == 0) { - me->translate_axis (Staff_symbol_referencer::staff_space (me) , Y_AXIS); } diff --git a/lily/score-element.cc b/lily/score-element.cc index 6a294a4301..49493167f3 100644 --- a/lily/score-element.cc +++ b/lily/score-element.cc @@ -836,8 +836,8 @@ init_functions () bool Score_element::has_interface (SCM k) { - if (mutable_property_alist_ == SCM_EOL) - return false; + // if (mutable_property_alist_ == SCM_EOL) + // return false; SCM ifs = get_elt_property (interfaces_sym); diff --git a/lily/slur.cc b/lily/slur.cc index 6a3d31eaed..4b6a9e081c 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -157,7 +157,7 @@ SCM Slur::after_line_breaking (SCM smob) { Score_element *me = unsmob_element (smob); - if (!gh_scm2int(scm_length (me->get_elt_property ("note-columns")))) + if (!scm_ilength (me->get_elt_property ("note-columns"))) { me->suicide (); return SCM_UNSPECIFIED; @@ -382,7 +382,7 @@ SCM Slur::brew_molecule (SCM smob) { Score_element * me = unsmob_element (smob); - if (!gh_scm2int(scm_length (me->get_elt_property ("note-columns")))) + if (!scm_ilength (me->get_elt_property ("note-columns"))) { me->suicide (); return SCM_EOL; diff --git a/ly/engraver.ly b/ly/engraver.ly index aee08d47b3..c4e4214931 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -565,9 +565,6 @@ ScoreContext = \translator { (interfaces . (mark-interface)) (visibility-lambda . ,end-of-line-invisible) ) - basicMelismaProperties = #`( - (interfaces . (melisma-interface)) - ) basicMultiMeasureRestProperties = #`( (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) (molecule-callback . ,Multi_measure_rest::brew_molecule) @@ -605,7 +602,8 @@ ScoreContext = \translator { ) basicTextProperties = #`( ) basicRestProperties = #`( - (interfaces . (rest-interface rhythmic-head-interface)) + (interfaces . (rest-interface rhythmic-head-interface)) + (after-line-breaking-callback . ,Rest::after_line_breaking) (molecule-callback . ,Rest::brew_molecule) (minimum-beam-collision-distance . 1.5) ) diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index d0c09e90e5..7ab5837cae 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.3.79 -Entered-date: 18AUG00 +Version: 1.3.80 +Entered-date: 21AUG00 Description: Keywords: music notation typesetting midi fonts engraving Author: hanwen@cs.uu.nl (Han-Wen Nienhuys) janneke@gnu.org (Jan Nieuwenhuizen) Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys) Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert - 1000k lilypond-1.3.79.tar.gz + 1000k lilypond-1.3.80.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.3.79.tar.gz + 1000k lilypond-1.3.80.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec index 71c92279a7..54e6b94a72 100644 --- a/make/out/lilypond.spec +++ b/make/out/lilypond.spec @@ -1,9 +1,9 @@ Name: lilypond -Version: 1.3.79 +Version: 1.3.80 Release: 1 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.79.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.80.tar.gz Summary: A program for printing sheet music. URL: http://www.cs.uu.nl/~hanwen/lilypond # Icon: lilypond-icon.gif diff --git a/mutopia/Coriolan/contrabasso-part.ly b/mutopia/Coriolan/contrabasso-part.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/mutopia/Coriolan/viola-part.ly b/mutopia/Coriolan/viola-part.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/mutopia/Coriolan/violoncello-part.ly b/mutopia/Coriolan/violoncello-part.ly deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scm/generic-property.scm b/scm/generic-property.scm index 1d53b08a85..a786acd0a1 100644 --- a/scm/generic-property.scm +++ b/scm/generic-property.scm @@ -79,7 +79,6 @@ (define generic-sustain-pedal-properties (cons 'sustain-pedal-interface (list - (list 'textScriptPadding number? 'padding) (list 'sustainPedalPadding number? 'padding)))) (define generic-chord-name-properties diff --git a/scm/slur.scm b/scm/slur.scm index 2574afd619..476d3cc233 100644 --- a/scm/slur.scm +++ b/scm/slur.scm @@ -26,16 +26,15 @@ (define slur-extremity-rules (list - ;; (cons (lambda (slur dir) (begin (display "before sanity check") (newline))#f) #f) + ;; (cons (lambda (slur dir) (begin (display "before head") (newline))#f) #f) ;; urg: don't crash on a slur without note-columns (cons (lambda (slur dir) (< (length (ly-get-elt-property slur 'note-columns)) 1)) 'head) - ;; (cons (lambda (slur dir) (begin (display "before loose-end") (newline))#f) #f) - (cons (lambda (slur dir) (not (attached-to-stem slur dir))) 'loose-end) - - ;; (cons (lambda (slur dir) (begin (display "before head") (newline))#f) #f) + ;; urg: don't crash on a slur without note-columns + (cons (lambda (slur dir) + (< (length (ly-get-elt-property slur 'note-columns)) 1)) 'head) (cons (lambda (slur dir) ;; urg, code dup diff --git a/scripts/etf2ly.py b/scripts/etf2ly.py index 7a99aeeb6d..292e983fb8 100644 --- a/scripts/etf2ly.py +++ b/scripts/etf2ly.py @@ -1,27 +1,22 @@ #!@PYTHON@ -# info taken from +# info mostly taken from looking at files. See also +# http://www.cs.uu.nl/~hanwen/lily-devel/etf.html -# * convertmusic (see sourceforge) -# * Margaret Cahill's thesis -# * http://www.codamusic.com/coda/Fin2000_pdk_download.asp (you have -# to register, but you don't need to have bought a code product - -# # This supports - # # * notes # * rests # * ties # * slurs -# +# * lyrics +# * articulation +# # todo: # * slur/stem directions -# * articulation # * voices (2nd half of frame?) -# * lyrics +# * more intelligent lyrics # * beams (better use autobeam?) program_name = 'etf2ly' @@ -36,11 +31,8 @@ import re import string import os - - finale_clefs= ['treble', 'alto', 'tenor', 'bass', 'percussion', 'treble8vb', 'bass8vb', 'baritone'] - def lily_clef (fin): return finale_clefs[fin] @@ -52,6 +44,7 @@ distances = [0, 2, 4, 5, 7, 9, 11, 12] def semitones (name, acc): return (name / 7 ) * 12 + distances[name % 7] + acc +# represent pitches as (notename, alteration), relative to C-major scale def transpose(orig, delta): (oname, oacc) = orig (dname, dacc) = delta @@ -146,6 +139,7 @@ def lily_notename (tuple2): return nn + class Slur: def __init__ (self, number): self.number = number @@ -159,7 +153,7 @@ class Slur: endnote = self.finale[3][2] cs = chords[startnote] - cs.suffix = '(' + cs.suffix + cs.note_suffix = '(' + cs.note_suffix ce = chords[endnote] ce.prefix = ce.prefix + ')' @@ -187,7 +181,70 @@ class Global_measure: self.scale = find_scale (k) +articulation_dict ={ + 11: '\\prall', + 12: '\\mordent', + 8: '\\fermata', + 18: '"arp"' , # arpeggio +}; + +class Articulation: + def __init__ (self, a,b, finale): + self.type = finale[0] + self.notenumber = b + def calculate (self, chords): + c = chords[self.notenumber] + try: + a = articulation_dict[self.type] + except KeyError: + a = '"art"' + + c.note_suffix = '-' + a + c.note_suffix + +class Syllable: + def __init__ (self, a,b , finale): + self.chordnum = b + self.syllable = finale[1] + self.verse = finale[0] + def calculate (self, chords, lyrics): + self.chord = chords[self.chordnum] + +class Verse: + def __init__ (self, number, body): + self.body = body + self.number = number + self.split_syllables () + def split_syllables (self): + ss = re.split ('(-| +)', self.body) + + sep = 0 + syls = [None] + for s in ss: + if sep: + septor = re.sub (" +", "", s) + septor = re.sub ("-", " -- ", septor) + syls[-1] = syls[-1] + septor + else: + syls.append (s) + + sep = not sep + + self.syllables = syls + + def dump (self): + str = '' + line = '' + for s in self.syllables[1:]: + line = line + ' ' + s + if len (line) > 72: + str = str + ' ' * 4 + line + '\n' + line = '' + + str = """\nverse%s = \\lyrics {\n %s}\n""" % (encodeint (self.number - 1) ,str) + return str + + class Measure: def __init__(self, no): self.number = no @@ -240,6 +297,9 @@ class Frame: str = str + '\n' return str +def encodeint (i): + return chr ( i + ord ('A')) + class Staff: def __init__ (self, number): self.number = number @@ -254,7 +314,7 @@ class Staff: return self.measures[no] def staffid (self): - return 'staff%s'% chr (self.number - 1 +ord ('A')) + return 'staff' + encodeint (self.number - 1) def layerid (self, l): return self.staffid() + 'layer%s' % chr (l -1 + ord ('A')) @@ -349,8 +409,11 @@ class Chord: self.duration = None self.next = None self.prev = None - self.prefix= '' - self.suffix = '' + self.note_prefix= '' + self.note_suffix = '' + self.chord_suffix = '' + self.chord_prefix = '' + def measure (self): if not self.frame: return None @@ -396,7 +459,7 @@ class Chord: self.pitches.append ((sn, acc)) tiestart = tiestart or (flag & Chord.TIE_START_MASK) if tiestart : - self.suffix = self.suffix + ' ~ ' + self.chord_suffix = self.chord_suffix + ' ~ ' REST_MASK = 0x40000000L TIE_START_MASK = 0x40000000L @@ -427,13 +490,14 @@ class Chord: nn = rest s = s + '%s%d%s' % (nn, self.duration[0], '.'* self.duration[1]) - + + if not self.pitches: + s = 'r%d%s' % (self.duration[0] , '.'* self.duration[1]) + s = self.note_prefix + s + self.note_suffix if len (self.pitches) > 1: s = '<%s>' % s - elif not self.pitches: - s = 'r%d%s' % (self.duration[0] , '.'* self.duration[1]) - - s = self.prefix + s + self.suffix + + s = self.chord_prefix + s + self.chord_suffix return s GFre = re.compile(r"""^\^GF\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""") @@ -443,6 +507,9 @@ FRre = re.compile (r"""^\^FR\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+ MSre = re.compile (r"""^\^MS\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""") note_re = re.compile (r"""^ +([0-9-]+) \$([A-Fa-f0-9]+)""") Sxre = re.compile (r"""^\^Sx\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""") +IMre = re.compile (r"""^\^IM\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""") +vere = re.compile(r"""^\^(ve|ch|se)\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""") +versere = re.compile(r"""^\^verse\(([0-9]+)\)(.*)\^end""") class Etf_file: def __init__ (self, name): @@ -452,7 +519,10 @@ class Etf_file: self.frames = [None] self.staffs = [None] self.slurs = [None] - + self.articulations = [None] + self.syllables = [None] + self.verses = [None] + ## do it self.parse (name) @@ -486,6 +556,37 @@ class Etf_file: where = string.atoi (m.group (2)) / 1024.0 return m + def try_IM (self, l): + m = IMre.match (l) + if m: + a = string.atoi (m.group (1)) + b = string.atoi (m.group (2)) + + fin = map (string.atoi, m.groups ()[2:]) + + self.articulations.append (Articulation (a,b,fin)) + return m + def try_verse (self,l): + m = versere .match (l) + if m: + a = string.atoi (m.group (1)) + body =m.group (2) + + body = re.sub (r"""\^[a-z]+\([^)]+\)""", "", body) + body = re.sub ("\^[a-z]+", "", body) + self.verses.append (Verse (a, body)) + + return m + def try_ve (self,l): + m = vere .match (l) + if m: + a = string.atoi (m.group (1)) + b = string.atoi (m.group (2)) + + fin = map (string.atoi, m.groups ()[2:]) + + self.syllables.append (Syllable (a,b,fin)) + return m def try_eE (self, l): m = eEre.match (l) if m: @@ -573,8 +674,12 @@ class Etf_file: m = self.try_note (l) if not m: m = self.try_eE (l) + if not m: + m = self.try_IM (l) if not m: m = self.try_Sx (l) + if not m: + m = self.try_verse (l) sys.stderr.write ('processing ...') sys.stderr.flush () @@ -612,6 +717,8 @@ class Etf_file: for s in self.slurs [1:]: s.calculate (self.chords) + for s in self.articulations[1:]: + s.calculate (self.chords) def get_thread (self, startno, endno): @@ -637,7 +744,14 @@ class Etf_file: if staffs: str = str + '\\score { < %s > } ' % string.join (staffs) - + # should use \addlyrics ? + + for v in self.verses[1:]: + str = str + v.dump() + + if len (self.verses) > 1: + sys.stderr.write ("\nLyrics found; edit to use \\addlyrics to couple to a staff\n") + return str -- 2.39.2