lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Cf. Hofstadter's Law


From: Rune Zedeler
Subject: Cf. Hofstadter's Law
Date: Sat, 06 Jul 2002 20:46:57 -0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.9) Gecko/20020513

Hofstadter's Law:
Everything takes longer than you think it will, even when you take into account Hofstadter's Law.

I am sitting at a web cafe and I am in a bit of a hurry - needs to catch a train in 30 minutes, so there are still a few things to be done (insert and docu aliasses in engraver-init.ly), but this patch should work on its own.

2002-07-06  Rune Zedeler  <address@hidden>

        * Documentation/user/refman.itely: Documented accidentals
        (incl. bugs), subdivideBeams and drum/percussion notation.

        * lily/translator-group.cc, lily/include/translator-group.hh
        (Translator_group::set_children_property): removed.

        * lily/accidental-engraver.cc: don't use
        Translator_group::set_children_property.

        * lily/new-accidental-engraver.cc: Added. More correct
        accidentals, but wrong spacing.

        * lily/beam-enagraver.cc, lily/auto-beam-engraver.cc: Small
        subdivideBeams-fixes.

        * scm/drums.scm: Small changes/fixes in instruments and maps


-Rune (very impressed with cvs)
/*
  accidental-engraver.cc -- implement accidental_engraver

  (c)  1997--2002 Han-Wen Nienhuys <address@hidden>
  Modified 2001--2002 by Rune Zedeler <address@hidden>
*/

#include "musical-request.hh"
#include "command-request.hh"
#include "item.hh"
#include "tie.hh"
#include "rhythmic-head.hh"
#include "engraver-group-engraver.hh"
#include "accidental-placement.hh"
#include "side-position-interface.hh"
#include "engraver.hh"
#include "arpeggio.hh"
#include "warn.hh"

#include "translator-group.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 New_accidental_entry {
  int pass_done_;
  int number_accidentals_;
  int number_cautionaries_;
  bool different_;
  Note_req * melodic_;
  Grob * accidental_;
  Translator_group *origin_;
  Grob*  head_;
  New_accidental_entry();
};

New_accidental_entry::New_accidental_entry()
{
  pass_done_ = 0;
  number_accidentals_ = 0;
  number_cautionaries_ = 0;
  different_ = false;
  melodic_ = 0;
  accidental_ = 0;
  origin_ = 0;
  head_ = 0;
}

struct New_accidental_engraver : Engraver {
protected:
  TRANSLATOR_DECLARATIONS (New_accidental_engraver);
  virtual void process_music ();
  virtual void acknowledge_grob (Grob_info);
  virtual void stop_translation_timestep ();
  virtual void initialize ();
  virtual void process_acknowledged_grobs ();
  virtual void finalize ();
  virtual void process_grobs_first_pass ();
  virtual void process_grobs_second_pass ();

  public:

  /*
    TODO -> property.
    
    This is not a property, and it is not protected.  This poses a
    very small risk of the value being GC'd from under us.
  */
  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_;

  Grob * accidental_placement_;
  

  /*
    The next 
   */
  Array<New_accidental_entry> accidental_arr_;
  
  Link_array<Grob> tie_arr_;


};


New_accidental_engraver::New_accidental_engraver ()
{
  accidental_placement_ = 0;
  last_keysig_ = SCM_EOL;
}

/* inserts the source alist into the destination alist, erasing old entries.
   result is: dest = merged
*/ 
static SCM merge_alists_front_x (SCM src, SCM dest) {
  if(gh_pair_p(src)) {
    dest = merge_alists_front_x(ly_cdr(src),dest);
    dest = ly_assoc_front_x(dest, ly_caar(src), ly_cdar(src));
  }
  return dest;
}

static void merge_property_on_children (Translator_group * trans,
                                       const char * from_sym, const char * 
to_sym)
{
  SCM from = trans->get_property(from_sym);
  SCM to = trans->get_property(to_sym);
  to = merge_alists_front_x(from, to);
  trans->set_property (to_sym,  to);
  trans->set_property (from_sym, SCM_EOL);
  for (SCM p = trans -> trans_group_list_; gh_pair_p (p); p = ly_cdr(p)) {
    Translator_group *trg =  dynamic_cast<Translator_group*> (unsmob_translator 
(ly_car (p)));
    merge_property_on_children(trg, from_sym, to_sym);
  }
}

static void merge_property_on_family (Translator_group * trans,
                                      const char * from_sym, const char * 
to_sym)
{
  merge_property_on_children (trans, from_sym, to_sym);
  trans = trans->daddy_trans_l_;
  while (trans)
    {
      SCM from = trans->get_property(from_sym);
      SCM to = trans->get_property(to_sym);
      to = merge_alists_front_x(from, to);
      trans->set_property (to_sym,  to);
      trans->set_property (from_sym, SCM_EOL);
      trans = trans->daddy_trans_l_;
    }
}

static void set_property_on_children (Translator_group * trans, const char * 
sym, SCM val)
{
  trans->set_property (sym, val);
  for (SCM p = trans -> trans_group_list_; gh_pair_p (p); p = ly_cdr(p)) {
    Translator_group *trg =  dynamic_cast<Translator_group*> (unsmob_translator 
(ly_car (p)));
    set_property_on_children(trg,sym,ly_deep_copy(val));
  }
}

static void set_property_on_family(Translator_group * trans, const char * sym, 
SCM val)
{
  set_property_on_children (trans, sym, val);
  trans = trans->daddy_trans_l_;
  while (trans)
    {
      trans -> set_property (sym,  ly_deep_copy (val));
      trans = trans->daddy_trans_l_;
    }
}

void
New_accidental_engraver::initialize ()
{
  // to ensure that process_music will initialize last_keysig_
  last_keysig_ = SCM_BOOL_F;
}

/*
calculates the number of accidentals on basis of the current local key sig
  (passed as argument)
  Returns number of accidentals (0, 1 or 2).
    Negative (-1 or -2) if accidental has changed.

*/
static int
number_accidentals (SCM sig, Note_req * note_l, Pitch *pitch, SCM curbarnum, 
SCM lazyness, 
                    bool ignore_octave_b)
{
  int n = pitch->notename_i_;
  int o = pitch->octave_i_;
  int a = pitch->alteration_i_;
  int curbarnum_i = gh_scm2int (curbarnum);
  int accbarnum_i = 0;

  SCM prev;
  if (ignore_octave_b)
    prev = ly_assoc_cdr (gh_int2scm (n), sig);
  else
    prev = gh_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), sig);

  /* should really be true unless prev == SCM_BOOL_F */
  if (gh_pair_p (prev) && gh_pair_p (ly_cdr (prev)))
    {
      accbarnum_i = gh_scm2int (ly_cddr (prev));
      prev = gh_cons (ly_car (prev), ly_cadr (prev));
    }
  
  /* If an accidental was not found or the accidental was too old */
  if (prev == SCM_BOOL_F ||
      (gh_number_p (lazyness) && curbarnum_i > accbarnum_i + gh_scm2int 
(lazyness)))
    prev = gh_assoc (gh_int2scm (n), sig);


  SCM prev_acc = (prev == SCM_BOOL_F) ? gh_int2scm (0) : ly_cdr (prev);

  int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0;

  int num;
  if (a == p
      && !to_boolean (note_l->get_mus_property ("force-accidental"))
      && gh_number_p (prev_acc))
    num = 0;
  else if ( (abs (a)<abs (p) || p*a<0) && a != 0 )
    num = 2;
  else
    num = 1;
  
  return a == p ? num : -num;
}

