2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1998--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
24 #include "string-convert.hh"
27 #include "ly-smobs.icc"
30 Pitch::Pitch (int o
, int n
, Rational a
)
35 scale_
= default_global_scale
;
39 /* FIXME: why is octave == 0 and default not middleC ? */
43 scale_
= default_global_scale
;
48 Pitch::compare (Pitch
const &m1
, Pitch
const &m2
)
50 int o
= m1
.octave_
- m2
.octave_
;
51 int n
= m1
.notename_
- m2
.notename_
;
52 Rational a
= m1
.alteration_
- m2
.alteration_
;
67 return notename_
+ octave_
* scale_
->step_count ();
71 Pitch::tone_pitch () const
73 return scale_
->tones_at_step (notename_
, octave_
) + alteration_
;
76 /* Calculate pitch height in 12th octave steps. Don't assume
77 normalized pitch as this function is used to normalize the pitch. */
79 Pitch::rounded_semitone_pitch () const
81 return int (double (tone_pitch () * Rational (2)));
85 Pitch::rounded_quartertone_pitch () const
87 return int (double (tone_pitch () * Rational (4)));
91 Pitch::normalize_octave ()
93 int normalized_step
= notename_
% scale_
->step_count ();
94 if (normalized_step
< 0)
95 normalized_step
+= scale_
->step_count ();
97 octave_
+= (notename_
- normalized_step
) / scale_
->step_count ();
98 notename_
= normalized_step
;
102 Pitch::normalize_alteration ()
104 while (alteration_
> Rational (1))
106 alteration_
-= scale_
->step_size (notename_
);
109 while (alteration_
< Rational (-1))
112 alteration_
+= scale_
->step_size (notename_
);
119 normalize_alteration ();
124 Pitch::transpose (Pitch delta
)
126 Rational new_alter
= tone_pitch () + delta
.tone_pitch ();
128 octave_
+= delta
.octave_
;
129 notename_
+= delta
.notename_
;
130 alteration_
+= new_alter
- tone_pitch ();
136 pitch_interval (Pitch
const &from
, Pitch
const &to
)
138 Rational sound
= to
.tone_pitch () - from
.tone_pitch ();
139 Pitch
pt (to
.get_octave () - from
.get_octave (),
140 to
.get_notename () - from
.get_notename (),
142 to
.get_alteration () - from
.get_alteration ());
144 return pt
.transposed (Pitch (0, 0, sound
- pt
.tone_pitch ()));
148 Merge with *pitch->text* funcs in chord-name.scm */
149 char const *accname
[] = {"eses", "eseh", "es", "eh", "",
150 "ih", "is", "isih", "isis"};
153 Pitch::to_string () const
155 int n
= (notename_
+ 2) % scale_
->step_count ();
156 string s
= ::to_string (char (n
+ 'a'));
157 Rational qtones
= alteration_
* Rational (4,1);
158 int qt
= int (rint (Real (qtones
)));
160 s
+= string (accname
[qt
+ 4]);
167 else if (octave_
< 0)
169 int o
= (-octave_
) - 1;
171 s
+= ::to_string (',');
177 /* Change me to relative, counting from last pitch p
178 return copy of resulting pitch. */
180 Pitch::to_relative_octave (Pitch p
) const
182 /* account for c' = octave 1 iso. 0 4 */
183 int oct_mod
= octave_
+ 1;
185 Pitch
down_pitch (p
);
187 up_pitch
.alteration_
= alteration_
;
188 down_pitch
.alteration_
= alteration_
;
191 up_pitch
.up_to (notename_
);
192 down_pitch
.down_to (notename_
);
195 if (abs (up_pitch
.steps () - h
) < abs (down_pitch
.steps () - h
))
200 n
.octave_
+= oct_mod
;
205 Pitch::up_to (int notename
)
207 if (notename_
> notename
)
209 notename_
= notename
;
213 Pitch::down_to (int notename
)
215 if (notename_
< notename
)
217 notename_
= notename
;
220 IMPLEMENT_TYPE_P (Pitch
, "ly:pitch?");
222 Pitch::mark_smob (SCM x
)
224 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (x
);
225 return p
->scale_
->self_scm ();
228 IMPLEMENT_SIMPLE_SMOBS (Pitch
);
230 Pitch::print_smob (SCM s
, SCM port
, scm_print_state
*)
232 Pitch
*r
= (Pitch
*) SCM_CELL_WORD_1 (s
);
233 scm_puts ("#<Pitch ", port
);
234 scm_display (ly_string2scm (r
->to_string ()), port
);
235 scm_puts (" >", port
);
240 Pitch::equal_p (SCM a
, SCM b
)
242 Pitch
*p
= (Pitch
*) SCM_CELL_WORD_1 (a
);
243 Pitch
*q
= (Pitch
*) SCM_CELL_WORD_1 (b
);
245 bool eq
= p
->notename_
== q
->notename_
246 && p
->octave_
== q
->octave_
247 && p
->alteration_
== q
->alteration_
;
249 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
252 MAKE_SCHEME_CALLBACK (Pitch
, less_p
, 2);
254 Pitch::less_p (SCM p1
, SCM p2
)
256 Pitch
*a
= unsmob_pitch (p1
);
257 Pitch
*b
= unsmob_pitch (p2
);
259 if (compare (*a
, *b
) < 0)
266 Pitch::get_octave () const
272 Pitch::get_notename () const
278 Pitch::get_alteration () const
284 Pitch::transposed (Pitch d
) const
292 Pitch::normalized () const
299 Rational
NATURAL_ALTERATION (0);
300 Rational
FLAT_ALTERATION (-1, 2);
301 Rational
DOUBLE_FLAT_ALTERATION (-1);
302 Rational
SHARP_ALTERATION (1, 2);
305 Pitch::negated () const
307 return pitch_interval (*this, Pitch ());