2 musical-pitch.cc -- implement Pitch
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
13 #include "ly-smobs.icc"
15 Pitch::Pitch (int o
, int n
, int a
)
23 /* FIXME: why is octave == 0 and default not middleC ? */
32 Pitch::compare (Pitch
const &m1
, Pitch
const &m2
)
34 int o
= m1
.octave_
- m2
.octave_
;
35 int n
= m1
.notename_
- m2
.notename_
;
36 int a
= m1
.alteration_
- m2
.alteration_
;
50 return notename_
+ octave_
* 7;
53 /* Should be settable from input? */
54 static Byte diatonic_scale_semitones
[ ] = { 0, 2, 4, 5, 7, 9, 11 };
56 /* Calculate pitch height in 12th octave steps. Don't assume
57 normalised pitch as this function is used to normalise the pitch. */
59 Pitch::semitone_pitch () const
70 programming_error ("semitone_pitch () called on quarter tone alteration.");
72 return ((o
+ n
/ 7) * 12
73 + diatonic_scale_semitones
[n
% 7]
78 Pitch::quartertone_pitch () const
88 return ((o
+ n
/ 7) * 24
89 + 2 * diatonic_scale_semitones
[n
% 7]
96 int pitch
= quartertone_pitch ();
97 while (notename_
>= 7)
101 alteration_
-= quartertone_pitch () - pitch
;
103 while (notename_
< 0)
107 alteration_
-= quartertone_pitch () - pitch
;
109 while (alteration_
> DOUBLE_SHARP
)
120 alteration_
-= quartertone_pitch () - pitch
;
123 while (alteration_
< DOUBLE_FLAT
)
134 alteration_
-= quartertone_pitch () - pitch
;
138 /* WHugh, wat een intervaas */
140 Pitch::transpose (Pitch delta
)
142 int new_semi
= quartertone_pitch () +delta
.quartertone_pitch ();
143 octave_
+= delta
.octave_
;
144 notename_
+= delta
.notename_
;
145 alteration_
+= new_semi
- quartertone_pitch ();
151 pitch_interval (Pitch
const &from
, Pitch
const &to
)
153 int sound
= to
.quartertone_pitch () - from
.quartertone_pitch ();
154 Pitch
pt (to
.get_octave () - from
.get_octave (),
155 to
.get_notename () - from
.get_notename (),
157 to
.get_alteration () - from
.get_alteration ());
159 return pt
.transposed (Pitch (0, 0, sound
- pt
.quartertone_pitch ()));
163 Merge with *pitch->text* funcs in chord-name.scm */
164 char const *accname
[] = {"eses", "eseh", "es", "eh", "",
165 "ih", "is", "isih", "isis"};
168 Pitch::to_string () const
170 int n
= (notename_
+ 2) % 7;
171 String s
= ::to_string (char (n
+ 'a'));
173 s
+= String (accname
[alteration_
- DOUBLE_FLAT
]);
181 else if (octave_
< 0)
183 int o
= (-octave_
) - 1;
185 s
+= ::to_string (',');
191 /* Change me to relative, counting from last pitch p
192 return copy of resulting pitch. */
194 Pitch::to_relative_octave (Pitch p
) const
196 /* account for c' = octave 1 iso. 0 4 */
197 int oct_mod
= octave_
+ 1;
199 Pitch
down_pitch (p
);
201 up_pitch
.alteration_
= alteration_
;
202 down_pitch
.alteration_
= alteration_
;
205 up_pitch
.up_to (notename_
);
206 down_pitch
.down_to (notename_
);
209 if (abs (up_pitch
.steps () - h
) < abs (down_pitch
.steps () - h
))
214 n
.octave_
+= oct_mod
;
219 Pitch::up_to (int notename
)
221 if (notename_
> notename
)
223 notename_
= notename
;
227 Pitch::down_to (int notename
)
229 if (notename_
< notename
)
231 notename_
= notename
;
234 IMPLEMENT_TYPE_P (Pitch
, "ly:pitch?");
237 Pitch::mark_smob (SCM
)
242 IMPLEMENT_SIMPLE_SMOBS (Pitch
);
244 Pitch::print_smob (SCM s
, SCM port
, scm_print_state
*)
246 Pitch
*r
= (Pitch
*) SCM_CELL_WORD_1 (s
);
247 scm_puts ("#<Pitch ", port
);
248 scm_display (scm_makfrom0str (r
->to_string ().to_str0 ()), port
);
249 scm_puts (" >", port
);
254 Pitch::equal_p (SCM a
, SCM b
)
256 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (a
);
257 Pitch
*q
= (Pitch
*) SCM_CELL_WORD_1 (b
);
259 bool eq
= p
->notename_
== q
->notename_
260 && p
->octave_
== q
->octave_
261 && p
->alteration_
== q
->alteration_
;
263 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
266 MAKE_SCHEME_CALLBACK (Pitch
, less_p
, 2);
268 Pitch::less_p (SCM p1
, SCM p2
)
270 Pitch
*a
= unsmob_pitch (p1
);
271 Pitch
*b
= unsmob_pitch (p2
);
273 if (compare (*a
, *b
) < 0)
280 Pitch::get_octave () const
286 Pitch::get_notename () const
292 Pitch::get_alteration () const
298 Pitch::transposed (Pitch d
) const