2 musical-pitch.cc -- implement Musical_pitch
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "musical-pitch.hh"
12 #include "ly-smobs.icc"
15 compare (Array<Musical_pitch>* left, Array<Musical_pitch>* right)
20 if (left->size () == right->size ())
22 for (int i = 0; i < left->size (); i++)
24 int r = Musical_pitch::compare ((*left)[i], (*right)[i]);
35 Musical_pitch::Musical_pitch (int o, int n, int a)
41 if (n < 0 || n >= 7 ||
44 String s = _("Pitch arguments out of range");
45 s += ": alteration = " + to_str (a);
46 s += ", notename = " + to_str (n);
51 Musical_pitch::Musical_pitch ()
59 Musical_pitch::compare (Musical_pitch const &m1, Musical_pitch const &m2)
61 int o= m1.octave_i_ - m2.octave_i_;
62 int n = m1.notename_i_ - m2.notename_i_;
63 int a = m1.alteration_i_ - m2.alteration_i_;
75 Musical_pitch::steps () const
77 return notename_i_ + octave_i_*7;
81 should be settable from input?
83 static Byte pitch_byte_a[ ] = { 0, 2, 4, 5, 7, 9, 11 };
86 Musical_pitch::semitone_pitch () const
88 return pitch_byte_a[ notename_i_ % 7 ] + alteration_i_ + octave_i_ * 12;
92 Musical_pitch::transpose (Musical_pitch delta)
94 int old_pitch = semitone_pitch ();
95 int delta_pitch = delta.semitone_pitch ();
96 octave_i_ += delta.octave_i_;
97 notename_i_ += delta.notename_i_;
100 while (notename_i_ >= 7)
106 int new_pitch = semitone_pitch ();
107 int delta_acc = new_pitch - old_pitch - delta_pitch;
108 alteration_i_ -= delta_acc;
113 // nice test for internationalisation strings
114 char const *accname[] = {"double flat", "flat", "natural",
115 "sharp" , "double sharp"};
117 char const *accname[] = {"eses", "es", "", "is" , "isis"};
121 Musical_pitch::str () const
123 int n = (notename_i_ + 2) % 7;
124 String s = to_str (char(n + 'a'));
126 s += String (accname[alteration_i_ + 2]);
130 int o = octave_i_ + 1;
134 else if (octave_i_ <0)
136 int o = (-octave_i_) - 1;
146 change me to relative, counting from last pitch p
147 return copy of resulting pitch
150 Musical_pitch::to_relative_octave (Musical_pitch p)
152 int oct_mod = octave_i_ + 1; // account for c' = octave 1 iso. 0 4
153 Musical_pitch up_pitch (p);
154 Musical_pitch down_pitch (p);
156 up_pitch.alteration_i_ = alteration_i_;
157 down_pitch.alteration_i_ = alteration_i_;
159 Musical_pitch n = *this;
160 up_pitch.up_to (notename_i_);
161 down_pitch.down_to (notename_i_);
164 if (abs (up_pitch.steps () - h) < abs (down_pitch.steps () - h))
169 n.octave_i_ += oct_mod;
176 Musical_pitch::up_to (int notename)
178 if (notename_i_ > notename)
182 notename_i_ = notename;
186 Musical_pitch::down_to (int notename)
188 if (notename_i_ < notename)
192 notename_i_ = notename;
195 /****************************************************************/
198 IMPLEMENT_TYPE_P(Musical_pitch, "pitch?");
199 IMPLEMENT_UNSMOB(Musical_pitch, pitch);
201 Musical_pitch::mark_smob (SCM )
206 IMPLEMENT_SIMPLE_SMOBS(Musical_pitch);
210 Musical_pitch::print_smob (SCM s, SCM port, scm_print_state *)
212 Musical_pitch *r = (Musical_pitch *) gh_cdr (s);
214 scm_puts ("#<Musical_pitch ", port);
215 scm_display (gh_str02scm (r->str().ch_C()), port);
216 scm_puts (" >", port);
222 Musical_pitch::equal_p (SCM a , SCM b)
224 Musical_pitch *p = (Musical_pitch *) gh_cdr (a);
225 Musical_pitch *q = (Musical_pitch *) gh_cdr (b);
227 bool eq = p->notename_i_ == q->notename_i_
228 && p->octave_i_ == q->octave_i_
229 && p->alteration_i_ == q->alteration_i_;
231 return eq ? SCM_BOOL_T : SCM_BOOL_F;
234 MAKE_SCHEME_CALLBACK(Musical_pitch, less_p, 2);
236 Musical_pitch::less_p (SCM p1, SCM p2)
238 Musical_pitch *a = unsmob_pitch (p1);
239 Musical_pitch *b = unsmob_pitch (p2);
241 if (compare(*a, *b) < 0 )
248 should add optional args
252 make_pitch (SCM o, SCM n, SCM a)
255 p.octave_i_ = gh_scm2int (o);
256 p.notename_i_ = gh_scm2int (n);
257 p.alteration_i_ = gh_scm2int (a);
258 return p.smobbed_copy ();
262 pitch_octave (SCM pp)
264 Musical_pitch *p = unsmob_pitch (pp);
267 warning ("Not a pitch");
271 return gh_int2scm (q);
275 pitch_alteration (SCM pp)
277 Musical_pitch *p = unsmob_pitch (pp);
280 warning ("Not a pitch");
282 q = p->alteration_i();
284 return gh_int2scm (q);
288 pitch_notename (SCM pp)
290 Musical_pitch *p = unsmob_pitch (pp);
293 warning ("Not a pitch");
297 return gh_int2scm (q);
301 pitch_semitones (SCM pp)
303 Musical_pitch *p = unsmob_pitch (pp);
306 warning ("Not a pitch");
310 return gh_int2scm (q);
316 scm_make_gsubr ("make-pitch", 3, 0, 0, (Scheme_function_unknown)make_pitch);
317 scm_make_gsubr ("pitch-octave", 1, 0, 0, (Scheme_function_unknown)pitch_octave);
318 scm_make_gsubr ("pitch-notename", 1, 0, 0, (Scheme_function_unknown)pitch_notename);
319 scm_make_gsubr ("pitch-alteration", 1, 0, 0, (Scheme_function_unknown)pitch_alteration);
320 scm_make_gsubr ("pitch-semitones", 1, 0, 0, (Scheme_function_unknown)pitch_semitones);
323 ADD_SCM_INIT_FUNC(pitch, add_funcs);
326 Musical_pitch::smobbed_copy ()const
328 Musical_pitch * p = new Musical_pitch (*this);
329 return p->smobbed_self ();
333 Musical_pitch::octave_i ()const
339 Musical_pitch::notename_i () const
345 Musical_pitch::alteration_i () const
347 return alteration_i_;