]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix #1009 (\transpose error with pitch alteration > double).
authorNeil Puttock <n.puttock@gmail.com>
Sun, 21 Feb 2010 17:10:22 +0000 (17:10 +0000)
committerNeil Puttock <n.puttock@gmail.com>
Sun, 21 Feb 2010 17:10:22 +0000 (17:10 +0000)
* lily/music.cc (transpose_mutable):

  if delta pitch has an alteration larger than a double, normalize using
  Pitch::normalized (), preventing invalid alterations being converted to strings

  also normalize transposed pitch (this changes note name, but ensures valid
  pitch)

* lily/pitch.cc (normalized):

  new method

lily/include/pitch.hh
lily/music.cc
lily/pitch.cc

index 676a30c093f8d7811a251e6a3b2177401490ee91..c69a58a893bc3be79c78d38242dd84f75ca8c0b9 100644 (file)
   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef MUSICAL_PITCH_HH
-#define MUSICAL_PITCH_HH
+#ifndef PITCH_HH
+#define PITCH_HH
 
 #include "lily-proto.hh"
 #include "smobs.hh"
 #include "rational.hh"
 
 
-/** A "tonal" pitch. This is a pitch used in diatonal western music
-    (24 quartertones in an octave), as opposed to a frequency in Hz or a
-    integer number of semitones.
-
-    Pitch is lexicographically ordered by (octave, notename,
-    alteration).
+/*
+  A "tonal" pitch.  This is a pitch used in diatonal western music
+  (24 quartertones in an octave), as opposed to a frequency in Hz or a
+  integer number of semitones.
 
+  Pitch is lexicographically ordered by (octave, notename, alteration).
 */
+
 class Pitch
 {
 private:
@@ -60,6 +60,8 @@ public:
   Pitch transposed (Pitch) const;
   Pitch to_relative_octave (Pitch) const;
 
+  Pitch normalized () const;
+
   static int compare (Pitch const &, Pitch const &);
 
   int steps () const;
@@ -86,15 +88,15 @@ enum {
   DOUBLE_SHARP,
 };
 
-extern Rational  DOUBLE_FLAT_ALTERATION;
-extern Rational  THREE_Q_FLAT_ALTERATION;
-extern Rational  FLAT_ALTERATION;
-extern Rational  SEMI_FLAT_ALTERATION;
-extern Rational  NATURAL_ALTERATION;
-extern Rational  SEMI_SHARP_ALTERATION;
-extern Rational  SHARP_ALTERATION;
-extern Rational  THREE_Q_SHARP_ALTERATION;
-extern Rational  DOUBLE_SHARP_ALTERATION;
+extern Rational DOUBLE_FLAT_ALTERATION;
+extern Rational THREE_Q_FLAT_ALTERATION;
+extern Rational FLAT_ALTERATION;
+extern Rational SEMI_FLAT_ALTERATION;
+extern Rational NATURAL_ALTERATION;
+extern Rational SEMI_SHARP_ALTERATION;
+extern Rational SHARP_ALTERATION;
+extern Rational THREE_Q_SHARP_ALTERATION;
+extern Rational DOUBLE_SHARP_ALTERATION;
 
 SCM ly_pitch_diff (SCM pitch, SCM root);
 SCM ly_pitch_transpose (SCM p, SCM delta);
@@ -105,5 +107,4 @@ INSTANTIATE_COMPARE (Pitch, Pitch::compare);
 extern SCM pitch_less_proc;
 Pitch pitch_interval (Pitch const &from, Pitch const &to);
 
-#endif /* MUSICAL_PITCH_HH */
-
+#endif /* PITCH_HH */
index 6a4aaa7dab29072b1045fdd6c9922ef47aadda36..d5170adc9c2eb42a2899fc7fcd48b046acfb6106 100644 (file)
@@ -50,7 +50,7 @@ Music::Music (SCM init)
 {
   length_callback_ = SCM_EOL;
   start_callback_ = SCM_EOL;
-  
+
   length_callback_ = get_property ("length-callback");
   if (!ly_is_procedure (length_callback_))
     length_callback_ = duration_length_callback_proc;
@@ -172,7 +172,8 @@ Music::to_relative_octave (Pitch last)
   SCM callback = get_property ("to-relative-callback");
   if (ly_is_procedure (callback))
     {
-      Pitch *p = unsmob_pitch (scm_call_2 (callback, self_scm (), last.smobbed_copy ()));
+      Pitch *p = unsmob_pitch (scm_call_2 (callback, self_scm (),
+                                          last.smobbed_copy ()));
       return *p;
     }
 
@@ -190,7 +191,8 @@ Music::compress (Moment factor)
   compress_music_list (get_property ("elements"), factor);
   Duration *d = unsmob_duration (get_property ("duration"));
   if (d)
-    set_property ("duration", d->compressed (factor.main_part_).smobbed_copy ());
+    set_property ("duration",
+                 d->compressed (factor.main_part_).smobbed_copy ());
 }
 
 /*
@@ -205,14 +207,23 @@ transpose_mutable (SCM alist, Pitch delta)
       SCM prop = scm_car (entry);
       SCM val = scm_cdr (entry);
       SCM new_val = val;
-      
+
       if (Pitch *p = unsmob_pitch (val))
        {
          Pitch transposed = p->transposed (delta);
          if (transposed.get_alteration ().abs () > Rational (1,1))
            {
-             warning (_f ("transposition by %s makes alteration larger than double",
-                          delta.to_string ()));
+             string delta_str;
+             if (delta.get_alteration ().abs () > Rational (1, 1))
+               delta_str = (delta.normalized ().to_string ()
+                            + " " + _ ("(normalized pitch)"));
+             else
+               delta_str = delta.to_string ();
+
+             warning (_f ("Transposing %s by %s makes alteration larger than double",
+                          p->to_string (),
+                          delta_str));
+             transposed = transposed.normalized ();
            }
 
          new_val = transposed.smobbed_copy ();
@@ -265,9 +276,7 @@ Music::to_event () const
 
   // catch programming mistakes.
   if (!internal_is_music_type (class_name))
-    {
-      programming_error ("Not a music type");
-    }
+    programming_error ("Not a music type");
 
   Stream_event *e = new Stream_event (class_name, mutable_property_alist_);
   Moment length = get_length ();
@@ -333,6 +342,5 @@ Music::duration_length_callback (SCM m)
 Music *
 unsmob_music (SCM m)
 {
-  return dynamic_cast<Music*> (unsmob_prob (m));
+  return dynamic_cast<Music *> (unsmob_prob (m));
 }
-
index 7b3eb02d232bed422ff2df3bd322342bf99f6e1a..e9872fdf8eb09ba8e9bb534b52644583b7ef2744 100644 (file)
@@ -156,7 +156,7 @@ Pitch::to_string () const
   string s = ::to_string (char (n + 'a'));
   Rational qtones = alteration_ * Rational (4,1);
   int qt = int (rint (Real (qtones)));
-      
+
   s += string (accname[qt + 4]);
   if (octave_ >= 0)
     {
@@ -288,6 +288,14 @@ Pitch::transposed (Pitch d) const
   return p;
 }
 
+Pitch
+Pitch::normalized () const
+{
+  Pitch p = *this;
+  p.normalize ();
+  return p;
+}
+
 Rational NATURAL_ALTERATION (0);
 Rational FLAT_ALTERATION (-1, 2);
 Rational DOUBLE_FLAT_ALTERATION (-1);