2 musical-pitch.cc -- implement Pitch
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
13 #include "string-convert.hh"
16 #include "ly-smobs.icc"
19 Pitch::Pitch (int o
, int n
, Rational a
)
24 scale_
= default_global_scale
;
28 /* FIXME: why is octave == 0 and default not middleC ? */
32 scale_
= default_global_scale
;
37 Pitch::compare (Pitch
const &m1
, Pitch
const &m2
)
39 int o
= m1
.octave_
- m2
.octave_
;
40 int n
= m1
.notename_
- m2
.notename_
;
41 Rational a
= m1
.alteration_
- m2
.alteration_
;
56 return notename_
+ octave_
* scale_
->step_tones_
.size ();
60 Pitch::tone_pitch () const
66 n
+= scale_
->step_tones_
.size ();
71 we're effictively hardcoding the octave to 6 whole-tones,
72 which is as arbitrary as coding it to 1200 cents
74 Rational
tones ((o
+ n
/ scale_
->step_tones_
.size ()) * 6, 1);
75 tones
+= scale_
->step_tones_
[n
% scale_
->step_tones_
.size ()];
82 /* Calculate pitch height in 12th octave steps. Don't assume
83 normalized pitch as this function is used to normalize the pitch. */
85 Pitch::rounded_semitone_pitch () const
87 return int (double (tone_pitch () * Rational (2)));
91 Pitch::rounded_quartertone_pitch () const
93 return int (double (tone_pitch () * Rational (4)));
99 Rational pitch
= tone_pitch ();
100 while (notename_
>= (int) scale_
->step_tones_
.size ())
102 notename_
-= scale_
->step_tones_
.size ();
104 alteration_
-= tone_pitch () - pitch
;
106 while (notename_
< 0)
108 notename_
+= scale_
->step_tones_
.size ();
110 alteration_
-= tone_pitch () - pitch
;
113 while (alteration_
> Rational (1))
115 if (notename_
== int (scale_
->step_tones_
.size ()))
123 alteration_
= Rational (0);
124 alteration_
-= tone_pitch () - pitch
;
126 while (alteration_
< Rational (-1))
130 notename_
= scale_
->step_tones_
.size ();
137 alteration_
-= tone_pitch () - pitch
;
142 Pitch::transpose (Pitch delta
)
144 Rational new_alter
= tone_pitch () + delta
.tone_pitch ();
146 octave_
+= delta
.octave_
;
147 notename_
+= delta
.notename_
;
148 alteration_
+= new_alter
- tone_pitch ();
154 pitch_interval (Pitch
const &from
, Pitch
const &to
)
156 Rational sound
= to
.tone_pitch () - from
.tone_pitch ();
157 Pitch
pt (to
.get_octave () - from
.get_octave (),
158 to
.get_notename () - from
.get_notename (),
160 to
.get_alteration () - from
.get_alteration ());
162 return pt
.transposed (Pitch (0, 0, sound
- pt
.tone_pitch ()));
166 Merge with *pitch->text* funcs in chord-name.scm */
167 char const *accname
[] = {"eses", "eseh", "es", "eh", "",
168 "ih", "is", "isih", "isis"};
171 Pitch::to_string () const
173 int n
= (notename_
+ 2) % scale_
->step_tones_
.size ();
174 string s
= ::to_string (char (n
+ 'a'));
175 Rational qtones
= alteration_
* Rational (4,1);
176 int qt
= int (rint (Real (qtones
)));
178 s
+= string (accname
[qt
+ 4]);
185 else if (octave_
< 0)
187 int o
= (-octave_
) - 1;
189 s
+= ::to_string (',');
195 /* Change me to relative, counting from last pitch p
196 return copy of resulting pitch. */
198 Pitch::to_relative_octave (Pitch p
) const
200 /* account for c' = octave 1 iso. 0 4 */
201 int oct_mod
= octave_
+ 1;
203 Pitch
down_pitch (p
);
205 up_pitch
.alteration_
= alteration_
;
206 down_pitch
.alteration_
= alteration_
;
209 up_pitch
.up_to (notename_
);
210 down_pitch
.down_to (notename_
);
213 if (abs (up_pitch
.steps () - h
) < abs (down_pitch
.steps () - h
))
218 n
.octave_
+= oct_mod
;
223 Pitch::up_to (int notename
)
225 if (notename_
> notename
)
227 notename_
= notename
;
231 Pitch::down_to (int notename
)
233 if (notename_
< notename
)
235 notename_
= notename
;
238 IMPLEMENT_TYPE_P (Pitch
, "ly:pitch?");
240 Pitch::mark_smob (SCM x
)
242 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (x
);
243 return p
->scale_
->self_scm ();
246 IMPLEMENT_SIMPLE_SMOBS (Pitch
);
248 Pitch::print_smob (SCM s
, SCM port
, scm_print_state
*)
250 Pitch
*r
= (Pitch
*) SCM_CELL_WORD_1 (s
);
251 scm_puts ("#<Pitch ", port
);
252 scm_display (ly_string2scm (r
->to_string ()), port
);
253 scm_puts (" >", port
);
258 Pitch::equal_p (SCM a
, SCM b
)
260 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (a
);
261 Pitch
*q
= (Pitch
*) SCM_CELL_WORD_1 (b
);
263 bool eq
= p
->notename_
== q
->notename_
264 && p
->octave_
== q
->octave_
265 && p
->alteration_
== q
->alteration_
;
267 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
270 MAKE_SCHEME_CALLBACK (Pitch
, less_p
, 2);
272 Pitch::less_p (SCM p1
, SCM p2
)
274 Pitch
*a
= unsmob_pitch (p1
);
275 Pitch
*b
= unsmob_pitch (p2
);
277 if (compare (*a
, *b
) < 0)
284 Pitch::get_octave () const
290 Pitch::get_notename () const
296 Pitch::get_alteration () const
302 Pitch::transposed (Pitch d
) const
309 Rational
NATURAL_ALTERATION (0);
310 Rational
FLAT_ALTERATION (-1, 2);
311 Rational
DOUBLE_FLAT_ALTERATION (-1);
312 Rational
SHARP_ALTERATION (1, 2);
315 Pitch::negated () const
317 return pitch_interval (*this, Pitch ());