]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-def.cc
7c492b23f3c298aec087dc4b4c3c9bdba818849a
[lilypond.git] / lily / key-def.cc
1 /*   
2   key-def.cc --  implement 
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
7   
8  */
9
10 #include "key-def.hh"
11 #include "debug.hh"
12
13 Key_def::Key_def ()
14 {
15   modality_i_ = 0;
16   ordinary_key_b_ = false;
17 }
18  
19 int
20 Key_def::ordinary_accidentals_i () const
21 {
22   if (!ordinary_key_b_) 
23     {
24       programming_error ("Accidentals requested for non-conventional key");
25       return 0;
26     }
27
28   int p;
29   if (pitch_arr_.size () < 1) 
30     {
31       warning (_ ("No key name: assuming `C'"));
32       p = 0;
33     }
34   else
35     {
36       p = pitch_arr_[0].semitone_pitch ();
37       p += modality_i_;
38     }
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;
42   
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;
47 }
48
49 int
50 Key_def::flats_i () const
51 {
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++)
56     {
57       if (pitch_arr_[i].accidental_i_ < 0)
58         flats_i -= pitch_arr_[i].accidental_i_;
59     }
60   return flats_i;
61 }
62
63 bool
64 Key_def::minor_b () const
65 {
66   return modality_i_ == 3;
67 }
68
69 int
70 Key_def::sharps_i () const
71 {
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++)
76     {
77       if (pitch_arr_[i].accidental_i_ > 0)
78         sharps_i += pitch_arr_[i].accidental_i_;
79     }
80   return sharps_i;
81 }
82
83 void
84 Key_def::transpose (Musical_pitch d) 
85 {
86   if (ordinary_key_b_ ) 
87     { 
88       if (pitch_arr_.size () > 0) 
89         pitch_arr_[0].transpose (d);
90       else
91         {
92           warning (_ ("don't know how handle empty keys")); // TODO 
93         }
94     }
95   else
96     {
97       Array<Musical_pitch> old_pitch_arr_;
98       for (int i = 0; i < pitch_arr_.size (); i++)
99         {
100           old_pitch_arr_.push (pitch_arr_[i]);
101         }
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;
108
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_);
112     
113       pitch_arr_.clear ();
114       if (accidentals_i < 0) 
115         {
116           int accidental = 6 ; // First accidental: bes
117           for ( ; accidentals_i < 0 ; accidentals_i++ ) 
118             {
119               Musical_pitch m;
120               m.accidental_i_ = -1;
121               m.notename_i_ = accidental;
122               pitch_arr_.push (m);
123      
124               accidental = (accidental + 3) % 7 ;
125             }
126         }
127       else 
128         { 
129           int accidental = 3 ; // First accidental: fis
130           for ( ; accidentals_i > 0 ; accidentals_i-- ) 
131             {
132               Musical_pitch m;
133               m.accidental_i_ = 1;
134               m.notename_i_ = accidental;
135               pitch_arr_.push (m);
136    
137               accidental = (accidental + 4) % 7 ;
138             }
139         }
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++)
145         {
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++)
150             {
151               if (pitch_arr_[j].notename_i_ == mm.notename_i_)
152                 {
153                   if (mm.accidental_i_ == 0)
154                     {
155                       // remove new accidental 
156                       pitch_arr_.del (j);
157                       accidentals_i--;
158                       acc_found = 1;
159                     }
160                   else
161                     {
162                       // change new accidental 
163                       pitch_arr_[j].accidental_i_ = mm.accidental_i_;
164                       acc_found = 1;
165                     }
166                 }
167             }
168           if (acc_found == 0)
169             {
170               // add transposed old accidental 
171               pitch_arr_.push (mm);
172             }
173         }
174     }
175 }
176
177 void
178 Key_def::squash_octaves ()
179 {
180   for (int i=0; i < pitch_arr_.size (); i++)
181     {
182       pitch_arr_[i].octave_i_ = 0;
183     }
184 }