static int
number_accidentals (Note_req * note_l, Pitch *pitch, Translator_group * 
origin_l, 
                    SCM accidentals, SCM curbarnum)
{
  int number = 0;

  bool diff = false;
  if (gh_pair_p (accidentals) && !gh_symbol_p (ly_car (accidentals)))
    warning (_f ("Accidental typesetting list must begin with context-name: 
%s", 
                 ly_scm2string (ly_car (accidentals)).ch_C ()));
  
  while (gh_pair_p (accidentals) && origin_l)
    {
      // If pair then it is a new accidentals typesetting rule to be checked
      if (gh_pair_p (ly_car (accidentals)))
        {
          SCM type = gh_caar (accidentals);
          SCM lazyness = gh_cdar (accidentals);
          SCM localsig = origin_l->get_property ("localKeySignature");
          
          bool same_octave_b = 
            gh_eq_p (ly_symbol2scm ("same-octave"), type);
          bool any_octave_b = 
            gh_eq_p (ly_symbol2scm ("any-octave"), type);

          if (same_octave_b || any_octave_b)
            {
              int n = number_accidentals
                (localsig, note_l, pitch, curbarnum, lazyness, any_octave_b);
              diff = diff || (n < 0);
              number = max (number, abs (n));     
            }
          else
            warning (_f ("unknown accidental typesetting: %s. Ignored", 
                         ly_symbol2string (type).ch_C ()));
        }
      

      /*
        if symbol then it is a context name. Scan parent contexts to find it.
      */
      else if (gh_symbol_p (ly_car (accidentals)))
        {
          String context = ly_symbol2string (ly_car (accidentals));
          
          while (origin_l && !origin_l->is_alias_b (context))
            origin_l = origin_l->daddy_trans_l_;
      
          if (!origin_l)
            warning (_f ("Symbol is not a parent context: %s. Ignored", 
                         context.ch_C ()));
        }
      else warning (_f ("Accidental typesetting must be pair or context-name: 
%s", 
                        ly_scm2string (ly_car (accidentals)).ch_C ()));
      
      accidentals = ly_cdr (accidentals);
    }
  return diff ? -number : number;
}


/* 
  Perhaps one should join the two functions into one function taking an
  argument (pass).
  OTOH even though code would be smaller, spaghetti-level would increase.
*/
void
New_accidental_engraver::process_grobs_first_pass ()
{
  SCM accidentals =  get_property ("autoAccidentals");
  SCM cautionaries =  get_property ("autoCautionaries");
  SCM barnum = get_property ("currentBarNumber");

  for (int i = 0; i  < accidental_arr_.size (); i++) 
    {
      if (accidental_arr_[i].pass_done_ >= 1)
        continue;
      accidental_arr_[i].pass_done_  = 1;

      Grob * support_l = accidental_arr_[i].head_;
      Note_req * note_l = accidental_arr_[i].melodic_;
      Translator_group * origin_l = accidental_arr_[i].origin_;
      Pitch * pitch = unsmob_pitch (note_l->get_mus_property ("pitch"));

      int num;
      num = number_accidentals (note_l, pitch, origin_l, accidentals, barnum);
      accidental_arr_[i].number_accidentals_ = abs(num);
      accidental_arr_[i].different_ = num<0;

      num = number_accidentals (note_l, pitch, origin_l, cautionaries, barnum);
      accidental_arr_[i].number_cautionaries_ = abs(num);
      accidental_arr_[i].different_ = accidental_arr_[i].different_ || num<0;

      bool tie_changes = false;
      for (int j = 0; j < tie_arr_.size (); j++)
        if (support_l == Tie::head (tie_arr_[j], RIGHT))
          tie_changes = accidental_arr_[i].different_;
      int n = pitch->notename_i_;
      int o = pitch->octave_i_;
      int a = pitch->alteration_i_;
      SCM o_s = gh_int2scm (o);
      SCM n_s = gh_int2scm (n);
      SCM on_s = gh_cons (o_s,n_s);
      
      while (origin_l)
        {
          SCM sigch = origin_l->get_property ("localKeySignatureChanges");
          SCM alt;
          if (tie_changes)
            /*
              Remember an alteration that is different both from
              that of the tied note and of the key signature.
            */
            alt = SCM_BOOL_T;
          else
            alt = gh_int2scm (a);
          bool other_alt_same_oct = false;
          bool other_alt_any_oct = false;
          for (SCM j = sigch; gh_pair_p(j); j = ly_cdr(j)) {
            SCM entry = ly_car(j);
            /* if same notename has a different alt already recorded: */
            if(gh_equal_p(ly_cdar(entry),n_s) && 
!gh_equal_p(ly_cadr(entry),alt))
              {
                /* if it is also in same octave */
                if(gh_equal_p(ly_caar(entry),o_s))
                  other_alt_same_oct = true;
                else
                  other_alt_any_oct = true;
              }
          }
          if(other_alt_same_oct)
            alt = SCM_BOOL_T;
          sigch = ly_assoc_front_x (sigch, on_s, gh_cons(alt,barnum)); 
          if(other_alt_any_oct && !other_alt_same_oct) {
            sigch = ly_assoc_front_x (sigch, on_s, gh_cons(SCM_BOOL_T,barnum));
          }
          origin_l->set_property ("localKeySignatureChanges",  sigch);
          origin_l = origin_l->daddy_trans_l_;  
        }
    }
}

