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_
;