X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fscale.cc;h=c1f9a81f0550c394a8f9ec6dc06e9b06d5c68869;hb=bbaf60edda2d5dd759050c1046cbd9865f3affbd;hp=0859c25dba306de8fdddaca00c4a421fb0c7a9c6;hpb=c5a3f0c024f4cb629811cff9eb04abff36e94138;p=lilypond.git diff --git a/lily/scale.cc b/lily/scale.cc index 0859c25dba..c1f9a81f05 100644 --- a/lily/scale.cc +++ b/lily/scale.cc @@ -3,8 +3,9 @@ source file of the GNU LilyPond music typesetter - (c) 2006--2007 Han-Wen Nienhuys - + (c) 2006--2009 Han-Wen Nienhuys + 2007--2008 Rune Zedeler + 2008 Joe Neeman */ #include "scale.hh" @@ -17,34 +18,36 @@ */ LY_DEFINE (ly_make_scale, "ly:make-scale", 1, 0, 0, (SCM steps), - "Create a scale. Takes a vector of ints as argument") + "Create a scale." + " The argument is a vector of rational numbers, each of which" + " represents the number of 200 cent tones of a pitch above the" + " tonic.") { bool type_ok = scm_is_vector (steps); - vector semitones; + vector tones; if (type_ok) { int len = scm_c_vector_length (steps); for (int i = 0 ; i < len; i++) { - SCM step = scm_c_vector_ref (steps, i); + SCM step = scm_c_vector_ref (steps, i); type_ok = type_ok && scm_is_rational (step); if (type_ok) { Rational from_c (scm_to_int (scm_numerator (step)), scm_to_int (scm_denominator (step))); - semitones.push_back (from_c); + tones.push_back (from_c); } } } - SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of int"); + + SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational"); - Scale *s = new Scale; - s->step_tones_ = semitones; + Scale *s = new Scale (tones); SCM retval = s->self_scm (); - s->unprotect (); return retval; @@ -55,8 +58,8 @@ LY_DEFINE (ly_default_scale, "ly:default-scale", "Get the global default scale.") { return default_global_scale - ? SCM_BOOL_F - : default_global_scale->self_scm (); + ? default_global_scale->self_scm () + : SCM_BOOL_F; } @@ -64,7 +67,12 @@ Scale * default_global_scale = 0; LY_DEFINE (ly_set_default_scale, "ly:set-default-scale", 1, 0, 0, (SCM scale), - "Set the global default scale.") + "Set the global default scale. This determines the tuning of" + " pitches with no accidentals or key signatures. The first" + " pitch is C. Alterations are calculated relative to this" + " scale. The number of pitches in this scale determines the" + " number of scale steps that make up an octave. Usually the" + " 7-note major scale.") { LY_ASSERT_SMOB (Scale, scale, 1); @@ -77,26 +85,66 @@ LY_DEFINE (ly_set_default_scale, "ly:set-default-scale", return SCM_UNSPECIFIED; } +int +Scale::step_count () const +{ + return step_tones_.size (); +} + +Rational +Scale::tones_at_step (int step, int octave) const +{ + int normalized_step = normalize_step (step); + + octave += (step - normalized_step) / step_count (); + + // There are 6 tones in an octave. + return step_tones_[normalized_step] + Rational (octave*6); +} + +Rational +Scale::step_size (int step) const +{ + int normalized_step = normalize_step (step); + + // Wrap around if we are asked for the final note of the + // scale (6 is the number of tones of the octave above the + // first note). + if (normalized_step + 1 == step_count ()) + return Rational(6) - step_tones_[normalized_step]; + + return step_tones_[normalized_step + 1] - step_tones_[normalized_step]; +} int -Scale::print_smob (SCM x, SCM port, scm_print_state *) +Scale::normalize_step (int step) const +{ + int ret = step % step_count (); + if (ret < 0) + ret += step_count (); + + return ret; +} + +int +Scale::print_smob (SCM /* x */, + SCM port, + scm_print_state *) { - (void) x; - scm_puts ("#", port); return 1; } - SCM -Scale::mark_smob (SCM x) +Scale::mark_smob (SCM) { - (void) x; return SCM_UNSPECIFIED; } -Scale::Scale () +Scale::Scale (vector const &tones) { + step_tones_ = tones; + smobify_self (); } @@ -111,5 +159,5 @@ Scale::~Scale () { } -IMPLEMENT_SMOBS(Scale); -IMPLEMENT_DEFAULT_EQUAL_P(Scale); +IMPLEMENT_SMOBS (Scale); +IMPLEMENT_DEFAULT_EQUAL_P (Scale);