void
New_accidental_engraver::process_grobs_second_pass ()
{
  SCM accidentals =  get_property ("autoAccidentals");
  SCM cautionaries =  get_property ("autoCautionaries");
  SCM barnum = get_property ("currentBarNumber");
  
  bool extra_natural_b = get_property ("extraNatural") == SCM_BOOL_T;
  for (int i = 0; i  < accidental_arr_.size (); i++) 
    {
      if (accidental_arr_[i].pass_done_ >= 2)
        continue;
      accidental_arr_[i].pass_done_  = 2;
      Grob * support_l = accidental_arr_[i].head_;
      Note_req * note_l = accidental_arr_[i].melodic_;
      Translator_group * origin_l = accidental_arr_[i].origin_;
      
      Pitch * pitch = unsmob_pitch (note_l->get_mus_property ("pitch"));

      int num;
      num = number_accidentals (note_l, pitch, origin_l, accidentals, barnum);
      accidental_arr_[i].number_accidentals_ =
        max (accidental_arr_[i].number_accidentals_, abs(num));
      accidental_arr_[i].different_ = accidental_arr_[i].different_ || num<0;

      num = number_accidentals (note_l, pitch, origin_l, cautionaries, barnum);
      accidental_arr_[i].number_cautionaries_ =
        max (accidental_arr_[i].number_cautionaries_, abs(num));
      accidental_arr_[i].different_ = accidental_arr_[i].different_ || num<0;


      bool cautionary = to_boolean (note_l->get_mus_property ("cautionary"));
      
      if (accidental_arr_[i].number_cautionaries_ 
>accidental_arr_[i].number_accidentals_ )
        {
          num = accidental_arr_[i].number_cautionaries_;
          cautionary = true;
        }
      else
          num = accidental_arr_[i].number_accidentals_;

      bool tie_changes = false;
      Grob *tie_break_reminder = 0;
      for (int j = 0; j < tie_arr_.size (); j++)
        if (support_l == Tie::head (tie_arr_[j], RIGHT))
          {
            tie_changes = accidental_arr_[i].different_;
            tie_break_reminder = tie_arr_[j];
          }
      
      if (num)
        {
          Grob * a = new Item (get_property ("Accidental"));
          a->set_parent (support_l, Y_AXIS);
          
          if (!accidental_placement_)
            {
              accidental_placement_ = new Item (get_property 
("AccidentalPlacement"));
              announce_grob (accidental_placement_, a->self_scm());
            }
          
          Accidental_placement::add_accidental (accidental_placement_, a);
          announce_grob (a, SCM_EOL);
          
          
          SCM accs = gh_cons (gh_int2scm (pitch->alteration_i_), SCM_EOL);
          if (num == 2 && extra_natural_b)
            accs = gh_cons (gh_int2scm (0), accs);
          
          if (cautionary)
            {
              a->set_grob_property ("cautionary", SCM_BOOL_T);
            }
          
          if (tie_break_reminder)
            {
              a->set_grob_property ("tie", tie_break_reminder->self_scm());
            }
          
          
          support_l->set_grob_property ("accidental-grob", a->self_scm ());
          
          a->set_grob_property ("accidentals", accs);
          accidental_arr_[i].accidental_ = a;
          /*
            We add the accidentals to the support of the arpeggio, so it is
            put left of the accidentals. 
          */
          for (int i = 0;  i < arpeggios_.size ();  i++)
            Side_position_interface::add_support (arpeggios_[i], a);
        }       
    }
}

void
New_accidental_engraver::process_acknowledged_grobs ()
{
  if (accidental_arr_.size () && accidental_arr_.top().pass_done_ < 1)
    process_grobs_first_pass ();
}

void
New_accidental_engraver::finalize ()
{

}

void
New_accidental_engraver::stop_translation_timestep ()
{
  merge_property_on_family(daddy_trans_l_, "localKeySignatureChanges", 
"localKeySignature");
  if (accidental_arr_.size () && accidental_arr_.top().pass_done_ < 2)
    process_grobs_second_pass ();

  for (int i = 0; i < accidental_arr_.size(); i++)
    {
      Grob *a = accidental_arr_[i].accidental_;
      if (a)
        {
          typeset_grob (a);
        }
    }

  if (accidental_placement_)
    typeset_grob(accidental_placement_);
  accidental_placement_ = 00;

  set_property_on_family(daddy_trans_l_, "localKeySignatureChanges", SCM_EOL);  
  accidental_arr_.clear();
  arpeggios_.clear ();
  tie_arr_.clear ();
}

void
New_accidental_engraver::acknowledge_grob (Grob_info info)
{
  Note_req * note_l =  dynamic_cast <Note_req *> (info.music_cause ());

  if (note_l && Rhythmic_head::has_interface (info.grob_l_))
    {
      New_accidental_entry entry ;
      entry.head_ = info.grob_l_;
      entry.origin_ = info.origin_trans_l_->daddy_trans_l_;
      entry.melodic_ = note_l;

      accidental_arr_.push (entry);
    }
  else if (Tie::has_interface (info.grob_l_))
    {
      tie_arr_.push (info.grob_l_);
    }
  else if (Arpeggio::has_interface (info.grob_l_))
    {
      arpeggios_.push (info.grob_l_); 
    }
  
}

void
New_accidental_engraver::process_music ()
{
  SCM sig = get_property ("keySignature");

  /* Detect key sig changes.
     Update all parents and children
  */
  if (last_keysig_ != sig)
    {
      set_property_on_family(daddy_trans_l_, "localKeySignature", sig);
      set_property_on_family(daddy_trans_l_, "localKeySignatureChanges", 
SCM_EOL); //This souldn't be neccesary
      last_keysig_ = sig;
    }
}





ENTER_DESCRIPTION (New_accidental_engraver,
"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.",
                   
               "Accidental",
               "rhythmic-head-interface tie-interface arpeggio-interface",
               "localKeySignature localKeySignatureChanges extraNatural 
autoAccidentals autoCautionaries",
                   "localKeySignature localKeySignatureChanges");
? lily/new-accidental-engraver.cc
Index: ChangeLog
===================================================================
RCS file: /home/lilypond/lilypond/ChangeLog,v
retrieving revision 1.265
diff -p -u -r1.265 ChangeLog
--- ChangeLog   5 Jul 2002 14:31:02 -0000       1.265
+++ ChangeLog   6 Jul 2002 18:36:27 -0000
@@ -1,3 +1,22 @@
+2002-07-06  Rune Zedeler  <address@hidden>
+
+       * Documentation/user/refman.itely: Documented accidentals
+       (incl. bugs), subdivideBeams and drum/percussion notation.
+
+       * lily/translator-group.cc, lily/include/translator-group.hh
+       (Translator_group::set_children_property): removed.
+
+       * lily/accidental-engraver.cc: don't use
+       Translator_group::set_children_property.
+
+       * lily/new-accidental-engraver.cc: Added. More correct
+       accidentals, but wrong spacing.
+
+       * lily/beam-enagraver.cc, lily/auto-beam-engraver.cc: Small
+       subdivideBeams-fixes.
+
+       * scm/drums.scm: Small changes/fixes in instruments and maps
+       
 2002-07-05  Jan Nieuwenhuizen  <address@hidden>
 
        * lexer-gcc-3.1.sh: Fixes and more comments.
Index: Documentation/user/refman.itely
===================================================================
RCS file: /home/lilypond/lilypond/Documentation/user/refman.itely,v
retrieving revision 1.113
diff -p -u -r1.113 refman.itely
--- Documentation/user/refman.itely     2 Jul 2002 19:31:52 -0000       1.113
+++ Documentation/user/refman.itely     6 Jul 2002 18:36:31 -0000
@@ -35,6 +35,7 @@ encouraged to study the tutorial first.
 * Staff notation::              
 * Polyphony::                   
 * Beaming::                     
+* Accidentals::                 
 * Expressive marks::            
 * Ornaments::                   
 * Repeats::                     
@@ -158,7 +159,8 @@ octave; each @code{,} lowers the pitch b
 @subsection Chromatic alterations
 
 Normally Accidentals signify that the pitch of a note differs from the
-key signature. Normally, they are printed automatically depending, but
+key signature. Normally, they are printed automatically 
+(see @ref{Accidentals}) depending, but
 you may force accidentals in the following  ways:
 A reminder accidental
 @cindex reminder accidental
@@ -360,6 +362,7 @@ context and turning on and off ties per 
 
 @node Automatic note splitting 
 @subsection Automatic note splitting
