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_str (a);
27 s += ", notename = " + to_str (n);
41 Pitch::compare (Pitch const &m1, Pitch const &m2)
43 int o= m1.octave_i_ - m2.octave_i_;
44 int n = m1.notename_i_ - m2.notename_i_;
45 int a = m1.alteration_i_ - m2.alteration_i_;
59 return notename_i_ + octave_i_*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_i_;
86 int pitch = semitone_pitch ();
87 while (notename_i_ >= 7)
91 alteration_i_ -= semitone_pitch () - pitch;
93 while (notename_i_ < 0)
97 alteration_i_ -= semitone_pitch () - pitch;
99 while (alteration_i_ >= 3)
101 if (notename_i_ == 6)
110 alteration_i_ -= semitone_pitch () - pitch;
112 while (alteration_i_ <= -3)
114 if (notename_i_ == 0)
123 alteration_i_ -= 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_i_ += delta.octave_i_;
134 notename_i_ += delta.notename_i_;
136 int new_semi = semitone_pitch ();
137 int delta_acc = new_semi - old_semi - delta_semi;
138 alteration_i_ -= delta_acc;
145 Merge with *pitch->text* funcs in chord-name.scm
147 char const *accname[] = {"eses", "es", "", "is" , "isis"};
152 int n = (notename_i_ + 2) % 7;
153 String s = to_str (char (n + 'a'));
155 s += String (accname[alteration_i_ + 2]);
159 int o = octave_i_ + 1;
163 else if (octave_i_ < 0)
165 int o = (-octave_i_) - 1;
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_i_ + 1; // account for c' = octave 1 iso. 0 4
182 Pitch down_pitch (p);
184 up_pitch.alteration_i_ = alteration_i_;
185 down_pitch.alteration_i_ = alteration_i_;
188 up_pitch.up_to (notename_i_);
189 down_pitch.down_to (notename_i_);
192 if (abs (up_pitch.steps () - h) < abs (down_pitch.steps () - h))
197 n.octave_i_ += oct_mod;
204 Pitch::up_to (int notename)
206 if (notename_i_ > notename)
210 notename_i_ = notename;
214 Pitch::down_to (int notename)
216 if (notename_i_ < notename)
220 notename_i_ = 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 (ly_str02scm (r->str ().ch_C ()), 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_i_ == q->notename_i_
271 && p->octave_i_ == q->octave_i_
272 && p->alteration_i_ == q->alteration_i_;
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->octave_i ();
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->alteration_i ();
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->notename_i ();
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");
355 return gh_int2scm (q);
358 LY_DEFINE(pitch_less, "pitch<?", 2,0,0, (SCM p1, SCM p2),
359 "Is @var{p1} lower than @var{p2}? This uses lexicographic ordening.")
361 return Pitch::less_p (ly_car (p1), ly_car (p2));
365 Pitch::smobbed_copy ()const
367 Pitch * p = new Pitch (*this);
368 return p->smobbed_self ();
372 Pitch::octave_i ()const
378 Pitch::notename_i () const
384 Pitch::alteration_i () const
386 return alteration_i_;