]> git.donarmstrong.com Git - lilypond.git/blob - lily/musical-pitch.cc
bb22b41291b59ad70833b4850dc8bf0c7cbe1d26
[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--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include "musical-pitch.hh"
10 #include "debug.hh"
11 #include "main.hh"
12
13 int
14 compare (Array<Musical_pitch>* left, Array<Musical_pitch>* right)
15 {
16   assert (left);
17   assert (right);
18   
19   if (left->size () == right->size ())
20     {
21       for (int i = 0; i < left->size (); i++)
22         {
23           int r = Musical_pitch::compare ((*left)[i], (*right)[i]);
24           if (r)
25             return r;
26         }
27     }
28   else
29     return 1;
30
31   return 0;
32 }
33
34 SCM
35 Musical_pitch::to_scm ()const
36 {
37   return gh_list (gh_int2scm (octave_i_),
38                   gh_int2scm (notename_i_),
39                   gh_int2scm (accidental_i_),
40                   SCM_UNDEFINED);
41 }
42
43
44 Musical_pitch::Musical_pitch (SCM s)
45 {
46   octave_i_ = gh_scm2int (gh_car (s));
47   notename_i_ = gh_scm2int (gh_cadr (s));
48   accidental_i_ = gh_scm2int (gh_caddr (s));
49 }
50
51 Musical_pitch::Musical_pitch (int n, int a, int o)
52 {
53   notename_i_ = n;
54   accidental_i_ = a;
55   octave_i_ = o;
56 }
57
58 void
59 Musical_pitch::print () const
60 {
61 #ifndef NPRINT
62   DEBUG_OUT << str ();
63 #endif
64 }
65
66 int
67 Musical_pitch::compare (Musical_pitch const &m1, Musical_pitch const &m2)
68 {
69     int o=  m1.octave_i_ - m2.octave_i_;
70   int n = m1.notename_i_ - m2.notename_i_;
71   int a = m1.accidental_i_ - m2.accidental_i_;
72
73   if (o)
74         return o;
75   if (n)
76         return n;
77   if (a)
78         return a;
79   return 0;
80 }
81
82 int
83 Musical_pitch::steps () const
84 {
85   return  notename_i_ + octave_i_*7;
86 }
87
88 /*
89   should be settable from input to allow "viola"-mode
90  */
91 static Byte pitch_byte_a[  ] = { 0, 2, 4, 5, 7, 9, 11 };
92
93 int
94 Musical_pitch::semitone_pitch () const
95 {
96   return  pitch_byte_a[ notename_i_ % 7 ] + accidental_i_ + octave_i_ * 12;
97 }
98
99 void
100 Musical_pitch::transpose (Musical_pitch delta)
101 {
102   int old_pitch = semitone_pitch ();
103   int delta_pitch = delta.semitone_pitch ();
104   octave_i_ += delta.octave_i_;
105   notename_i_ += delta.notename_i_;
106
107   
108   while  (notename_i_ >= 7)
109     {
110       notename_i_ -= 7;
111       octave_i_ ++;
112     }
113
114   int new_pitch = semitone_pitch ();
115   int delta_acc = new_pitch - old_pitch - delta_pitch;
116   accidental_i_ -= delta_acc;
117 }
118
119
120 #if 0
121 // nice test for internationalisation strings
122 char const *accname[] = {"double flat", "flat", "natural",
123                          "sharp" , "double sharp"};
124 #else
125 char const *accname[] = {"eses", "es", "", "is" , "isis"};
126 #endif
127
128 String
129 Musical_pitch::str () const
130 {
131   int n = (notename_i_ + 2) % 7;
132   String s = to_str (char(n + 'a'));
133   if (accidental_i_)
134     s += String (accname[accidental_i_ + 2]);
135
136   if (octave_i_ > 0)
137     {
138       int o = octave_i_ + 1;
139       while (o--)
140         s += "'";
141     }
142   else if (octave_i_ <0)
143     {
144       int o = (-octave_i_) - 1;
145       while (o--)
146         s += to_str (',');
147     }
148
149
150   return s;
151 }
152
153 /*
154   change me to relative, counting from last pitch p
155   return copy of resulting pitch
156  */
157 Musical_pitch
158 Musical_pitch::to_relative_octave (Musical_pitch p)
159 {
160   int oct_mod = octave_i_  + 1; // account for c' = octave 1 iso. 0 4
161   Musical_pitch up_pitch (p);
162   Musical_pitch down_pitch (p);
163
164   up_pitch.accidental_i_ = accidental_i_;
165   down_pitch.accidental_i_ = accidental_i_;
166   
167   Musical_pitch n = *this;
168   up_pitch.up_to (notename_i_);
169   down_pitch.down_to (notename_i_);
170
171   int h = p.steps ();
172   if (abs (up_pitch.steps () - h) < abs (down_pitch.steps () - h))
173     n = up_pitch;
174   else
175     n = down_pitch;
176   
177   n.octave_i_ += oct_mod;
178
179   *this = n;
180   return *this;
181 }
182
183 void
184 Musical_pitch::up_to (int notename)
185 {
186   if (notename_i_  > notename)
187     {
188       octave_i_ ++;
189     }
190   notename_i_  = notename;
191 }
192
193 void
194 Musical_pitch::down_to (int notename)
195 {
196   if (notename_i_ < notename)
197     {
198       octave_i_ --;
199     }
200   notename_i_ = notename;
201 }
202