address@hidden FIXME: This subsection doesn't belong in @ref{Note entry}.
 
 There is a facility for automatically converting long notes to  tied
 notes. This is done by replacing the @code{Note_heads_engraver} by the
@@ -1191,6 +1194,32 @@ horizontal, falls two staff spaces:
 
 @end ignore
 
+Even though the same effect can be accomplished by some twiddling with
address@hidden and @code{stemRightBeamCount} the property
address@hidden can be set in order to subdivide all 16th or
+shorter beams at beat positions:
+
address@hidden
+[c16 c c c c c c c]
+\property Voice.subdivideBeams = ##t
+[c16 c c c c c c c]
+[c32 c c c c c c c c c c c c c c c]
+\property Score.beatLength = #(make-moment 1 8)
+[c32 c c c c c c c c c c c c c c c]
address@hidden example
address@hidden
+\score {
+    \notes \relative c' {
+        [c16 c c c c c c c]
+        \property Voice.subdivideBeams = ##t
+        [c16 c c c c c c c]
+        [c32 c c c c c c c c c c c c c c c]
+        \property Score.beatLength = #(make-moment 1 8)
+        [c32 c c c c c c c c c c c c c c c]
+    }
+}
address@hidden lilypond
address@hidden subdivideBeams
 
 Kneed beams are inserted automatically, when a large gap between two
 adjacent beamed notes is detected. This behavior can be tuned through
@@ -1325,6 +1354,230 @@ It is not possible to specify beaming pa
 different parts of a measure. This means that it is not possible to use
 automatic beaming in irregular meters such as @code{5/8}.
 
address@hidden Accidentals
address@hidden Accidentals
address@hidden Accidentals
+This section describes how to change the way that LilyPond automatically
+inserts accidentals before the running notes.
+
address@hidden
+* Using the predefined accidental macros ::
+* Defining your own accidental typesettings ::
address@hidden menu
address@hidden Using the predefined accidental macros
address@hidden Using the predefined accidental macros
+The constructs for describing the accidental typesetting rules are
+quite hairy, so non-experts should stick to the macros defined in
address@hidden/property-init.ly}.
address@hidden @file{property-init.ly}
+
+The normal way of using the macros is to enter the macro name right after the
+creation of the context in which the accidental typesetting described
+by the macro is to take effect. I.e. if you want to use
+piano-accidentals in a pianostaff then you issue
address@hidden first thing after the creation of the piano
+staff:
address@hidden
+\score @{
+    \notes \relative c'' <
+        \context Staff = sa @{ cis4 d e2 @}
+        \context GrandStaff <
+            \pianoAccidentals
+            \context Staff = sb @{ cis4 d e2 @}
+            \context Staff = sc @{ es2 c @}
+        >
+        \context Staff = sd @{ es2 c @}
+    >
address@hidden
address@hidden example
address@hidden
+\score {
+    \notes \relative c'' <
+        \context Staff = sa { cis4 d e2 }
+        \context GrandStaff <
+            \pianoAccidentals
+            \context Staff = sb { cis4 d e2 }
+            \context Staff = sc { es2 c }
+        >
+        \context Staff = sd { es2 c }
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            minimumVerticalExtent = #'(-4.0 . 4.0)
+        }
+    }
+}
address@hidden lilypond
+
+The macros are:
address@hidden @code
address@hidden {\defaultAccidentals}
+      @cindex @code{\defaultAccidentals}
+      This is the default typesetting behaviour. It should correspond
+      to 18th century common practice: Accidentals are
+      remembered to the end of the measure in which they occur and
+      only on their own octave.
+
address@hidden {\voiceAccidentals}
+      @cindex @code{\voiceAccidentals}
+      The normal behaviour is to remember the accidentals on
+      Staff-level.
+      This macro, however, typesets accidentals individually for each
+      voice.
+      Apart from that the rule is similar to
+      @code{\defaultAccidentals}.
+
+      Warning: This leads to some weird and often unwanted results
+      because accidentals from one voice DO NOT get cancelled in other
+      voices:
address@hidden,relative,fragment,verbatim]
+    \context Staff <
+        \voiceAccidentals
+        \context Voice=va { \voiceOne es g }
+        \context Voice=vb { \voiceTwo c, e }
+    >
address@hidden lilypond
+      Hence you should only use @code{\voiceAccidentals}
+      if the voices are to be read solely by
+      individual musicians. if the staff should be readable also
+      by one musician/conductor then you should use
+      @code{\modernVoiceAccidentals} or @code{\modernVoiceCautionaries}
+      instead.
+
address@hidden {\modernAccidentals}
+      @cindex @code{\modernAccidentals}
+      This rule should correspond to the common practice in the 20th
+      century.
+      The rule is a bit more complex than @code{\defaultAccidentals}:
+      You get all the same accidentals, but temporary
+      accidentals also get cancelled in other octaves. Further more,
+      in the same octave, they also get cancelled in the following measure:
address@hidden,fragment,verbatim]
+      \modernAccidentals
+      cis' c'' cis'2 | c'' c'
address@hidden lilypond
+
address@hidden {\modernCautionaries}
+      @cindex @code{\modernCautionaries}
+     This rule is similar to @code{\modernAccidentals}, but the
+     ``extra'' accidentals (the ones not typeset by
+     @code{\defaultAccidentals}) are typeset as cautionary accidentals
+     (i.e. in reduced size):
address@hidden,fragment,verbatim]
+      \modernCautionaries
+      cis' c'' cis'2 | c'' c'
address@hidden lilypond
+
address@hidden {\modernVoiceAccidentals}
+      @cindex @code{\modernVoiceAccidentals}
+      Multivoice accidentals to be read both by musicians playing one voice
+      and musicians playing all voices.
+
+      Accidentals are typeset for each voice, but they ARE cancelled
+      across voices in the same @internalsref{Staff}.
+
address@hidden {\modernVoiceCautionaries}
+      @cindex @code{\modernVoiceCautionaries}
+      The same as @code{\modernVoiceAccidentals}, but with the
+      extra accidentals (the ones not typeset by
+      @code{\voiceAccidentals}) typeset as cautionaries.
+      Notice that even though all accidentals typeset by
+      @code{\defaultAccidentals} ARE typeset by this macro then some
+      of them are typeset as cautionaries.
+
address@hidden {\pianoAccidentals}
+      @cindex @code{\pianoAccidentals}
+      20th century practice for piano notation. Very similar to
+      @code{\modernAccidentals} but accidentals also get cancelled
+      across the staves in the same @internalsref{GrandStaff} or
+      @internalsref{PianoStaff}.
+
address@hidden {\pianoCautionaries}
+      @cindex @code{\pianoCautionaries}
+      As @code{\pianoAccidentals} but with the extra accidentals
+      typeset as cationaries.
+
address@hidden {\noResetKey}
+      @cindex @code{\noResetKey}
+      Same as @code{\defaultAccidentals} but with accidentals lasting
+      ``forever'' and not only until the next measure:
address@hidden,fragment,verbatim,relative]
+      \noResetKey
+      c1 cis cis c
address@hidden lilypond
+
address@hidden {\forgetAccidentals}
+      @cindex @code{\forgetAccidentals}
+      This is sort of the opposite of @code{\noResetKey}: Accidentals
+      are not remembered at all - and hence all accidentals are
+      typeset relative to the key signature, regardless of what was
+      before in the music:
address@hidden,fragment,verbatim,relative]
+      \forgetAccidentals
+      \key d\major c4 c cis cis d d dis dis
address@hidden lilypond
address@hidden table
+
address@hidden Defining your own accidental typesettings
address@hidden Defining your own accidental typesettings
+This section must be concidered gurus-only, and hence it must be
+sufficient with a short description of the system and a reference to
+the internal documentation.
+
+The idea of the algorithm is to try several different rules and then
+use the rule that gives the highest number of accidentals.
+Each rule cosists of
address@hidden @asis
address@hidden {Context:}
+      In which context is the rule applied. I.e. if context is
+      @internalsref{Score} then all staves share accidentals, and if
+      context is @internalsref{Staff} then all voices in the same
+      staff share accidentals, but staves don't - like normally.
address@hidden {Octavation:}
+      Whether the accidental changes all octaves or only the current
+      octave.
address@hidden {Lazyness:}
+      Over how many barlines the accidental lasts.
+      If lazyness is @code{-1} then the accidental is forget
+      immidiately, and if lazyness is @code{#t} then the accidental
+      lasts forever.
address@hidden table
+
+As described in the internal documentation of
address@hidden, the properties @code{autoAccidentals} and
address@hidden contain lists of rule descriptions. Notice
+that the contexts must be listed from in to out - that is
address@hidden before @internalsref{Voice},
address@hidden before @internalsref{Staff}, etc. 
+see the macros in @file{ly/property-init.ly} for examples of how the
+properties are set.
+
address@hidden
+
+Currently the simultainous notes are concidered to be entered in sequential
+mode. This means that in a chord the accidentals are typeset as if
+the notes in the chord happened one at a time - in the order in which
+they appear in the input file.
+
+Of course this is only a problem when you have simultainous notes
+which accidentals should depend on each other.
+Notice that the problem only occurs when using non-default accidentals
+- as the default accidentals only depend on other accidentals on the
+same staff and same pitch and hence cannot depend on other
+simultainous notes.
+
+This example shows two examples of the same music giving different
+accidentals depending on the order in which the notes occur in the
+input file:
+
address@hidden,fragment,verbatim]
+\property Staff.autoAccidentals = #'( Staff (any-octave . 0) )
+cis'4 <c'' c'> r2 | cis'4 <c' c''> r2 | <cis' c''> r | <c'' cis'> r | 
address@hidden lilypond
+
+The only solution is to manually insert the problematic
+accidentals using @code{!} and @code{?}.
 
 @node Expressive marks
 @section Expressive marks
