lilypond-devel
[Top][All Lists]
Advanced

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

Accidentals patch


From: Rune Zedeler
Subject: Accidentals patch
Date: Mon, 08 Oct 2001 00:05:48 +0200

I've restructured the accidentals engraver, and added property
autoReminders, automatically creating reminder accidentals.
Please comment on the new structure of the engraver.
Still needs lots of clean up - as I do not entirely understand the idea
of the tie-break handling. - Afaics it handles tie breaks the same way
as before. - But I do not really see the idea - i.e. in the example
added to test/ I do not understand why the 2nd note of measure 6 should
get a sharp...
I cannot build the docu, but hopefully the minor updates, I have added,
works properly.


-Rune
diff -urN lilypond-1.5.15/CHANGES lilypond-1.5.15.rz1/CHANGES
--- lilypond-1.5.15/CHANGES     Fri Oct  5 18:02:16 2001
+++ lilypond-1.5.15.rz1/CHANGES Sun Oct  7 23:34:18 2001
@@ -1,3 +1,9 @@
+1.5.15.rz1
+==========
+
+* added property autoReminders, automatically creating reminder
+  accidentals. - major changes to accidental-engraver.
+
 1.5.14.jcn6
 ===========
 
diff -urN lilypond-1.5.15/VERSION lilypond-1.5.15.rz1/VERSION
--- lilypond-1.5.15/VERSION     Fri Oct  5 19:51:30 2001
+++ lilypond-1.5.15.rz1/VERSION Sun Oct  7 20:00:02 2001
@@ -2,7 +2,7 @@
 MAJOR_VERSION=1
 MINOR_VERSION=5
 PATCH_LEVEL=15
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=rz1
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff -urN lilypond-1.5.15/input/test/accidentals.ly 
lilypond-1.5.15.rz1/input/test/accidentals.ly
--- lilypond-1.5.15/input/test/accidentals.ly   Thu Jan  1 01:00:00 1970
+++ lilypond-1.5.15.rz1/input/test/accidentals.ly       Sun Oct  7 23:16:49 2001
@@ -0,0 +1,23 @@
+% \version "1.5.15.rz1"
+
+mel = \notes {
+ d4  dis dis d | d dis disis dis | d des disis d | dis deses d dis ~ | dis dis 
~ dis dis ~ | \break
+ dis dis cis c | c cis cisis cis | c ces cisis c | cis ceses c cis ~ | cis cis 
~ cis cis \bar "|."  | \break
+}
+
+\score { \notes \context Staff \transpose c''' {
+   \key d \major
+   \mel
+   \property Score.autoReminders = #'cautionary
+   < s1^"$\\backslash$property Score.autoReminders = \\#'cautionary" \mel >
+   \property Score.autoReminders = #'accidental
+   < s1^"$\\backslash$property Score.autoReminders = \\#'accidental" \mel >
+   \property Score.autoReminders = ##f
+   \property Score.forgetAccidentals = ##t
+   < s1^"$\\backslash$property Score.forgetAccidentals = \\#\\#t" \mel >
+   \property Score.forgetAccidentals = ##f
+   \property Score.noResetKey = ##t
+   < s1^"$\\backslash$property Score.noResetKey = \\#\\#t" \mel >
+  }
+}
+
diff -urN lilypond-1.5.15/lily/accidental-engraver.cc 
lilypond-1.5.15.rz1/lily/accidental-engraver.cc
--- lilypond-1.5.15/lily/accidental-engraver.cc Thu Oct  4 00:27:40 2001
+++ lilypond-1.5.15.rz1/lily/accidental-engraver.cc     Sun Oct  7 23:45:53 2001
@@ -1,7 +1,8 @@
 /*
-  local-key-engraver.cc -- implement accidental_engraver
+  accidental-engraver.cc -- implement accidental_engraver
 
   (c)  1997--2001 Han-Wen Nienhuys <address@hidden>
+  Modified 2001 by Rune Zedeler <address@hidden>
 */
 
 #include "musical-request.hh"
@@ -38,6 +39,7 @@
   virtual void acknowledge_grob (Grob_info);
   virtual void stop_translation_timestep ();
   virtual void initialize ();
+  virtual int  number_accidentals (SCM sig, Note_req *);
   virtual void create_grobs ();
   virtual void finalize ();
 public:
@@ -69,6 +71,34 @@
 {
   last_keysig_ = get_property ("keySignature");
   daddy_trans_l_->set_property ("localKeySignature",  last_keysig_);  
+  daddy_trans_l_->set_property ("lazyKeySignature",   last_keysig_);  
+}
+
+/** calculates the number of accidentals on basis of the current local time sig
+  * (passed as argument).
+  * Returns number of accidentals (0, 1 or 2).
+  *   Negative (-1 or -2) if accidental has changed.
+  **/
+int
+Accidental_engraver::number_accidentals (SCM sig, Note_req * note_l)
+{
+  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_;
+  
+  SCM prev = scm_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), sig);
+  if (prev == SCM_BOOL_F)
+    prev = scm_assoc (gh_int2scm (n), sig);
+  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;
+
+  int num;
+  if (a==p && !to_boolean (note_l->get_mus_property ("force-accidental"))) 
num=0;
+  else if ( (abs(a)<abs(p) || p*a<0) && a!=0 ) num=2;
+  else num=1;
+  
+  return a==p ? num : -num;
 }
 
 void
@@ -77,26 +107,41 @@
   if (!key_item_p_ && mel_l_arr_.size ()) 
     {
       SCM localsig = get_property ("localKeySignature");
-  
+      SCM lazysig = get_property ("lazyKeySignature");
+
       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_;
-         
+         int local_num = number_accidentals(localsig,note_l);
+         bool local_diff = local_num<0; local_num = abs(local_num);
+         int lazy_num = number_accidentals(lazysig,note_l);
+         bool lazy_diff = lazy_num<0; lazy_num = abs(lazy_num);
+
+         int num;
+         bool different;
+         bool cautionary = to_boolean (note_l->get_mus_property 
("cautionary"));
+         if (to_boolean (get_property ("noResetKey"))) {
+           num = lazy_num;
+           different = lazy_diff;
+         }
+         else if (gh_equal_p (get_property 
("autoReminders"),ly_symbol2scm("cautionary"))
+                  || gh_equal_p (get_property 
("autoReminders"),ly_symbol2scm("accidental"))) {
+           num = max(local_num,lazy_num);
+           if (gh_equal_p (get_property 
("autoReminders"),ly_symbol2scm("cautionary"))
+               && lazy_num>local_num)
+             cautionary = true;
+         }
+         else {
+           num = local_num;
+           different = local_diff;
+         }
+
          /* 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;
@@ -115,17 +160,7 @@
                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 (num)
            {
              if (!key_item_p_) 
                {
@@ -142,37 +177,36 @@
                }
 
              
-             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,
+                                        cautionary,
+                                        num==2,
                                         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?
-
+           (???? -Rune )
           */
+         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_;
+         SCM ON = gh_cons (gh_int2scm (o), gh_int2scm (n));
          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.
-
+               (????? -Rune )
               */
-             localsig = scm_assoc_set_x (localsig, gh_cons (gh_int2scm (o),
-                                                            gh_int2scm (n)),
-                                         SCM_BOOL_T); 
-
+             localsig = scm_assoc_set_x (localsig, ON, SCM_BOOL_T); 
+             lazysig = scm_assoc_set_x  (lazysig,  ON, SCM_BOOL_T); 
            }
          else if (!forget)
            {
@@ -180,17 +214,13 @@
                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)); 
-
+             localsig = scm_assoc_set_x (localsig, ON, gh_int2scm (a)); 
+             lazysig = scm_assoc_set_x  (lazysig,  ON, gh_int2scm (a)); 
            }
         }
-
-
-  
   
       daddy_trans_l_->set_property ("localKeySignature",  localsig);
+      daddy_trans_l_->set_property ("lazyKeySignature",   lazysig);
     }
   
 
@@ -274,11 +304,11 @@
   if (last_keysig_ != sig) 
     {
       daddy_trans_l_->set_property ("localKeySignature",  ly_deep_copy (sig));
+      daddy_trans_l_->set_property ("lazyKeySignature",  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));
     }
 }
diff -urN lilypond-1.5.15/scm/translator-description.scm 
lilypond-1.5.15.rz1/scm/translator-description.scm
--- lilypond-1.5.15/scm/translator-description.scm      Mon Sep 24 01:04:29 2001
+++ lilypond-1.5.15.rz1/scm/translator-description.scm  Sun Oct  7 23:42:20 2001
@@ -19,6 +19,15 @@
   (interfaces-acked all)
   (properties-read combineParts noDirection soloADue soloText soloIIText 
aDueText split-interval unison solo unisilence unirhythm)
   )
+ (Accidental_engraver 
+  (name . "Accidental_engraver")
+  (description . "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")
+  (grobs-created Accidentals)
+  (interfaces-acked grob-interface)
+  (properties-read localKeySignature forgetAccidentals noResetKey 
autoReminders)
+  )
  (Arpeggio_engraver 
 
   (name . "Arpeggio_engraver")
@@ -38,7 +47,7 @@
 ")
   (grobs-created Beam)
   (interfaces-acked grob-interface)
-  (properties-read noAutoBeaming autoBeamSettings)
+  (properties-read noAutoBeaming autoBeamSettings subdivideBeams)
   )
  (Axis_group_engraver 
 
@@ -73,7 +82,7 @@
 printed with flags instead of beams.")
   (grobs-created Beam)
   (interfaces-acked grob-interface)
-  (properties-read beamMelismaBusy)
+  (properties-read beamMelismaBusy subdivideBeams)
   )
  (Break_align_engraver 
 
@@ -209,15 +218,6 @@
   (grobs-created KeySignature)
   (interfaces-acked grob-interface)
   (properties-read keySignature explicitKeySignatureVisibility 
createKeyOnClefChange keyAccidentalOrder keySignature)
-  )
- (Local_key_engraver 
-  (name . "Local_key_engraver")
-  (description . "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")
-  (grobs-created Accidentals)
-  (interfaces-acked grob-interface)
-  (properties-read localKeySignature forgetAccidentals noResetKey)
   )
  (Lyric_engraver 
 
diff -urN lilypond-1.5.15/scm/translator-property-description.scm 
lilypond-1.5.15.rz1/scm/translator-property-description.scm
--- lilypond-1.5.15/scm/translator-property-description.scm     Fri Sep 28 
23:58:21 2001
+++ lilypond-1.5.15.rz1/scm/translator-property-description.scm Sun Oct  7 
23:40:45 2001
@@ -90,6 +90,9 @@
 melismata, and align lyrics accordingly.
 ")
 
+(translator-property-description 'autoReminders symbol? "If set to 
@samp{accidental} or @samp{cautionary},
+a (reminder) accidental automatically is inserted whenever an accidental is 
reverted - even after a bar."
+
 (translator-property-description 'barAlways boolean? " If set to true a bar 
line is drawn after each note.
 ")
 (translator-property-description 'barCheckNoSynchronize boolean? "If set, 
don't reset measurePosition when finding a bbarcheck. This
@@ -308,6 +311,8 @@
 .")
 (translator-property-description 'stemRightBeamCount integer? "idem, for the 
right side.")
 (translator-property-description 'stz string? "Abbreviated form for a stanza, 
see also Stanza property.")
+(translator-property-description 'subdivideBeams boolean? "If set, multiple 
beams will be subdivided at beat
+positions - by only drawing one beam over the beat.")
 (translator-property-description 'textNonEmpty boolean? " If set
 to true then text placed above or below the staff is not assumed to
 have zero width.  @code{\fatText} and @code{\emptyText} are predefined

reply via email to

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