]> git.donarmstrong.com Git - lilypond.git/blob - lily/musical-pitch.cc
release: 1.1.2
[lilypond.git] / lily / musical-pitch.cc
1 /*   
2   musical-pitch.cc --  implement Musical_pitch
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include "musical-pitch.hh"
10 #include "debug.hh"
11 #include "main.hh"
12
13 Musical_pitch::Musical_pitch ()
14 {
15   init ();
16 }
17
18 void
19 Musical_pitch::init ()
20 {
21   notename_i_ = 0;
22   octave_i_ = 0;
23   accidental_i_ = 0;
24   cautionary_b_ = false;
25 }
26
27 void
28 Musical_pitch::print () const
29 {
30 #ifndef NPRINT
31   DOUT << str ();
32 #endif
33 }
34
35 int
36 Musical_pitch::compare (Musical_pitch const &m1, Musical_pitch const &m2)
37 {
38     int o=  m1.octave_i_ - m2.octave_i_;
39   int n = m1.notename_i_ - m2.notename_i_;
40   int a = m1.accidental_i_ - m2.accidental_i_;
41
42   if (o)
43         return o;
44   if (n)
45         return n;
46   if (a)
47         return a;
48   return 0;
49 }
50
51 int
52 Musical_pitch::steps () const
53 {
54   return  notename_i_ + octave_i_*7;
55 }
56
57 /*
58   should be settable from input to allow "viola"-mode
59  */
60 static Byte pitch_byte_a[  ] = { 0, 2, 4, 5, 7, 9, 11 };
61
62 int
63 Musical_pitch::semitone_pitch () const
64 {
65   return  pitch_byte_a[ notename_i_ % 7 ] + accidental_i_ + octave_i_ * 12;
66 }
67
68 void
69 Musical_pitch::transpose (Musical_pitch delta)
70 {
71   int old_pitch = semitone_pitch ();
72   int delta_pitch = delta.semitone_pitch ();
73   octave_i_ += delta.octave_i_;
74   notename_i_ += delta.notename_i_;
75
76   
77   while  (notename_i_ >= 7)
78     {
79       notename_i_ -= 7;
80       octave_i_ ++;
81     }
82
83   int new_pitch = semitone_pitch ();
84   int delta_acc = new_pitch - old_pitch - delta_pitch;
85   accidental_i_ -= delta_acc;
86 }
87
88
89 #if 0
90 // nice test for internationalisation strings
91 char const *accname[] = {"double flat", "flat", "natural",
92                          "sharp" , "double sharp"};
93 #else
94 char const *accname[] = {"eses", "es", "", "is" , "isis"};
95 #endif
96
97 String
98 Musical_pitch::str () const
99 {
100   int n = (notename_i_ + 2) % 7;
101   String s = to_str (char(n + 'a'));
102   if (accidental_i_)
103     s += String (accname[accidental_i_ + 2]);
104
105   if (octave_i_)
106     s  += String ((octave_i_> 0)? "^": "_") + to_str (octave_i_);
107
108   return s;
109 }
110
111 /*
112   change me to relative, counting from last pitch p
113   return copy of resulting pitch
114  */
115 Musical_pitch
116 Musical_pitch::to_relative_octave (Musical_pitch p)
117 {
118   int oct_mod = octave_i_  + 1; // account for c' = octave 1 iso. 0 4
119   Musical_pitch up_pitch (p);
120   Musical_pitch down_pitch (p);
121
122   up_pitch.accidental_i_ = accidental_i_;
123   down_pitch.accidental_i_ = accidental_i_;
124   
125   Musical_pitch n = *this;
126   up_pitch.up_to (notename_i_);
127   down_pitch.down_to (notename_i_);
128
129   int h = p.steps ();
130   if (abs (up_pitch.steps () - h) < abs (down_pitch.steps () - h))
131     n = up_pitch;
132   else
133     n = down_pitch;
134   
135   if (find_quarts_global_b)
136     {
137       int d = this->semitone_pitch () - n.semitone_pitch ();
138       if (d)
139         {
140           int i = 1 + (abs (d) - 1) / 12;
141           String quote_str = d < 0 ? to_str (',', i) : to_str ('\'', i);
142           Musical_pitch w = *this;
143           w.octave_i_ = 0;
144           String name_str = w.str ();
145           name_str + quote_str;
146           w.warning (_f ("Interval greater than quart, relative: %s", 
147             name_str + quote_str));
148           // don't actually do any relative stuff
149           n = *this;
150         }
151     }
152   else
153     n.octave_i_ += oct_mod;
154
155   *this = n;
156   return *this;
157 }
158
159 void
160 Musical_pitch::up_to (int notename)
161 {
162   if (notename_i_  > notename)
163     {
164       octave_i_ ++;
165     }
166   notename_i_  = notename;
167 }
168
169 void
170 Musical_pitch::down_to (int notename)
171 {
172   if (notename_i_ < notename)
173     {
174       octave_i_ --;
175     }
176   notename_i_ = notename;
177 }
178