@@ -2099,7 +2352,8 @@ with slashes, and repeating that measure
 
 
 @menu
-* Rhythmic staves::             
+* Rhythmic staves::
+* Percussion staves::             
 @end menu
 
 @node Rhythmic staves
@@ -2116,7 +2370,298 @@ are squashed, and the  staff itself  loo
   }
 @end lilypond
 
address@hidden Percussion staves
address@hidden Percussion staves
address@hidden percussion
address@hidden drums
+To typeset more than one piece of percussion to be played by the same
+musician one typically uses a multiline staff where each staff
+position refers to a specific piece of percussion.
+
+LilyPond is shipped with a bunch of scheme functions which allows you
+to do this fairly easily.
+
+The system is based on the general midi drum-pitches.
+In order to use the drum pitches you include
address@hidden/drumpitch-init.ly}. This file defines the pitches from the scheme
+variable @code{drum-pitch-names} - which definition can be read in
address@hidden/drums.scm}. You see that each piece of percussion has a full
+name and an abbreviated name - and you may freely select whether to
+refer to the full name or the abbreviation in your music definition.
+
+To typeset the music on a staff you apply the scheme function
address@hidden>paper} to the percussion music. This function takes a
+list of percussion instrument names, notehead scripts and staff
+positions (that is: pitches relative to the C-clef) and uses this to
+transform the input music by moving the pitch, changing the notehead
+and (optionally) adding a script:
address@hidden,verbatim]
+\include "drumpitch-init.ly"
+up = \notes { crashcymbal4 hihat8 halfopenhihat hh hh hh openhihat }
+down = \notes { bassdrum4 snare8 bd r bd sn4 }
+\score {
+    \apply #(drums->paper 'drums) \context Staff <
+        \clef percussion
+        \context Voice = up { \voiceOne \up }
+        \context Voice = down { \voiceTwo \down }
+    >
+}
+
address@hidden lilypond
+In the above example the music was transformed using the list @code{'drums}.
+Currently the following lists are defined in @file{scm/drums.scm}:
address@hidden @code
address@hidden 'drums
+To typeset a typical drum kit on a five line staff.
address@hidden
+\include "drumpitch-init.ly"
+nam = \lyrics { cymc cyms cymr hh hhc hho hhho hhp cb hc
+    bd sn ss tomh tommh tomml toml tomfh tomfl }
+mus = \notes  { cymc cyms cymr hh hhc hho hhho hhp cb hc
+    bd sn ss tomh tommh tomml toml tomfh tomfl s16 }
+\score {
+    <
+        \apply #(drums->paper 'drums) \context Staff <
+            \clef percussion
+            \mus
+        >
+        \context Lyrics \nam 
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            \remove Bar_engraver
+            \remove Time_signature_engraver
+            minimumVerticalExtent = #'(-4.0 . 5.0)
+        }
+        \translator {
+            \VoiceContext
+            \remove Stem_engraver
+        }
+   }   
+}
address@hidden lilypond
+Notice that the scheme supports six different toms.
+If you are using fewer toms then you simply select the toms that produce
+the desired result - i.e. to get toms on the three middle lines you
+use @code{tommh}, @code{tomml} and @code{tomfh}.
+
+Because the general midi contain no rimshots we use the sidestick for
+this purpose instead.
address@hidden 'timbales
+To typeset timbales on a two line staff.
address@hidden
+\include "drumpitch-init.ly"
+nam = \lyrics { timh ssh timl ssl cb }
+mus = \notes  { timh ssh timl ssl cb s16 }
+\score {
+    <
+        \apply #(drums->paper 'timbales) \context Staff <
+            \clef percussion
+            \mus
+        >
+        \context Lyrics \nam 
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            \remove Bar_engraver
+            \remove Time_signature_engraver
+            StaffSymbol \override #'line-count = #2
+            StaffSymbol \override #'staff-space = #2
+            minimumVerticalExtent = #'(-3.0 . 4.0)
+        }
+        \translator {
+            \VoiceContext
+            \remove Stem_engraver
+        }
+
+    }   
+}
address@hidden lilypond
address@hidden 'congas
+To typeset congas on a two line staff.
address@hidden
+\include "drumpitch-init.ly"
+nam = \lyrics { cgh cgho cghm ssh cgl cglo cglm ssl }
+mus = \notes  { cgh cgho cghm ssh cgl cglo cglm ssl s16 }
+\score {
+    <
+        \apply #(drums->paper 'congas) \context Staff <
+            \clef percussion
+            \mus
+        >
+        \context Lyrics \nam 
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            \remove Bar_engraver
+            \remove Time_signature_engraver
+            StaffSymbol \override #'line-count = #2
+            StaffSymbol \override #'staff-space = #2
+            minimumVerticalExtent = #'(-3.0 . 4.0)
+        }
+        \translator {
+            \VoiceContext
+            \remove Stem_engraver
+        }
+    }   
+}
address@hidden lilypond
address@hidden 'bongos
+To typeset bongos on a two line staff.
address@hidden
+\include "drumpitch-init.ly"
+nam = \lyrics { boh boho bohm ssh bol bolo bolm ssl }
+mus = \notes  { boh boho bohm ssh bol bolo bolm ssl s16 }
+\score {
+    <
+        \apply #(drums->paper 'bongos) \context Staff <
+            \clef percussion
+            \mus
+        >
+        \context Lyrics \nam 
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            \remove Bar_engraver
+            \remove Time_signature_engraver
+            StaffSymbol \override #'line-count = #2
+            StaffSymbol \override #'staff-space = #2
+            minimumVerticalExtent = #'(-3.0 . 4.0)
+        }
+        \translator {
+            \VoiceContext
+            \remove Stem_engraver
+        }
+    }   
+}
address@hidden lilypond
address@hidden 'percussion
+To typeset all kinds of simple percussion on one line staves.
address@hidden
+\include "drumpitch-init.ly"
+nam = \lyrics { tri trio trim gui guis guil cb cl tamb cab mar hc }
+mus = \notes  { tri trio trim gui guis guil cb cl tamb cab mar hc s16 }
+\score {
+    <
+        \apply #(drums->paper 'percussion) \context Staff <
+            \clef percussion
+            \mus
+        >
+        \context Lyrics \nam 
+    >
+    \paper {
+        \translator {
+            \StaffContext
+            \remove Bar_engraver
+            \remove Time_signature_engraver
+            StaffSymbol \override #'line-count = #1
+            minimumVerticalExtent = #'(-2.0 . 3.0)
+        }
+        \translator {
+            \VoiceContext
+            \remove Stem_engraver
+        }
+    }   
+}
address@hidden lilypond
address@hidden table
+
+If you don't like any of the predefined lists you can define your own
+list at the top of your file:
+
address@hidden, verbatim]
+#(define mydrums `(
+        (bassdrum     default   #f        ,(make-pitch -1 2 0))
+        (snare        default   #f        ,(make-pitch 0 1 0))
+        (hihat        cross     #f        ,(make-pitch 0 5 0))
+        (pedalhihat   xcircle   "stopped" ,(make-pitch 0 5 0))
+        (lowtom              diamond   #f        ,(make-pitch -1 6 0))
+))
+\include "drumpitch-init.ly"
+up = \notes { hh8 hh hh hh hhp4 hhp }
+down = \notes { bd4 sn bd toml8 toml }
+\score {    
+    \apply #(drums->paper 'mydrums) \context Staff <
+        \clef percussion
+        \context Voice = up { \voiceOne \up }
+        \context Voice = down { \voiceTwo \down }
+    >
+}
address@hidden lilypond
+
+To use a modified existing list instead of building your own from
+scratch you can append your modifications to the start of the existing
+list:
+
address@hidden
+#(define mydrums (append `(
+   (bassdrum default #f ,(make-pitch -1 2 0))
+   (lowtom   diamond #f ,(make-pitch -1 6 0))
+) drums ))
address@hidden example
+
address@hidden FIXME: Too many levels of headers when using subsubsections.
address@hidden Perhaps junk subsection ``Percussion staves''
address@hidden Percussion staves with normal staves
+When you include @file{drumpitch-init.ly} then the default pitches
+are overridden so that you after the inclusion cannot use the common
+dutch pitch names anymore. Hence you might wan't to reinclude
address@hidden after the drum-pattern-definitions:
address@hidden,verbatim]
+\include "drumpitch-init.ly"
+up = \notes { crashcymbal4 hihat8 halfopenhihat hh hh hh openhihat }
+down = \notes { bassdrum4 snare8 bd r bd sn4 }
+\include "nederlands.ly"
+bass = \notes \transpose c, { a4. e8 r e g e }
+\score {
+    <
+        \apply #(drums->paper 'drums) \context Staff = drums <
+            \clef percussion
+            \context Voice = up { \voiceOne \up }
+            \context Voice = down { \voiceTwo \down }
+        >
+        \context Staff = bass { \clef "F_8" \bass }
+    >
+}
address@hidden lilypond
+
address@hidden Percussion midi output
+In order to produce correct midi output you need to produce two score
+blocks - one for the paper and one for the midi.
+To use the percussion channel you set the property @code{instrument}
+to @code{'drums}. Because the drum-pitches themself are similar to the
+general midi pitches all you have to do is to insert the voices with
+none of the scheme functions to get the correct midi output:
+
address@hidden
+\score @{    
+    \apply #(drums->paper 'mydrums) \context Staff <
+        \clef percussion
+        \context Voice = up @{ \voiceOne \up @}
+        \context Voice = down @{ \voiceTwo \down @}
+    >
+    address@hidden@}
address@hidden
+\score @{    
+    \context Staff <
+        \property Staff.instrument = #'drums
+        \up \down
+    >
+    address@hidden@}
address@hidden
address@hidden example
+
address@hidden
 
+This scheme is to be concidered a temporary implementation. Even
+though the scheme will probably keep on working then the future might
+bring some other way of typesetting drums, and probably
+there will be made no great efforts in keeping things downwards
+compatible.
 @c . {Piano music}
 @node Piano music
 @section Piano music
Index: input/regression/accidental-octave.ly
===================================================================
RCS file: /home/lilypond/lilypond/input/regression/accidental-octave.ly,v
retrieving revision 1.2
diff -p -u -r1.2 accidental-octave.ly
--- input/regression/accidental-octave.ly       21 Mar 2002 00:44:50 -0000      
1.2
+++ input/regression/accidental-octave.ly       6 Jul 2002 18:36:31 -0000
@@ -1,3 +1,4 @@
+
 \version "1.5.43.rz1"
 
 \header {
Index: lily/accidental-engraver.cc
===================================================================
RCS file: /home/lilypond/lilypond/lily/accidental-engraver.cc,v
retrieving revision 1.19
diff -p -u -r1.19 accidental-engraver.cc
--- lily/accidental-engraver.cc 19 Jun 2002 19:06:33 -0000      1.19
+++ lily/accidental-engraver.cc 6 Jul 2002 18:36:32 -0000
@@ -87,6 +87,15 @@ public:
 };
 
 
+static void set_property_on_children (Translator_group * trans, const char * 
sym, SCM val)
+{
+  trans->set_property (sym, val);
+  for (SCM p = trans -> trans_group_list_; gh_pair_p (p); p = ly_cdr(p)) {
+    Translator_group *trg =  dynamic_cast<Translator_group*> 
(unsmob_translator (ly_car (p)));
+    set_property_on_children(trg,sym,ly_deep_copy(val));
+  }
+}
+
 Accidental_engraver::Accidental_engraver ()
 {
   accidental_placement_ = 0;
@@ -104,7 +113,7 @@ Accidental_engraver::initialize ()
       trans_ -> set_property ("localKeySignature",  ly_deep_copy 
(last_keysig_));
       trans_ = trans_->daddy_trans_l_;
     }
-  daddy_trans_l_->set_children_property ("localKeySignature", last_keysig_);
+  set_property_on_children (daddy_trans_l_,"localKeySignature", last_keysig_);
 }
 
 /*
@@ -455,7 +464,7 @@ Accidental_engraver::process_music ()
          trans_ -> set_property ("localKeySignature",  ly_deep_copy (sig));
          trans_ = trans_->daddy_trans_l_;
        }
-      daddy_trans_l_->set_children_property ("localKeySignature", sig);
+      set_property_on_children(daddy_trans_l_,"localKeySignature", sig);
 
       last_keysig_ = sig;
     }
Index: lily/auto-beam-engraver.cc
===================================================================
RCS file: /home/lilypond/lilypond/lily/auto-beam-engraver.cc,v
retrieving revision 1.74
diff -p -u -r1.74 auto-beam-engraver.cc
--- lily/auto-beam-engraver.cc  19 Jun 2002 19:06:33 -0000      1.74
+++ lily/auto-beam-engraver.cc  6 Jul 2002 18:36:32 -0000
@@ -63,6 +63,7 @@ private:
   Moment beam_start_location_;
 
   bool subdivide_beams_;
+  Moment beat_length_;
   
   // We act as if beam were created, and start a grouping anyway.
   Beaming_info_list*grouping_p_;  
@@ -249,7 +250,8 @@ Auto_beam_engraver::begin_beam ()
   grouping_p_ = new Beaming_info_list;
   beam_start_moment_ = now_mom ();
   beam_start_location_ = *unsmob_moment (get_property ("measurePosition"));
-  subdivide_beams_ = gh_scm2bool(get_property("subdivideBeams")); 
+  subdivide_beams_ = gh_scm2bool(get_property("subdivideBeams"));
+  beat_length_ = *unsmob_moment (get_property ("beatLength"));
 }
 
 
@@ -292,8 +294,7 @@ Auto_beam_engraver::typeset_beam ()
 {
   if (finished_beam_p_)
     {
-      finished_grouping_p_->beamify(*unsmob_moment (get_property 
("beatLength")),
-                                   subdivide_beams_);
+      finished_grouping_p_->beamify(beat_length_, subdivide_beams_);
       Beam::set_beaming (finished_beam_p_, finished_grouping_p_);
       typeset_grob (finished_beam_p_);
       finished_beam_p_ = 0;
@@ -481,5 +482,5 @@ stemRightBeamCount.
 ",
 /* creats*/       "Beam",
 /* acks  */       "stem-interface rest-interface beam-interface 
