-/*
- key-def.cc -- implement Key_def
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2000 Jan Nieuwenhuizen <janneke@gnu.org>
-
- */
-
-#include "key-def.hh"
-#include "debug.hh"
-
-Key_def::Key_def ()
-{
- modality_i_ = 0;
- ordinary_key_b_ = false;
-}
-
-int
-Key_def::ordinary_accidentals_i () const
-{
- if (!ordinary_key_b_)
- {
- programming_error ("Accidentals requested for non-conventional key");
- return 0;
- }
-
- int p;
- if (pitch_arr_.size () < 1)
- {
- warning (_ ("No key name, assuming `C'"));
- p = 0;
- }
- else
- {
- p = pitch_arr_[0].semitone_pitch ();
- p += modality_i_;
- }
- /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
- int accidentals_i = (7*p) % 12;
- accidentals_i = (accidentals_i + 18) % 12 -6;
-
- /* Correct from flats to sharps or vice versa */
- if (accidentals_i * pitch_arr_[0].accidental_i_ < 0)
- accidentals_i += 12 * sign (pitch_arr_[0].accidental_i_);
- return accidentals_i;
-}
-
-int
-Key_def::flats_i () const
-{
- if (ordinary_key_b_)
- return 0 >? -ordinary_accidentals_i ();
- int flats_i = 0;
- for (int i = 0; i < pitch_arr_.size (); i++)
- {
- if (pitch_arr_[i].accidental_i_ < 0)
- flats_i -= pitch_arr_[i].accidental_i_;
- }
- return flats_i;
-}
-
-bool
-Key_def::minor_b () const
-{
- return modality_i_ == 3;
-}
-
-int
-Key_def::sharps_i () const
-{
- if (ordinary_key_b_)
- return 0 >? ordinary_accidentals_i ();
- int sharps_i = 0;
- for (int i = 0; i < pitch_arr_.size (); i++)
- {
- if (pitch_arr_[i].accidental_i_ > 0)
- sharps_i += pitch_arr_[i].accidental_i_;
- }
- return sharps_i;
-}
-
-void
-Key_def::transpose (Musical_pitch d)
-{
- if (ordinary_key_b_ )
- {
- if (pitch_arr_.size () > 0)
- pitch_arr_[0].transpose (d);
- else
- {
- warning (_ ("Don't know how handle empty keys")); // TODO
- }
- }
- else
- {
- Array<Musical_pitch> old_pitch_arr_;
- for (int i = 0; i < pitch_arr_.size (); i++)
- {
- old_pitch_arr_.push (pitch_arr_[i]);
- }
- // set accidentals for \key d (as in Key_engraver::read_req)
- // (later called "new accidentals")
- int p = d.semitone_pitch ();
- /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
- int accidentals_i = (7*p) % 12;
- accidentals_i = (accidentals_i + 18) % 12 -6;
-
- /* Correct from flats to sharps or vice versa */
- if (accidentals_i * d.accidental_i_ < 0)
- accidentals_i += 12 * sign (d.accidental_i_);
-
- pitch_arr_.clear ();
- if (accidentals_i < 0)
- {
- int accidental = 6 ; // First accidental: bes
- for ( ; accidentals_i < 0 ; accidentals_i++ )
- {
- Musical_pitch m;
- m.accidental_i_ = -1;
- m.notename_i_ = accidental;
- pitch_arr_.push (m);
-
- accidental = (accidental + 3) % 7 ;
- }
- }
- else
- {
- int accidental = 3 ; // First accidental: fis
- for ( ; accidentals_i > 0 ; accidentals_i-- )
- {
- Musical_pitch m;
- m.accidental_i_ = 1;
- m.notename_i_ = accidental;
- pitch_arr_.push (m);
-
- accidental = (accidental + 4) % 7 ;
- }
- }
- // Check if transposed old accidentals and the new ones coincide
- accidentals_i = pitch_arr_.size ();
- int acc_found;
- Musical_pitch mm;
- for (int i=0; i < old_pitch_arr_.size (); i++)
- {
- acc_found = 0;
- mm = old_pitch_arr_[i];
- mm.transpose (d);
- for (int j=0; ( (j < accidentals_i) && (acc_found == 0)); j++)
- {
- if (pitch_arr_[j].notename_i_ == mm.notename_i_)
- {
- if (mm.accidental_i_ == 0)
- {
- // remove new accidental
- pitch_arr_.del (j);
- accidentals_i--;
- acc_found = 1;
- }
- else
- {
- // change new accidental
- pitch_arr_[j].accidental_i_ = mm.accidental_i_;
- acc_found = 1;
- }
- }
- }
- if (acc_found == 0)
- {
- // add transposed old accidental
- pitch_arr_.push (mm);
- }
- }
- }
-}
-
-void
-Key_def::squash_octaves ()
-{
- for (int i=0; i < pitch_arr_.size (); i++)
- {
- pitch_arr_[i].octave_i_ = 0;
- }
-}