Consider accidentals in optical spacing correction.
[lilypond.git] / lily / scale.cc
blobc1f9a81f0550c394a8f9ec6dc06e9b06d5c68869
1 /*
2 scale.cc -- implement Scale
4 source file of the GNU LilyPond music typesetter
6 (c) 2006--2009 Han-Wen Nienhuys <hanwen@lilypond.org>
7 2007--2008 Rune Zedeler
8 2008 Joe Neeman <joeneeman@gmail.com>
9 */
11 #include "scale.hh"
13 #include "ly-smobs.icc"
16 todo: put string <-> pitch here too.
19 LY_DEFINE (ly_make_scale, "ly:make-scale",
20 1, 0, 0, (SCM steps),
21 "Create a scale."
22 " The argument is a vector of rational numbers, each of which"
23 " represents the number of 200 cent tones of a pitch above the"
24 " tonic.")
26 bool type_ok = scm_is_vector (steps);
28 vector<Rational> tones;
29 if (type_ok)
31 int len = scm_c_vector_length (steps);
32 for (int i = 0 ; i < len; i++)
34 SCM step = scm_c_vector_ref (steps, i);
35 type_ok = type_ok && scm_is_rational (step);
36 if (type_ok)
38 Rational from_c (scm_to_int (scm_numerator (step)),
39 scm_to_int (scm_denominator (step)));
40 tones.push_back (from_c);
46 SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational");
48 Scale *s = new Scale (tones);
50 SCM retval = s->self_scm ();
51 s->unprotect ();
53 return retval;
56 LY_DEFINE (ly_default_scale, "ly:default-scale",
57 0, 0, 0, (),
58 "Get the global default scale.")
60 return default_global_scale
61 ? default_global_scale->self_scm ()
62 : SCM_BOOL_F;
66 Scale * default_global_scale = 0;
68 LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
69 1, 0, 0, (SCM scale),
70 "Set the global default scale. This determines the tuning of"
71 " pitches with no accidentals or key signatures. The first"
72 " pitch is C. Alterations are calculated relative to this"
73 " scale. The number of pitches in this scale determines the"
74 " number of scale steps that make up an octave. Usually the"
75 " 7-note major scale.")
77 LY_ASSERT_SMOB (Scale, scale, 1);
79 Scale *s = Scale::unsmob (scale);
80 if (default_global_scale)
81 default_global_scale->unprotect ();
82 default_global_scale = s;
83 s->protect ();
85 return SCM_UNSPECIFIED;
88 int
89 Scale::step_count () const
91 return step_tones_.size ();
94 Rational
95 Scale::tones_at_step (int step, int octave) const
97 int normalized_step = normalize_step (step);
99 octave += (step - normalized_step) / step_count ();
101 // There are 6 tones in an octave.
102 return step_tones_[normalized_step] + Rational (octave*6);
105 Rational
106 Scale::step_size (int step) const
108 int normalized_step = normalize_step (step);
110 // Wrap around if we are asked for the final note of the
111 // scale (6 is the number of tones of the octave above the
112 // first note).
113 if (normalized_step + 1 == step_count ())
114 return Rational(6) - step_tones_[normalized_step];
116 return step_tones_[normalized_step + 1] - step_tones_[normalized_step];
120 Scale::normalize_step (int step) const
122 int ret = step % step_count ();
123 if (ret < 0)
124 ret += step_count ();
126 return ret;
130 Scale::print_smob (SCM /* x */,
131 SCM port,
132 scm_print_state *)
134 scm_puts ("#<Scale>", port);
135 return 1;
139 Scale::mark_smob (SCM)
141 return SCM_UNSPECIFIED;
144 Scale::Scale (vector<Rational> const &tones)
146 step_tones_ = tones;
148 smobify_self ();
151 Scale::Scale (Scale const &src)
153 step_tones_ = src.step_tones_;
154 smobify_self ();
158 Scale::~Scale ()
162 IMPLEMENT_SMOBS (Scale);
163 IMPLEMENT_DEFAULT_EQUAL_P (Scale);