2 musical-pitch.cc -- implement Pitch
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2009 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_count ();
60 Pitch::tone_pitch () const
62 return scale_
->tones_at_step (notename_
, octave_
) + alteration_
;
65 /* Calculate pitch height in 12th octave steps. Don't assume
66 normalized pitch as this function is used to normalize the pitch. */
68 Pitch::rounded_semitone_pitch () const
70 return int (double (tone_pitch () * Rational (2)));
74 Pitch::rounded_quartertone_pitch () const
76 return int (double (tone_pitch () * Rational (4)));
80 Pitch::normalize_octave ()
82 int normalized_step
= notename_
% scale_
->step_count ();
83 if (normalized_step
< 0)
84 normalized_step
+= scale_
->step_count ();
86 octave_
+= (notename_
- normalized_step
) / scale_
->step_count ();
87 notename_
= normalized_step
;
91 Pitch::normalize_alteration ()
93 while (alteration_
> Rational (1))
95 alteration_
-= scale_
->step_size (notename_
);
98 while (alteration_
< Rational (-1))
101 alteration_
+= scale_
->step_size (notename_
);
108 normalize_alteration ();
113 Pitch::transpose (Pitch delta
)
115 Rational new_alter
= tone_pitch () + delta
.tone_pitch ();
117 octave_
+= delta
.octave_
;
118 notename_
+= delta
.notename_
;
119 alteration_
+= new_alter
- tone_pitch ();
125 pitch_interval (Pitch
const &from
, Pitch
const &to
)
127 Rational sound
= to
.tone_pitch () - from
.tone_pitch ();
128 Pitch
pt (to
.get_octave () - from
.get_octave (),
129 to
.get_notename () - from
.get_notename (),
131 to
.get_alteration () - from
.get_alteration ());
133 return pt
.transposed (Pitch (0, 0, sound
- pt
.tone_pitch ()));
137 Merge with *pitch->text* funcs in chord-name.scm */
138 char const *accname
[] = {"eses", "eseh", "es", "eh", "",
139 "ih", "is", "isih", "isis"};
142 Pitch::to_string () const
144 int n
= (notename_
+ 2) % scale_
->step_count ();
145 string s
= ::to_string (char (n
+ 'a'));
146 Rational qtones
= alteration_
* Rational (4,1);
147 int qt
= int (rint (Real (qtones
)));
149 s
+= string (accname
[qt
+ 4]);
156 else if (octave_
< 0)
158 int o
= (-octave_
) - 1;
160 s
+= ::to_string (',');
166 /* Change me to relative, counting from last pitch p
167 return copy of resulting pitch. */
169 Pitch::to_relative_octave (Pitch p
) const
171 /* account for c' = octave 1 iso. 0 4 */
172 int oct_mod
= octave_
+ 1;
174 Pitch
down_pitch (p
);
176 up_pitch
.alteration_
= alteration_
;
177 down_pitch
.alteration_
= alteration_
;
180 up_pitch
.up_to (notename_
);
181 down_pitch
.down_to (notename_
);
184 if (abs (up_pitch
.steps () - h
) < abs (down_pitch
.steps () - h
))
189 n
.octave_
+= oct_mod
;
194 Pitch::up_to (int notename
)
196 if (notename_
> notename
)
198 notename_
= notename
;
202 Pitch::down_to (int notename
)
204 if (notename_
< notename
)
206 notename_
= notename
;
209 IMPLEMENT_TYPE_P (Pitch
, "ly:pitch?");
211 Pitch::mark_smob (SCM x
)
213 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (x
);
214 return p
->scale_
->self_scm ();
217 IMPLEMENT_SIMPLE_SMOBS (Pitch
);
219 Pitch::print_smob (SCM s
, SCM port
, scm_print_state
*)
221 Pitch
*r
= (Pitch
*) SCM_CELL_WORD_1 (s
);
222 scm_puts ("#<Pitch ", port
);
223 scm_display (ly_string2scm (r
->to_string ()), port
);
224 scm_puts (" >", port
);
229 Pitch::equal_p (SCM a
, SCM b
)
231 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (a
);
232 Pitch
*q
= (Pitch
*) SCM_CELL_WORD_1 (b
);
234 bool eq
= p
->notename_
== q
->notename_
235 && p
->octave_
== q
->octave_
236 && p
->alteration_
== q
->alteration_
;
238 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
241 MAKE_SCHEME_CALLBACK (Pitch
, less_p
, 2);
243 Pitch::less_p (SCM p1
, SCM p2
)
245 Pitch
*a
= unsmob_pitch (p1
);
246 Pitch
*b
= unsmob_pitch (p2
);
248 if (compare (*a
, *b
) < 0)
255 Pitch::get_octave () const
261 Pitch::get_notename () const
267 Pitch::get_alteration () const
273 Pitch::transposed (Pitch d
) const
280 Rational
NATURAL_ALTERATION (0);
281 Rational
FLAT_ALTERATION (-1, 2);
282 Rational
DOUBLE_FLAT_ALTERATION (-1);
283 Rational
SHARP_ALTERATION (1, 2);
286 Pitch::negated () const
288 return pitch_interval (*this, Pitch ());