]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 1.5.15 release/1.5.15
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Oct 2001 16:02:16 +0000 (18:02 +0200)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Oct 2001 16:02:16 +0000 (18:02 +0200)
===========

* 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

26 files changed:
CHANGES
VERSION
input/bugs/beam-space.ly [new file with mode: 0644]
input/bugs/harakiri-autoknee.ly [new file with mode: 0644]
input/regression/accidental-double.ly [new file with mode: 0644]
input/regression/accidental.ly
lily/accidental-engraver.cc [new file with mode: 0644]
lily/auto-beam-engraver.cc
lily/beam-engraver.cc
lily/beam.cc
lily/beaming-info.cc
lily/include/beaming.hh
lily/include/lily-guile.hh
lily/local-key-engraver.cc [deleted file]
lily/local-key-item.cc
lily/rhythmic-column-engraver.cc
lily/span-bar.cc
ly/engraver-init.ly
make/out/lilypond.lsm
make/out/lilypond.mandrake.spec
make/out/lilypond.redhat.spec
make/out/lilypond.suse.spec
modules/midi.c
scm/grob-property-description.scm
scm/interface-description.scm
scripts/midi2ly.py

diff --git a/CHANGES b/CHANGES
index b671b77e423e31aa752adac09faedbc103dca5ee..f2a922ccbdda644926a658b727b8f2a98146ba42 100644 (file)
--- 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 d70f1c7952e96cae975df35509ea2fcc080d60e9..f5c31f1b08b54aa24e698cd743114a20b5611016 100644 (file)
--- 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 (file)
index 0000000..46c7f4c
--- /dev/null
@@ -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 (file)
index 0000000..0a2a3c9
--- /dev/null
@@ -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 (file)
index 0000000..eb37a7c
--- /dev/null
@@ -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! }
+   >
+}
+
+
index 614995069da06ebbe5e8ac8aaedad4c965d23837..af01b459cf2cbc4f236223678118578a4a72cf51 100644 (file)
@@ -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 (file)
index 0000000..46914f6
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+  local-key-engraver.cc -- implement accidental_engraver
+
+  (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#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<Grob> arpeggios_;
+  
+  Link_array<Note_req> mel_l_arr_;
+  Link_array<Grob> support_l_arr_;
+  Link_array<Item> forced_l_arr_;
+  Link_array<Grob> 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 <Note_req *> (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 */       "");
index 97451c6a4ef6da5811bddb7d4c4f211f1636232a..2044f8850010e4d96b6f35f1de0178183ddf86b0 100644 (file)
@@ -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;
index a927a75f05638d515bf6a99d0f297a295aa8914f..b9e7eb63fec08cb961c5221795ca05b9f49d9196 100644 (file)
@@ -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_;
index e25ca0db06988de11cb88206813ed48b68633829..9e433827b64bc8ca0ac95f460db68c33d536585f 100644 (file)
@@ -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)
     {
index 97071ee65ed8bca91c7e1d26e7a370c0c4bc7b28..9eaed377635b3050ea5a01c88a52b4e8ea2a17a2 100644 (file)
@@ -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<Beaming_info_list> 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) <?
-    splits[LEFT].beam_extend_count (RIGHT);
+  int middle_beams = (split ? 1 :
+                     splits[RIGHT].beam_extend_count (LEFT) <?
+                     splits[LEFT].beam_extend_count (RIGHT));
 
   do
     {
index 6fca4f6a9791d12ddebb09ba2af8f43b46d171e6..e577f604a9dd7fa44cd8b12ccec1270dd4de33ac 100644 (file)
@@ -33,11 +33,10 @@ struct Beaming_info_list
   Array<Beaming_info> 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 */
-
index 77e9bdd6ebf5d3f23fae3d6ce5f8a5bf94f2d4fe..30c154cac59be09607676b80e0154d3a6d9a1c8d 100644 (file)
@@ -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 (file)
index 8ef57ed..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-  local-key-engraver.cc -- implement Local_key_engraver
-
-  (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-*/
-
-#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<Grob> arpeggios_;
-  
-  Link_array<Note_req> mel_l_arr_;
-  Link_array<Grob> support_l_arr_;
-  Link_array<Item> forced_l_arr_;
-  Link_array<Grob> 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 <Note_req *> (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 */       "");
index ff0172616907e7eadc6513d648bd5a212cf23ab9..1ffc2c696cca0a6d7d975b351bb981b1c210c412 100644 (file)
@@ -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);
 }
index ac1515162a31870c97060ce27c11392f6b1a3c33..41e3f4a85143e30dcffc23ac33eed31838b6a87c 100644 (file)
@@ -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 */       "");
index 01020ca6260b85a50e372435e89270abc1bb80ca..1700d181fc2e02ec3090478fe177b573b158245a 100644 (file)
@@ -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
index 6261811a13244229551ed15f5fa5ca89533f5348..450d5b7784079e36b15b17bc1e19be7d24c87adb 100644 (file)
@@ -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)
index d12c232a557ae1a726f2edee64192b4e1ed6bec0..eb460454291278888d169d9ecd1d18087b6382ef 100644 (file)
@@ -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
index 0c791bdf0966b278f3a9e7eaab271c770deedacd..f1add83b521d51b49523219f91f2bc3e48fd3a1f 100644 (file)
@@ -1,5 +1,5 @@
 %define name lilypond
-%define version 1.5.14
+%define version 1.5.15
 %define release 1mdk
 
 Name: %{name}
index 89aac5523121d7cbf064b83545990789824f5820..7ee9630603f3b9a5ff7f4ee8dbf30f4a5bbb2fa8 100644 (file)
@@ -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
index aade40834432ccca6c32deb2798e231cd668589f..1aa450a47576c1a1fd6da8275f21c01408607643 100644 (file)
 
 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/
index 826215b13984780c022dcfc97f2fac33d5058dec..1228d1c50f474b6160822b1a3637384a42095bdc 100644 (file)
@@ -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);
index 9b8ec528b7d941e10b7a5551a95334fde78bff3c..3f808ba8bf0a5e0d61f442120ce4f5e5e2764eec 100644 (file)
@@ -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.")
index 8bd3ca2ed723e055539bcf7134a805486d09b151..9d2249cac2d4eb3de7ac11c9f6364c9da09c92a5 100644 (file)
 (lily-interface
  'accidentals-interface
  "Accidentals"
- '(
+ '(accidentals
    left-padding 
    right-padding 
    ))
index bf169683f12f98b6b661a8713608c15144d55150..ec72a6a07a61c5b1a00f737dd2c8229decc22f42 100644 (file)
@@ -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