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