bar-line-interface",
-/* reads */       "autoBeaming autoBeamSettings subdivideBeams",
+/* reads */       "autoBeaming autoBeamSettings beatLength subdivideBeams",
 /* write */       "");
Index: lily/beam-engraver.cc
===================================================================
RCS file: /home/lilypond/lilypond/lily/beam-engraver.cc,v
retrieving revision 1.72
diff -p -u -r1.72 beam-engraver.cc
--- lily/beam-engraver.cc       7 Jun 2002 16:51:39 -0000       1.72
+++ lily/beam-engraver.cc       6 Jul 2002 18:36:32 -0000
@@ -38,6 +38,7 @@ protected:  
   Moment beam_start_mom_;
 
   bool subdivide_beams_;
+  Moment beat_length_;
 
   void typeset_beam ();
   void set_melisma (bool);
@@ -190,9 +191,7 @@ Beam_engraver::typeset_beam ()
 {
   if (finished_beam_p_)
     {
-      finished_beam_info_p_->beamify(*unsmob_moment (get_property 
("beatLength")),
-                                    subdivide_beams_);
-
+      finished_beam_info_p_->beamify(beat_length_, subdivide_beams_);
       Beam::set_beaming (finished_beam_p_, finished_beam_info_p_);
       typeset_grob (finished_beam_p_);
       delete finished_beam_info_p_;
@@ -215,7 +214,8 @@ Beam_engraver::start_translation_timeste
        {
          set_melisma (true);
        }
-      subdivide_beams_ = to_boolean(get_property("subdivideBeams")); 
+      subdivide_beams_ = to_boolean(get_property("subdivideBeams"));
+      beat_length_ = *unsmob_moment (get_property ("beatLength"));
     }
 }
 
