From: Han-Wen Nienhuys Date: Fri, 5 Oct 2001 16:02:16 +0000 (+0200) Subject: release: 1.5.15 X-Git-Tag: release/1.5.15 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=fbc5381fb54df596fd5652236eedc7c1078601e6;p=lilypond.git release: 1.5.15 =========== * Some more random hacking at midi2ly.py. * Slightly better doco for r, s and \skip, with examples. * Bugfixes: add-html-footer.py and @MAILADDRESS@. * Some website related fixes (thanks Tiggr). * Ugly hack in add-html-footer for disabling tutorial and refman links in sidebar. * Guile > 1.4 compilation fixes. * Website bugfix: mailto: (thanks David Boersma). 1.5.14.h --- diff --git a/CHANGES b/CHANGES index b671b77e42..f2a922ccbd 100644 --- a/CHANGES +++ b/CHANGES @@ -8,7 +8,7 @@ * Bugfixes: add-html-footer.py and @MAILADDRESS@. * Some website related fixes (thanks Tiggr). - + * Ugly hack in add-html-footer for disabling tutorial and refman links in sidebar. @@ -16,6 +16,27 @@ in sidebar. * Website bugfix: mailto: (thanks David Boersma). +1.5.14.hwn1 +=========== + +* Rename: Local_key_engraver to Accidental_engraver + +* Add documentation for accidentals grob property. + +* Don't make double accidentals even if two of the same notes are +specified. (Thanks Rune) + +* Search all staff-bars for non-empty barline to determine type. This +fixes span-bars with the lowest staff hara-kiried. (Thanks Rune) + + +1.5.14.rz1 +========== + +* Less buggy beam-split + +* Added subdivideBeams, subdividing beams on beats + 1.5.14 ====== diff --git a/VERSION b/VERSION index d70f1c7952..f5c31f1b08 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,8 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 -PATCH_LEVEL=14 -MY_PATCH_LEVEL=jcn6 +PATCH_LEVEL=15 +MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/bugs/beam-space.ly b/input/bugs/beam-space.ly new file mode 100644 index 0000000000..46c7f4c5f8 --- /dev/null +++ b/input/bugs/beam-space.ly @@ -0,0 +1,23 @@ + + +u = { \translator Staff = up \stemDown } +m = { \translator Staff = mid \stemUp } + +global = \notes { \key fis \major \time 6/8 } + +righta = \notes \transpose c'' { + \repeat unfold 4 { \m [a,16 \u d a d] \m [c \u d c' d ] [c \m b,] [d \u d ] } ] +} + + +\score { \notes + \context PianoStaff < + \context Staff = up { + \clef G \global \righta + } + \context Staff = mid { + \clef F \global s2. *4 + } + > + \paper { } +} diff --git a/input/bugs/harakiri-autoknee.ly b/input/bugs/harakiri-autoknee.ly new file mode 100644 index 0000000000..0a2a3c9fab --- /dev/null +++ b/input/bugs/harakiri-autoknee.ly @@ -0,0 +1,17 @@ + + +\score { \notes \transpose c''' + \context PianoStaff < + \context Staff = up { c4 c c c \break c c c c } + \context Staff = mid { c4 c c c \break s1 } + \context Staff = down { c8 \translator Staff=mid c \translator +Staff=down c c c4 c c c c c } + > + \paper { + \translator { + \HaraKiriStaffContext +% Beam \revert #'auto-knee-gap + } + } +} + diff --git a/input/regression/accidental-double.ly b/input/regression/accidental-double.ly new file mode 100644 index 0000000000..eb37a7c289 --- /dev/null +++ b/input/regression/accidental-double.ly @@ -0,0 +1,15 @@ +\header { + texidoc = "If two forced accidentals happen at the same time, only one + sharp sign is printed." +} + + +\score { \notes \transpose c'' + \context Staff < + \key g \major + \context Voice=va { \stemUp c' fis! } + \context Voice=vb { \stemDown c fis! } + > +} + + diff --git a/input/regression/accidental.ly b/input/regression/accidental.ly index 614995069d..af01b459cf 100644 --- a/input/regression/accidental.ly +++ b/input/regression/accidental.ly @@ -7,10 +7,9 @@ fourth show forced and courtesy accidentals. " } -foo = \notes\relative c'' { \key as \major dis4 dis dis! dis? } +foo = \notes\relative c'' { \key as \major dis4 dis dis!^"force" dis? } \score { - < \foo \context NoteNames \foo > diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc new file mode 100644 index 0000000000..46914f6d20 --- /dev/null +++ b/lily/accidental-engraver.cc @@ -0,0 +1,297 @@ +/* + local-key-engraver.cc -- implement accidental_engraver + + (c) 1997--2001 Han-Wen Nienhuys +*/ + +#include "musical-request.hh" +#include "command-request.hh" +#include "local-key-item.hh" +#include "item.hh" +#include "tie.hh" +#include "rhythmic-head.hh" +#include "timing-translator.hh" +#include "engraver-group-engraver.hh" + +#include "staff-symbol-referencer.hh" +#include "side-position-interface.hh" +#include "engraver.hh" +#include "arpeggio.hh" + +/** + + + FIXME: should not compute vertical positioning of accidentals, but + get them from the noteheads + + The algorithm for accidentals should be documented, and made + tweakable. + +*/ + + +struct Accidental_engraver : Engraver { + Item *key_item_p_; +protected: + TRANSLATOR_DECLARATIONS(Accidental_engraver); + virtual void process_music (); + virtual void acknowledge_grob (Grob_info); + virtual void stop_translation_timestep (); + virtual void initialize (); + virtual void create_grobs (); + virtual void finalize (); +public: + + // todo -> property + SCM last_keysig_; + + /* + Urgh. Since the accidentals depend on lots of variables, we have to + store all information before we can really create the accidentals. + */ + Link_array arpeggios_; + + Link_array mel_l_arr_; + Link_array support_l_arr_; + Link_array forced_l_arr_; + Link_array tie_l_arr_; + +}; + +Accidental_engraver::Accidental_engraver () +{ + key_item_p_ =0; + last_keysig_ = SCM_EOL; +} + +void +Accidental_engraver::initialize () +{ + last_keysig_ = get_property ("keySignature"); + daddy_trans_l_->set_property ("localKeySignature", last_keysig_); +} + +void +Accidental_engraver::create_grobs () +{ + if (!key_item_p_ && mel_l_arr_.size ()) + { + SCM localsig = get_property ("localKeySignature"); + + for (int i=0; i < mel_l_arr_.size (); i++) + { + Grob * support_l = support_l_arr_[i]; + Note_req * note_l = mel_l_arr_[i]; + + int n = unsmob_pitch (note_l->get_mus_property ("pitch"))->notename_i_; + int o = unsmob_pitch (note_l->get_mus_property ("pitch"))->octave_i () ; + int a = unsmob_pitch (note_l->get_mus_property ("pitch"))->alteration_i_; + + /* see if there's a tie that "changes" the accidental */ + /* works because if there's a tie, the note to the left + is of the same pitch as the actual note */ + + SCM prev = scm_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), localsig); + if (prev == SCM_BOOL_F) + prev = scm_assoc (gh_int2scm (n), localsig); + SCM prev_acc = (prev == SCM_BOOL_F) ? gh_int2scm (0) : ly_cdr (prev); + bool different = !gh_equal_p (prev_acc , gh_int2scm (a)); + int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0; + + Grob *tie_break_reminder = 0; + bool tie_changes = false; + for (int i=0; i < tie_l_arr_.size (); i++) + if (support_l == Tie::head (tie_l_arr_[i], RIGHT)) + { + tie_changes = different; + /* Enable accidentals for broken tie + + We only want an accidental on a broken tie, + if the tie changes the accidental. + + Maybe check property noTieBreakForceAccidental? */ + if (different) + tie_break_reminder = tie_l_arr_[i]; + break; + } + + /* When do we want accidentals: + + 1. when property force-accidental is set, and not + tie_changes + 2. when different and not tie-changes + 3. maybe when at end of a tie: we must later see if + we're after a line break */ + if (( (to_boolean (note_l->get_mus_property ("force-accidental")) + || different) + && !tie_changes) + || tie_break_reminder) + { + if (!key_item_p_) + { + key_item_p_ = new Item (get_property ("Accidentals")); + Local_key_item::set_interface (key_item_p_); + + + Staff_symbol_referencer::set_interface (key_item_p_); + SCM c0 = get_property ("centralCPosition"); + if (gh_number_p (c0)) + Staff_symbol_referencer::set_position (key_item_p_, gh_scm2int (c0)); + + announce_grob (key_item_p_, 0); + } + + + bool extra_natural = + sign (p) * (p - a) == 1 + && abs (p) == 2; + + Local_key_item::add_pitch (key_item_p_, *unsmob_pitch (note_l->get_mus_property ("pitch")), + to_boolean (note_l->get_mus_property ("cautionary")), + extra_natural, + tie_break_reminder); + Side_position_interface::add_support (key_item_p_,support_l); + } + + /* + We should not record the accidental if it is the first + note and it is tied from the previous measure. + + Checking whether it is tied also works mostly, but will it + always do the correct thing? + + */ + bool forget = to_boolean (get_property ("forgetAccidentals")); + if (tie_changes) + { + /* + Remember an alteration that is different both from + that of the tied note and of the key signature. + + */ + localsig = scm_assoc_set_x (localsig, gh_cons (gh_int2scm (o), + gh_int2scm (n)), + SCM_BOOL_T); + + } + else if (!forget) + { + /* + not really really correct if there are more than one + noteheads with the same notename. + */ + localsig = scm_assoc_set_x (localsig, gh_cons (gh_int2scm (o), + gh_int2scm (n)), + gh_int2scm (a)); + + } + } + + + + + daddy_trans_l_->set_property ("localKeySignature", localsig); + } + + + if (key_item_p_) + { + /* + Hmm. Which one has to be on the left? + + On which left, code or paper? + + (Arpeggios are engraved left of accidentals, of course.) + */ + for (int i=0; i < arpeggios_.size (); i++) + Side_position_interface::add_support (arpeggios_[i], key_item_p_); + + arpeggios_.clear (); + } +} + +void +Accidental_engraver::finalize () +{ + +} + +void +Accidental_engraver::stop_translation_timestep () +{ + if (key_item_p_) + { + for (int i=0; i < support_l_arr_.size (); i++) + Side_position_interface::add_support (key_item_p_,support_l_arr_[i]); + + typeset_grob (key_item_p_); + key_item_p_ =0; + } + + + mel_l_arr_.clear (); + arpeggios_.clear (); + tie_l_arr_.clear (); + support_l_arr_.clear (); + forced_l_arr_.clear (); +} + +void +Accidental_engraver::acknowledge_grob (Grob_info info) +{ + Note_req * note_l = dynamic_cast (info.req_l_); + + if (note_l && Rhythmic_head::has_interface (info.grob_l_)) + { + mel_l_arr_.push (note_l); + support_l_arr_.push (info.grob_l_); + } + else if (Tie::has_interface (info.grob_l_)) + { + tie_l_arr_.push (info.grob_l_); + } + else if (Arpeggio::has_interface (info.grob_l_)) + { + arpeggios_.push (info.grob_l_); + } + +} + +/* + ugh. repeated deep_copy generates lots of garbage. + */ +void +Accidental_engraver::process_music () +{ + SCM smp = get_property ("measurePosition"); + Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); + + SCM sig = get_property ("keySignature"); + + /* + Detect key sig changes. If we haven't found any, check if at start + of measure, and set localKeySignature anyhow. */ + if (last_keysig_ != sig) + { + daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); + last_keysig_ = sig; + } + else if (!mp.to_bool () ) + { + if (!to_boolean (get_property ("noResetKey"))) + daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); + } +} + + + + + +ENTER_DESCRIPTION(Accidental_engraver, +/* descr */ "Make accidentals. Catches note heads, ties and notices key-change +events. Due to interaction with ties (which don't come together +with note heads), this needs to be in a context higher than Tie_engraver. FIXME", +/* creats*/ "Accidentals", +/* acks */ "rhythmic-head-interface tie-interface arpeggio-interface", +/* reads */ "localKeySignature forgetAccidentals noResetKey", +/* write */ ""); diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 97451c6a4e..2044f88500 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -291,7 +291,8 @@ Auto_beam_engraver::typeset_beam () { if (finished_beam_p_) { - finished_grouping_p_->beamify (); + finished_grouping_p_->beamify(*unsmob_moment (get_property ("beatLength")), + (bool)gh_scm2bool(get_property("subdivideBeams"))); Beam::set_beaming (finished_beam_p_, finished_grouping_p_); typeset_grob (finished_beam_p_); finished_beam_p_ = 0; diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index a927a75f05..b9e7eb63fe 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -181,8 +181,9 @@ Beam_engraver::typeset_beam () { if (finished_beam_p_) { - finished_beam_info_p_->beamify (); - + finished_beam_info_p_->beamify(*unsmob_moment (get_property ("beatLength")), + (bool)gh_scm2bool(get_property("subdivideBeams"))); + Beam::set_beaming (finished_beam_p_, finished_beam_info_p_); typeset_grob (finished_beam_p_); delete finished_beam_info_p_; diff --git a/lily/beam.cc b/lily/beam.cc index e25ca0db06..9e433827b6 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -802,11 +802,12 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev, Direction dir = Directional_element_interface::get (me); - + /* [Tremolo] beams on whole notes may not have direction set? */ if (dir == CENTER) dir = Directional_element_interface::get (here); - + + /* half beams extending to the left. */ if (prev) { diff --git a/lily/beaming-info.cc b/lily/beaming-info.cc index 97071ee65e..9eaed37763 100644 --- a/lily/beaming-info.cc +++ b/lily/beaming-info.cc @@ -24,23 +24,29 @@ Beaming_info::Beaming_info (Moment m, int i) } const int infinity_i = INT_MAX; // guh. +const int at_beat = 1<<15; int -Beaming_info_list::min_denominator_index () const +Beaming_info_list::best_splitpoint_index (Moment &beat_length,bool subdivide) const { int minden = infinity_i; int minidx = -1; + Moment beat_pos; for (int i=1; i < infos_.size (); i++) { - if (infos_[i].start_mom_.den () < minden) + beat_pos = infos_[i].start_mom_ / beat_length; + int den = beat_pos.den (); + if (infos_[i].beams_i_drul_[LEFT] == infos_[i-1].beams_i_drul_[RIGHT] && !subdivide) + den *= 4; + if (den < minden) { minidx = i; - minden = infos_[i].start_mom_.den (); + minden = den; } } - return minidx; + return minidx|(minden==1 && subdivide ? at_beat : 0); } int @@ -56,13 +62,14 @@ Beaming_info_list::beam_extend_count (Direction d) const } void -Beaming_info_list::beamify () +Beaming_info_list::beamify (Moment &beat_length,bool subdivide) { if (infos_.size () <= 1) return; Drul_array splits; - int m = min_denominator_index (); + int m = best_splitpoint_index (beat_length,subdivide); + bool split = subdivide && (m & at_beat); m = m & ~at_beat; splits[LEFT].infos_ = infos_.slice (0,m); splits[RIGHT].infos_ = infos_.slice (m, infos_.size ()); @@ -70,12 +77,13 @@ Beaming_info_list::beamify () do { - splits[d].beamify (); + splits[d].beamify (beat_length,subdivide); } while (flip (&d) != LEFT); - int middle_beams = splits[RIGHT].beam_extend_count (LEFT) infos_; int beam_extend_count (Direction) const; - int min_denominator_index () const; - void beamify (); + int best_splitpoint_index (Moment &beat_length,bool subdivide) const; + void beamify (Moment &beat_length,bool subdivide); void add_stem (Moment d, int beams); }; #endif /* BEAMING_HH */ - diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 77e9bdd6eb..30c154cac5 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -75,9 +75,11 @@ SCM ly_last (SCM list); SCM ly_str02scm (char const*c); SCM ly_write2scm (SCM s); SCM ly_deep_copy (SCM); - +#define CACHE_SYMBOLS #ifdef CACHE_SYMBOLS -#warning: CACHE_SYMBOLS + +// #warning: CACHE_SYMBOLS + /* Using this trick we cache the value of gh_symbol2scm ("fooo") where "fooo" is a constant string. This is done at the cost of one static @@ -88,9 +90,12 @@ SCM ly_deep_copy (SCM); */ #define ly_symbol2scm(x) ({ static SCM cached; \ - (__builtin_constant_p (x)) \ - ? ((cached) ? cached : scm_permanent_object (cached = gh_symbol2scm((char*)x))) \ - : gh_symbol2scm(x); }) + SCM value = cached; /* We store this one locally, since G++ -O2 fucks up else */ \ + if (__builtin_constant_p (x))\ + value = cached = scm_permanent_object (gh_symbol2scm((char*)x));\ + else\ + value = gh_symbol2scm ((char*)x); \ + value; }) #else inline SCM ly_symbol2scm(char const* x) { return gh_symbol2scm((char*)x); } #endif diff --git a/lily/local-key-engraver.cc b/lily/local-key-engraver.cc deleted file mode 100644 index 8ef57ed105..0000000000 --- a/lily/local-key-engraver.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* - local-key-engraver.cc -- implement Local_key_engraver - - (c) 1997--2001 Han-Wen Nienhuys -*/ - -#include "musical-request.hh" -#include "command-request.hh" -#include "local-key-item.hh" -#include "item.hh" -#include "tie.hh" -#include "rhythmic-head.hh" -#include "timing-translator.hh" -#include "engraver-group-engraver.hh" - -#include "staff-symbol-referencer.hh" -#include "side-position-interface.hh" -#include "engraver.hh" -#include "arpeggio.hh" - -/** - - - FIXME: should not compute vertical positioning of accidentals, but - get them from the noteheads - - The algorithm for accidentals should be documented, and made - tweakable. - -*/ - - -struct Local_key_engraver : Engraver { - Item *key_item_p_; -protected: - TRANSLATOR_DECLARATIONS(Local_key_engraver); - virtual void process_music (); - virtual void acknowledge_grob (Grob_info); - virtual void stop_translation_timestep (); - virtual void initialize (); - virtual void create_grobs (); - virtual void finalize (); -public: - - // todo -> property - SCM last_keysig_; - - /* - Urgh. Since the accidentals depend on lots of variables, we have to - store all information before we can really create the accidentals. - */ - Link_array arpeggios_; - - Link_array mel_l_arr_; - Link_array support_l_arr_; - Link_array forced_l_arr_; - Link_array tie_l_arr_; - -}; - -Local_key_engraver::Local_key_engraver () -{ - key_item_p_ =0; - last_keysig_ = SCM_EOL; -} - -void -Local_key_engraver::initialize () -{ - last_keysig_ = get_property ("keySignature"); - daddy_trans_l_->set_property ("localKeySignature", last_keysig_); -} - -void -Local_key_engraver::create_grobs () -{ - if (!key_item_p_ && mel_l_arr_.size ()) - { - SCM localsig = get_property ("localKeySignature"); - - for (int i=0; i < mel_l_arr_.size (); i++) - { - Grob * support_l = support_l_arr_[i]; - Note_req * note_l = mel_l_arr_[i]; - - int n = unsmob_pitch (note_l->get_mus_property ("pitch"))->notename_i_; - int o = unsmob_pitch (note_l->get_mus_property ("pitch"))->octave_i () ; - int a = unsmob_pitch (note_l->get_mus_property ("pitch"))->alteration_i_; - - /* see if there's a tie that "changes" the accidental */ - /* works because if there's a tie, the note to the left - is of the same pitch as the actual note */ - - SCM prev = scm_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), localsig); - if (prev == SCM_BOOL_F) - prev = scm_assoc (gh_int2scm (n), localsig); - SCM prev_acc = (prev == SCM_BOOL_F) ? gh_int2scm (0) : ly_cdr (prev); - bool different = !gh_equal_p (prev_acc , gh_int2scm (a)); - int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0; - - Grob *tie_break_reminder = 0; - bool tie_changes = false; - for (int i=0; i < tie_l_arr_.size (); i++) - if (support_l == Tie::head (tie_l_arr_[i], RIGHT)) - { - tie_changes = different; - /* Enable accidentals for broken tie - - We only want an accidental on a broken tie, - if the tie changes the accidental. - - Maybe check property noTieBreakForceAccidental? */ - if (different) - tie_break_reminder = tie_l_arr_[i]; - break; - } - - /* When do we want accidentals: - - 1. when property force-accidental is set, and not - tie_changes - 2. when different and not tie-changes - 3. maybe when at end of a tie: we must later see if - we're after a line break */ - if (( (to_boolean (note_l->get_mus_property ("force-accidental")) - || different) - && !tie_changes) - || tie_break_reminder) - { - if (!key_item_p_) - { - key_item_p_ = new Item (get_property ("Accidentals")); - Local_key_item::set_interface (key_item_p_); - - - Staff_symbol_referencer::set_interface (key_item_p_); - SCM c0 = get_property ("centralCPosition"); - if (gh_number_p (c0)) - Staff_symbol_referencer::set_position (key_item_p_, gh_scm2int (c0)); - - announce_grob (key_item_p_, 0); - } - - - bool extra_natural = - sign (p) * (p - a) == 1 - && abs (p) == 2; - - Local_key_item::add_pitch (key_item_p_, *unsmob_pitch (note_l->get_mus_property ("pitch")), - to_boolean (note_l->get_mus_property ("cautionary")), - extra_natural, - tie_break_reminder); - Side_position_interface::add_support (key_item_p_,support_l); - } - - /* - We should not record the accidental if it is the first - note and it is tied from the previous measure. - - Checking whether it is tied also works mostly, but will it - always do the correct thing? - - */ - bool forget = to_boolean (get_property ("forgetAccidentals")); - if (tie_changes) - { - /* - Remember an alteration that is different both from - that of the tied note and of the key signature. - - */ - localsig = scm_assoc_set_x (localsig, gh_cons (gh_int2scm (o), - gh_int2scm (n)), - SCM_BOOL_T); - - } - else if (!forget) - { - /* - not really really correct if there are more than one - noteheads with the same notename. - */ - localsig = scm_assoc_set_x (localsig, gh_cons (gh_int2scm (o), - gh_int2scm (n)), - gh_int2scm (a)); - - } - } - - - - - daddy_trans_l_->set_property ("localKeySignature", localsig); - } - - - if (key_item_p_) - { - /* - Hmm. Which one has to be on the left? - - On which left, code or paper? - - (Arpeggios are engraved left of accidentals, of course.) - */ - for (int i=0; i < arpeggios_.size (); i++) - Side_position_interface::add_support (arpeggios_[i], key_item_p_); - - arpeggios_.clear (); - } -} - -void -Local_key_engraver::finalize () -{ - -} - -void -Local_key_engraver::stop_translation_timestep () -{ - if (key_item_p_) - { - for (int i=0; i < support_l_arr_.size (); i++) - Side_position_interface::add_support (key_item_p_,support_l_arr_[i]); - - typeset_grob (key_item_p_); - key_item_p_ =0; - } - - - mel_l_arr_.clear (); - arpeggios_.clear (); - tie_l_arr_.clear (); - support_l_arr_.clear (); - forced_l_arr_.clear (); -} - -void -Local_key_engraver::acknowledge_grob (Grob_info info) -{ - Note_req * note_l = dynamic_cast (info.req_l_); - - if (note_l && Rhythmic_head::has_interface (info.grob_l_)) - { - mel_l_arr_.push (note_l); - support_l_arr_.push (info.grob_l_); - } - else if (Tie::has_interface (info.grob_l_)) - { - tie_l_arr_.push (info.grob_l_); - } - else if (Arpeggio::has_interface (info.grob_l_)) - { - arpeggios_.push (info.grob_l_); - } - -} - -/* - ugh. repeated deep_copy generates lots of garbage. - */ -void -Local_key_engraver::process_music () -{ - SCM smp = get_property ("measurePosition"); - Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); - - SCM sig = get_property ("keySignature"); - - /* - Detect key sig changes. If we haven't found any, check if at start - of measure, and set localKeySignature anyhow. */ - if (last_keysig_ != sig) - { - daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); - last_keysig_ = sig; - } - else if (!mp.to_bool () ) - { - if (!to_boolean (get_property ("noResetKey"))) - daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); - } -} - - - - - -ENTER_DESCRIPTION(Local_key_engraver, -/* descr */ "Make accidentals. Catches note heads, ties and notices key-change -events. Due to interaction with ties (which don't come together -with note heads), this needs to be in a context higher than Tie_engraver. FIXME", -/* creats*/ "Accidentals", -/* acks */ "rhythmic-head-interface tie-interface arpeggio-interface", -/* reads */ "localKeySignature forgetAccidentals noResetKey", -/* write */ ""); diff --git a/lily/local-key-item.cc b/lily/local-key-item.cc index ff01726169..1ffc2c696c 100644 --- a/lily/local-key-item.cc +++ b/lily/local-key-item.cc @@ -28,7 +28,7 @@ static SCM pitch_less_proc; void init_pitch_funcs () { - pitch_less_proc = gh_new_procedure2_0 ("pits-less", &pitch_less); + pitch_less_proc = gh_new_procedure2_0 ("pitch-less", &pitch_less); } ADD_SCM_INIT_FUNC (lkpitch,init_pitch_funcs); @@ -40,7 +40,10 @@ Local_key_item::add_pitch (Grob*me, Pitch p, bool cautionary, bool natural, { SCM acs = me->get_grob_property ("accidentals"); SCM pitch = p.smobbed_copy (); - SCM opts = SCM_EOL; + SCM opts = scm_assoc (pitch, acs); + bool new_pitch = !gh_pair_p (opts); + opts= new_pitch ? SCM_EOL : gh_cdr (opts); + if (cautionary) opts = gh_cons (ly_symbol2scm ("cautionary"), opts); if (natural) @@ -52,8 +55,13 @@ Local_key_item::add_pitch (Grob*me, Pitch p, bool cautionary, bool natural, opts = gh_cons (ly_symbol2scm ("tie-break-reminder"), opts); } - pitch = gh_cons (pitch, opts); - acs = scm_merge_x (acs, gh_cons (pitch, SCM_EOL), pitch_less_proc); + if (new_pitch) + { + pitch = gh_cons (pitch, opts); + acs = scm_merge_x (acs, gh_cons (pitch, SCM_EOL), pitch_less_proc); + } + else + scm_assoc_set_x (acs, pitch, opts); me->set_grob_property ("accidentals", acs); } diff --git a/lily/rhythmic-column-engraver.cc b/lily/rhythmic-column-engraver.cc index ac1515162a..41e3f4a851 100644 --- a/lily/rhythmic-column-engraver.cc +++ b/lily/rhythmic-column-engraver.cc @@ -122,6 +122,6 @@ Rhythmic_column_engraver::start_translation_timestep () ENTER_DESCRIPTION(Rhythmic_column_engraver, /* descr */ "Generates NoteColumn, an objects that groups stems, noteheads and rests.", /* creats*/ "NoteColumn", -/* acks */ "stem-interface rhythmicb-head-interface dot-column-interface", +/* acks */ "stem-interface rhythmic-head-interface dot-column-interface", /* reads */ "", /* write */ ""); diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 01020ca626..1700d181fc 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -177,17 +177,24 @@ void Span_bar::evaluate_glyph (Grob*me) { SCM elts = me->get_grob_property ("elements"); - Grob * b = unsmob_grob (ly_car (elts)); - SCM glsym =ly_symbol2scm ("glyph"); - SCM gl =b ->get_grob_property (glsym); + SCM glyph_symbol = ly_symbol2scm ("glyph"); + SCM gl = SCM_EOL; + + while (gh_pair_p (elts)) + { + gl = unsmob_grob (gh_car (elts))->get_grob_property (glyph_symbol); + if (gh_string_p (gl)) + break; + elts =gh_cdr (elts); + } + if (!gh_string_p (gl)) { me->suicide (); - return ; + return; } - - String type = ly_scm2string (gl); + String type = ly_scm2string (gl); if (type == "|:") { type = ".|"; @@ -202,8 +209,8 @@ Span_bar::evaluate_glyph (Grob*me) } gl = ly_str02scm (type.ch_C ()); - if (scm_equal_p (me->get_grob_property (glsym), gl) != SCM_BOOL_T) - me->set_grob_property (glsym, gl); + if (scm_equal_p (me->get_grob_property (glyph_symbol), gl) != SCM_BOOL_T) + me->set_grob_property (glyph_symbol, gl); } Interval diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 6261811a13..450d5b7784 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -27,7 +27,7 @@ StaffContext=\translator { \consists "Staff_symbol_engraver" \consists "Collision_engraver" \consists "Rest_collision_engraver" - \consists "Local_key_engraver" + \consists "Accidental_engraver" \consists "Piano_pedal_engraver" \consists "Instrument_name_engraver" @@ -379,6 +379,8 @@ ScoreContext = \translator { tupletNumberFormatFunction = #denominator-tuplet-formatter + subdivideBeams = ##f + keyAccidentalOrder = #'( (6 . -1) (2 . -1) (5 . -1 ) (1 . -1) (4 . -1) (0 . -1) (3 . -1) (3 . 1) (0 . 1) (4 . 1) (1 . 1) (5 . 1) (2 . 1) (6 . 1) diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index d12c232a55..eb46045429 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.5.14 -Entered-date: 29SEP01 +Version: 1.5.15 +Entered-date: 05OKT01 Description: @BLURB@ 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.5.14.tar.gz + 1000k lilypond-1.5.15.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.5.14.tar.gz + 1000k lilypond-1.5.15.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.mandrake.spec b/make/out/lilypond.mandrake.spec index 0c791bdf09..f1add83b52 100644 --- a/make/out/lilypond.mandrake.spec +++ b/make/out/lilypond.mandrake.spec @@ -1,5 +1,5 @@ %define name lilypond -%define version 1.5.14 +%define version 1.5.15 %define release 1mdk Name: %{name} diff --git a/make/out/lilypond.redhat.spec b/make/out/lilypond.redhat.spec index 89aac55231..7ee9630603 100644 --- a/make/out/lilypond.redhat.spec +++ b/make/out/lilypond.redhat.spec @@ -1,11 +1,11 @@ %define info yes Name: lilypond -Version: 1.5.14 +Version: 1.5.15 Release: 1 License: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.14.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.15.tar.gz Summary: Create and print music notation URL: http://www.lilypond.org/ BuildRoot: /tmp/lilypond-install diff --git a/make/out/lilypond.suse.spec b/make/out/lilypond.suse.spec index aade408344..1aa450a475 100644 --- a/make/out/lilypond.suse.spec +++ b/make/out/lilypond.suse.spec @@ -14,11 +14,11 @@ Distribution: SuSE Linux 7.0 (i386) Name: lilypond -Version: 1.5.14 +Version: 1.5.15 Release: 2 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.14.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.15.tar.gz # music notation software for.. ? Summary: A program for printing sheet music. URL: http://www.lilypond.org/ diff --git a/modules/midi.c b/modules/midi.c index 826215b139..1228d1c50f 100644 --- a/modules/midi.c +++ b/modules/midi.c @@ -286,7 +286,9 @@ midi_parse_track (unsigned char **track, unsigned char *track_end) #endif debug_print ("%s", "\n"); - assert (!strcmp (*track, "MTrk")); + if (!strcmp (*track, "MTrk")) + return midi_error ("parse_track(): MTrk expected"); + *track += 4; track_len = get_number (track, *track + 4, 4); diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index 9b8ec528b7..3f808ba8bf 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -29,6 +29,9 @@ (grob-property-description 'X-offset-callbacks list? "list of functions, each taking an grob and axis argument. The function determine the position relative to this grob's parent. The last one in the list is called first.") (grob-property-description 'Y-extent-callback procedure? "see @code{X-extent-callback}.") (grob-property-description 'Y-offset-callbacks list? "see @code{X-offset-callbacks}.") +(grob-property-description 'accidentals list? "Alist with (PITCH +. OPTION-LIST) entries. OPTION-LIST can contain 'cautionary, 'natural +and 'tie-break-reminder ") (grob-property-description 'add-stem boolean? "Add stem to porrectus?.") (grob-property-description 'after-line-breaking-callback procedure? "Procedure taking a grob as argument. This procedure is called (using dependency resolution) after line breaking. Return value is ignored.") diff --git a/scm/interface-description.scm b/scm/interface-description.scm index 8bd3ca2ed7..9d2249cac2 100644 --- a/scm/interface-description.scm +++ b/scm/interface-description.scm @@ -185,7 +185,7 @@ (lily-interface 'accidentals-interface "Accidentals" - '( + '(accidentals left-padding right-padding )) diff --git a/scripts/midi2ly.py b/scripts/midi2ly.py index bf169683f1..ec72a6a07a 100644 --- a/scripts/midi2ly.py +++ b/scripts/midi2ly.py @@ -60,10 +60,10 @@ class Time: def dump (self): return dump_skip (self.duration) + '\\time %d/%d ' % (self.num, self.den) -key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis') -key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges') - class Key: + key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis') + key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges') + def __init__ (self, t, sharps, flats, minor): self.duration = t self.flats = flats