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