@@ -306,7 +306,7 @@ ENTER_DESCRIPTION(Beam_engraver,
 printed with flags instead of beams.",
 /* creats*/       "Beam",
 /* acks  */       "stem-interface rest-interface",
-/* reads */       "beamMelismaBusy subdivideBeams",
+/* reads */       "beamMelismaBusy beatLength subdivideBeams",
 /* write */       "");
 
 
@@ -348,6 +348,6 @@ are at grace points in time.
 ",
 /* creats*/       "Beam",
 /* acks  */       "stem-interface rest-interface",
-/* reads */       "beamMelismaBusy subdivideBeams",
+/* reads */       "beamMelismaBusy beatLength subdivideBeams",
 /* write */       "");
 
Index: lily/translator-group.cc
===================================================================
RCS file: /home/lilypond/lilypond/lily/translator-group.cc,v
retrieving revision 1.82
diff -p -u -r1.82 translator-group.cc
--- lily/translator-group.cc    18 May 2002 23:45:15 -0000      1.82
+++ lily/translator-group.cc    6 Jul 2002 18:36:33 -0000
@@ -312,16 +312,6 @@ Translator_group::internal_set_property 
   properties_dict ()->set (sym, val);
 }
 
-void
-Translator_group::internal_set_children_property (SCM sym, SCM val)
-{
-  internal_set_property (sym, val);
-  for (SCM p = trans_group_list_; gh_pair_p (p); p = ly_cdr(p)) {
-    Translator_group *trg =  dynamic_cast<Translator_group*> 
(unsmob_translator (ly_car (p)));
-    trg->internal_set_children_property(sym,ly_deep_copy(val));
-  }
-}
-
 /*
   TODO: look up to check whether we have inherited var? 
  */
Index: lily/include/translator-group.hh
===================================================================
RCS file: /home/lilypond/lilypond/lily/include/translator-group.hh,v
retrieving revision 1.42
diff -p -u -r1.42 translator-group.hh
--- lily/include/translator-group.hh    21 Mar 2002 00:44:50 -0000      1.42
+++ lily/include/translator-group.hh    6 Jul 2002 18:36:33 -0000
@@ -20,7 +20,6 @@
 // egcs
 typedef void (Translator::*Method_pointer) (void);
 #define set_property(x,y) internal_set_property(ly_symbol2scm(x),y)
-#define set_children_property(x,y) 
internal_set_children_property(ly_symbol2scm(x),y)
 
 class Scheme_hash_table;
 
@@ -44,7 +43,6 @@ public:
 
   void unset_property (SCM var_sym);
   void internal_set_property (SCM var_sym, SCM value);  
-  void internal_set_children_property (SCM var_sym, SCM value);  
   Translator_group *where_defined (SCM name_sym) const;
 
   String id_str_;
