2 musical-pitch.cc -- implement Pitch
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
12 #include "ly-smobs.icc"
16 Pitch::Pitch (int o
, int n
, int a
)
22 if (n
< 0 || n
>= 7 ||
25 String s
= _ ("Pitch arguments out of range");
26 s
+= ": alteration = " + to_string (a
);
27 s
+= ", notename = " + to_string (n
);
41 Pitch::compare (Pitch
const &m1
, Pitch
const &m2
)
43 int o
= m1
.octave_
- m2
.octave_
;
44 int n
= m1
.notename_
- m2
.notename_
;
45 int a
= m1
.alteration_
- m2
.alteration_
;
59 return notename_
+ octave_
*7;
63 should be settable from input?
65 static Byte pitch_byte_a
[ ] = { 0, 2, 4, 5, 7, 9, 11 };
68 /* Calculate pitch height in 12th octave steps. Don't assume
69 normalised pitch as this function is used to normalise the pitch. */
71 Pitch::semitone_pitch () const
80 return (o
+ n
/ 7) * 12 + pitch_byte_a
[n
% 7] + alteration_
;
86 int pitch
= semitone_pitch ();
87 while (notename_
>= 7)
91 alteration_
-= semitone_pitch () - pitch
;
97 alteration_
-= semitone_pitch () - pitch
;
99 while (alteration_
>= 3)
110 alteration_
-= semitone_pitch () - pitch
;
112 while (alteration_
<= -3)
123 alteration_
-= semitone_pitch () - pitch
;
127 /* WHugh, wat een intervaas */
129 Pitch::transpose (Pitch delta
)
131 int old_semi
= semitone_pitch ();
132 int delta_semi
= delta
.semitone_pitch ();
133 octave_
+= delta
.octave_
;
134 notename_
+= delta
.notename_
;
136 int new_semi
= semitone_pitch ();
137 int delta_acc
= new_semi
- old_semi
- delta_semi
;
138 alteration_
-= delta_acc
;
145 Merge with *pitch->text* funcs in chord-name.scm
147 char const *accname
[] = {"eses", "es", "", "is" , "isis"};
150 Pitch::string () const
152 int n
= (notename_
+ 2) % 7;
153 String s
= to_string (char (n
+ 'a'));
155 s
+= String (accname
[alteration_
+ 2]);
163 else if (octave_
< 0)
165 int o
= (-octave_
) - 1;
167 s
+= to_string (',');
174 change me to relative, counting from last pitch p
175 return copy of resulting pitch
178 Pitch::to_relative_octave (Pitch p
)
180 int oct_mod
= octave_
+ 1; // account for c' = octave 1 iso. 0 4
182 Pitch
down_pitch (p
);
184 up_pitch
.alteration_
= alteration_
;
185 down_pitch
.alteration_
= alteration_
;
188 up_pitch
.up_to (notename_
);
189 down_pitch
.down_to (notename_
);
192 if (abs (up_pitch
.steps () - h
) < abs (down_pitch
.steps () - h
))
197 n
.octave_
+= oct_mod
;
204 Pitch::up_to (int notename
)
206 if (notename_
> notename
)
210 notename_
= notename
;
214 Pitch::down_to (int notename
)
216 if (notename_
< notename
)
220 notename_
= notename
;
223 LY_DEFINE(ly_pitch_transpose
,
224 "ly-transpose-pitch", 2, 0, 0,
226 "Transpose @var{p} by the amount @var{delta}, where @var{delta} is the
227 pitch that central C is transposed to.
230 Pitch
* t
= unsmob_pitch (p
);
231 Pitch
*d
= unsmob_pitch (delta
);
232 SCM_ASSERT_TYPE(t
, p
, SCM_ARG1
, __FUNCTION__
, "pitch") ;
233 SCM_ASSERT_TYPE(d
, delta
, SCM_ARG1
, __FUNCTION__
, "pitch") ;
237 return tp
.smobbed_copy ();
240 /****************************************************************/
243 IMPLEMENT_TYPE_P (Pitch
, "pitch?");
246 Pitch::mark_smob (SCM
)
251 IMPLEMENT_SIMPLE_SMOBS (Pitch
);
253 Pitch::print_smob (SCM s
, SCM port
, scm_print_state
*)
255 Pitch
*r
= (Pitch
*) ly_cdr (s
);
257 scm_puts ("#<Pitch ", port
);
258 scm_display (scm_makfrom0str (r
->string ().to_str0 ()), port
);
259 scm_puts (" >", port
);
265 Pitch::equal_p (SCM a
, SCM b
)
267 Pitch
*p
= (Pitch
*) ly_cdr (a
);
268 Pitch
*q
= (Pitch
*) ly_cdr (b
);
270 bool eq
= p
->notename_
== q
->notename_
271 && p
->octave_
== q
->octave_
272 && p
->alteration_
== q
->alteration_
;
274 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
277 MAKE_SCHEME_CALLBACK (Pitch
, less_p
, 2);
279 Pitch::less_p (SCM p1
, SCM p2
)
281 Pitch
*a
= unsmob_pitch (p1
);
282 Pitch
*b
= unsmob_pitch (p2
);
284 if (compare (*a
, *b
) < 0)
291 should add optional args
294 LY_DEFINE(make_pitch
, "make-pitch", 3, 0, 0,
295 (SCM o
, SCM n
, SCM a
),
297 @var{octave} is specified by an integer, zero for the octave containing
298 middle C. @var{note} is a number from 0 to 6, with 0 corresponding to C
299 and 6 corresponding to B. The shift is zero for a natural, negative for
300 flats, or positive for sharps.
304 SCM_ASSERT_TYPE(gh_number_p (o
), o
, SCM_ARG1
, __FUNCTION__
, "number");
305 SCM_ASSERT_TYPE(gh_number_p (n
), n
, SCM_ARG2
, __FUNCTION__
, "number");
306 SCM_ASSERT_TYPE(gh_number_p (a
), a
, SCM_ARG3
, __FUNCTION__
, "number");
308 Pitch
p (gh_scm2int (o
), gh_scm2int (n
), gh_scm2int (a
));
309 return p
.smobbed_copy ();
313 LY_DEFINE(pitch_octave
, "pitch-octave", 1, 0, 0,
315 "extract the octave from pitch @var{p}.")
317 Pitch
*p
= unsmob_pitch (pp
);
318 SCM_ASSERT_TYPE(p
, pp
, SCM_ARG1
, __FUNCTION__
, "Pitch");
319 int q
= p
->get_octave ();
321 return gh_int2scm (q
);
324 LY_DEFINE(pitch_alteration
, "pitch-alteration", 1, 0, 0,
326 "extract the alteration from pitch @var{p}.")
328 Pitch
*p
= unsmob_pitch (pp
);
329 SCM_ASSERT_TYPE(p
, pp
, SCM_ARG1
, __FUNCTION__
, "Pitch");
330 int q
= p
->get_alteration ();
332 return gh_int2scm (q
);
335 LY_DEFINE(pitch_notename
, "pitch-notename", 1, 0, 0,
337 "extract the note name from pitch @var{pp}.")
339 Pitch
*p
= unsmob_pitch (pp
);
340 SCM_ASSERT_TYPE(p
, pp
, SCM_ARG1
, __FUNCTION__
, "Pitch");
341 int q
= p
->get_notename ();
343 return gh_int2scm (q
);
346 LY_DEFINE(pitch_semitones
, "pitch-semitones", 1, 0, 0,
348 "calculate the number of semitones of @var{p} from central C.")
350 Pitch
*p
= unsmob_pitch (pp
);
351 SCM_ASSERT_TYPE(p
, pp
, SCM_ARG1
, __FUNCTION__
, "Pitch");
353 int q
= p
->semitone_pitch ();
357 //int q = p->steps ();
359 // As the function is called "pitch_semitones", I assume it was a mistake !
362 return gh_int2scm (q
);
365 LY_DEFINE(pitch_less
, "pitch<?", 2,0,0, (SCM p1
, SCM p2
),
366 "Is @var{p1} lower than @var{p2}? This uses lexicographic ordening.")
368 return Pitch::less_p (ly_car (p1
), ly_car (p2
));
372 Pitch::smobbed_copy ()const
374 Pitch
* p
= new Pitch (*this);
375 return p
->smobbed_self ();
379 Pitch::get_octave ()const
385 Pitch::get_notename () const
391 Pitch::get_alteration () const