lilypond-1.3.124
[lilypond.git] / lily / key-def.cc
blob523c2144623e764c5df9ce22dd6a1fee099219eb
1 /*
2 key-def.cc -- implement Key_def
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2000 Jan Nieuwenhuizen <janneke@gnu.org>
8 */
10 #include "key-def.hh"
11 #include "debug.hh"
13 Key_def::Key_def ()
15 modality_i_ = 0;
16 ordinary_key_b_ = false;
19 int
20 Key_def::ordinary_accidentals_i () const
22 if (!ordinary_key_b_)
24 programming_error ("Accidentals requested for non-conventional key");
25 return 0;
28 int p;
29 if (pitch_arr_.size () < 1)
31 warning (_ ("No key name, assuming `C'"));
32 p = 0;
34 else
36 p = pitch_arr_[0].semitone_pitch ();
37 p += modality_i_;
39 /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
40 int accidentals_i = (7*p) % 12;
41 accidentals_i = (accidentals_i + 18) % 12 -6;
43 /* Correct from flats to sharps or vice versa */
44 if (accidentals_i * pitch_arr_[0].accidental_i_ < 0)
45 accidentals_i += 12 * sign (pitch_arr_[0].accidental_i_);
46 return accidentals_i;
49 int
50 Key_def::flats_i () const
52 if (ordinary_key_b_)
53 return 0 >? -ordinary_accidentals_i ();
54 int flats_i = 0;
55 for (int i = 0; i < pitch_arr_.size (); i++)
57 if (pitch_arr_[i].accidental_i_ < 0)
58 flats_i -= pitch_arr_[i].accidental_i_;
60 return flats_i;
63 bool
64 Key_def::minor_b () const
66 return modality_i_ == 3;
69 int
70 Key_def::sharps_i () const
72 if (ordinary_key_b_)
73 return 0 >? ordinary_accidentals_i ();
74 int sharps_i = 0;
75 for (int i = 0; i < pitch_arr_.size (); i++)
77 if (pitch_arr_[i].accidental_i_ > 0)
78 sharps_i += pitch_arr_[i].accidental_i_;
80 return sharps_i;
83 void
84 Key_def::transpose (Musical_pitch d)
86 if (ordinary_key_b_ )
88 if (pitch_arr_.size () > 0)
89 pitch_arr_[0].transpose (d);
90 else
92 warning (_ ("Don't know how handle empty keys")); // TODO
95 else
97 Array<Musical_pitch> old_pitch_arr_;
98 for (int i = 0; i < pitch_arr_.size (); i++)
100 old_pitch_arr_.push (pitch_arr_[i]);
102 // set accidentals for \key d (as in Key_engraver::read_req)
103 // (later called "new accidentals")
104 int p = d.semitone_pitch ();
105 /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
106 int accidentals_i = (7*p) % 12;
107 accidentals_i = (accidentals_i + 18) % 12 -6;
109 /* Correct from flats to sharps or vice versa */
110 if (accidentals_i * d.accidental_i_ < 0)
111 accidentals_i += 12 * sign (d.accidental_i_);
113 pitch_arr_.clear ();
114 if (accidentals_i < 0)
116 int accidental = 6 ; // First accidental: bes
117 for ( ; accidentals_i < 0 ; accidentals_i++ )
119 Musical_pitch m;
120 m.accidental_i_ = -1;
121 m.notename_i_ = accidental;
122 pitch_arr_.push (m);
124 accidental = (accidental + 3) % 7 ;
127 else
129 int accidental = 3 ; // First accidental: fis
130 for ( ; accidentals_i > 0 ; accidentals_i-- )
132 Musical_pitch m;
133 m.accidental_i_ = 1;
134 m.notename_i_ = accidental;
135 pitch_arr_.push (m);
137 accidental = (accidental + 4) % 7 ;
140 // Check if transposed old accidentals and the new ones coincide
141 accidentals_i = pitch_arr_.size ();
142 int acc_found;
143 Musical_pitch mm;
144 for (int i=0; i < old_pitch_arr_.size (); i++)
146 acc_found = 0;
147 mm = old_pitch_arr_[i];
148 mm.transpose (d);
149 for (int j=0; ( (j < accidentals_i) && (acc_found == 0)); j++)
151 if (pitch_arr_[j].notename_i_ == mm.notename_i_)
153 if (mm.accidental_i_ == 0)
155 // remove new accidental
156 pitch_arr_.del (j);
157 accidentals_i--;
158 acc_found = 1;
160 else
162 // change new accidental
163 pitch_arr_[j].accidental_i_ = mm.accidental_i_;
164 acc_found = 1;
168 if (acc_found == 0)
170 // add transposed old accidental
171 pitch_arr_.push (mm);
177 void
178 Key_def::squash_octaves ()
180 for (int i=0; i < pitch_arr_.size (); i++)
182 pitch_arr_[i].octave_i_ = 0;