Index: ly/property-init.ly
===================================================================
RCS file: /home/lilypond/lilypond/ly/property-init.ly,v
retrieving revision 1.14
diff -p -u -r1.14 property-init.ly
--- ly/property-init.ly 25 May 2002 11:45:27 -0000      1.14
+++ ly/property-init.ly 6 Jul 2002 18:36:34 -0000
@@ -148,7 +148,7 @@ voiceAccidentals = {
 % in other octaves and in the next measure.
 modernAccidentals = {
   \property Score.extraNatural = ##f
-  \property Score.autoAccidentals = #'(Staff (same-octave . 0) (any-octave . 
0) (any-octave . 1))
+  \property Score.autoAccidentals = #'(Staff (same-octave . 0) (any-octave . 
0) (same-octave . 1))
   \property Score.autoCautionaries = #'()  
 }
 
@@ -156,7 +156,7 @@ modernAccidentals = {
 modernCautionaries = {
   \property Score.extraNatural = ##f
   \property Score.autoAccidentals = #'(Staff (same-octave . 0))
-  \property Score.autoCautionaries = #'(Staff (any-octave . 0) (any-octave . 
1))  
+  \property Score.autoCautionaries = #'(Staff (any-octave . 0) (same-octave . 
1))  
 }
 
 % Multivoice accidentals to be read both by musicians playing one voice
@@ -165,8 +165,8 @@ modernCautionaries = {
 modernVoiceAccidentals = {
   \property Staff.extraNatural = ##f
   \property Staff.autoAccidentals = #'(
-    Voice (same-octave . 0) (any-octave . 0) (any-octave . 1)
-    Staff (same-octave . 0) (any-octave . 0) (any-octave . 1)
+    Voice (same-octave . 0) (any-octave . 0) (same-octave . 1)
+    Staff (same-octave . 0) (any-octave . 0) (same-octave . 1)
   )
   \property Staff.autoCautionaries = #'()  
 }
@@ -179,8 +179,8 @@ modernVoiceCautionaries = {
     Voice (same-octave . 0) 
   )
   \property Staff.autoCautionaries = #'(
-    Voice (any-octave . 0) (any-octave . 1)
-    Staff (same-octave . 0) (any-octave . 0) (any-octave . 1)
+    Voice (any-octave . 0) (same-octave . 1)
+    Staff (same-octave . 0) (any-octave . 0) (same-octave . 1)
   )  
 }
 
@@ -188,11 +188,22 @@ modernVoiceCautionaries = {
 % Accidentals are cancelled across the staves in the same grand staff as well
 pianoAccidentals = {
   \property GrandStaff.autoAccidentals = #'(
-    Staff (same-octave . 0) (any-octave . 0) (any-octave . 1)
-    GrandStaff (any-octave . 1)
+    Staff (same-octave . 0) (any-octave . 0) (same-octave . 1)
+    GrandStaff (any-octave . 0) (same-octave . 1)
   )
   \property GrandStaff.autoCautionaries = #'()  
 }
+
+pianoCautionaries = {
+  \property GrandStaff.autoAccidentals = #'(
+    Staff (same-octave . 0)
+  )
+  \property GrandStaff.autoCautionaries = #'(
+    Staff (any-octave . 0) (same-octave . 1)
+    GrandStaff (any-octave . 0) (same-octave . 1)
+  )  
+}
+
 
 % Do not reset the key at the start of a measure.  Accidentals will be
 % printed only once and are in effect until overridden, possibly many
Index: scm/drums.scm
===================================================================
RCS file: /home/lilypond/lilypond/scm/drums.scm,v
retrieving revision 1.6
diff -p -u -r1.6 drums.scm
--- scm/drums.scm       12 Jun 2002 08:54:40 -0000      1.6
+++ scm/drums.scm       6 Jul 2002 18:36:34 -0000
@@ -37,9 +37,14 @@
        (crashcymbalb     cymcb ,(make-pitch -1 5 0))
        (vibraslap        vibs  ,(make-pitch -1 5 1))
        (ridecymbalb      cymrb ,(make-pitch -1 6 0))
+       (mutehibongo      bohm  ,(make-pitch -1 6 1))
        (hibongo          boh   ,(make-pitch 0 0 0))
+       (openhibongo      boho  ,(make-pitch 0 1 -2))
+       (mutelobongo      bolm  ,(make-pitch -1 6 2))
        (lobongo          bol   ,(make-pitch 0 0 1))
+       (openlobongo      bolo  ,(make-pitch 0 1 -1))
        (mutehiconga      cghm  ,(make-pitch 0 1 0))
+       (muteloconga      cglm  ,(make-pitch 0 2 -2))
        (openhiconga      cgho  ,(make-pitch 0 1 1))
        (hiconga          cgh   ,(make-pitch 0 2 -1))
        (openloconga      cglo  ,(make-pitch 0 1 2))
@@ -89,10 +94,10 @@
        (hihat            cross         #f        ,(make-pitch 0 3 0))
        (highfloortom     default       #f        ,(make-pitch -1 5 0))
        (pedalhihat       cross         #f        ,(make-pitch -1 2 0))
-       (lowtom           default       #f        ,(make-pitch 0 0 0))
+       (lowtom           default       #f        ,(make-pitch -1 6 0))
        (openhihat        cross         "open"    ,(make-pitch 0 3 0))
        (halfopenhihat    xcircle       #f        ,(make-pitch 0 3 0))
-       (lowmidtom        default       #f        ,(make-pitch 0 1 0))
+       (lowmidtom        default       #f        ,(make-pitch 0 0 0))
        (himidtom         default       #f        ,(make-pitch 0 2 0))
        (crashcymbala     xcircle       #f        ,(make-pitch 0 5 0))
        (crashcymbal      xcircle       #f        ,(make-pitch 0 5 0))
@@ -119,7 +124,8 @@
 (define congas `(
        (losidestick      cross         #f        ,(make-pitch -1 6 0))
        (loconga          default       #f        ,(make-pitch -1 6 0))
-       (openloconga      default       ,"open"   ,(make-pitch -1 6 0))
+       (openloconga      default       "open"    ,(make-pitch -1 6 0))
+       (muteloconga      default       "stopped" ,(make-pitch -1 6 0))
        (hisidestick      cross         #f        ,(make-pitch 0 1 0))
        (hiconga          default       #f        ,(make-pitch 0 1 0))
        (openhiconga      default       "open"    ,(make-pitch 0 1 0))
@@ -128,8 +134,14 @@
  ))
 
 (define bongos `(
+       (losidestick      cross         #f        ,(make-pitch -1 6 0))
        (lobongo          default       #f        ,(make-pitch -1 6 0))
+       (openlobongo      default       "open"    ,(make-pitch -1 6 0))
+       (mutelobongo      default       "stopped" ,(make-pitch -1 6 0))
+       (hisidestick      cross         #f        ,(make-pitch 0 1 0))
        (hibongo          default       #f        ,(make-pitch 0 1 0))
+       (openhibongo      default       "open"    ,(make-pitch 0 1 0))
+       (mutehibongo      default       "stopped" ,(make-pitch 0 1 0))
  ))
 
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]