Add arrowed sharp signs
[lilypond.git] / lily / scale.cc
blob9e39d8a99e83fa992a31c1be95fdb37a362c15ac
1 /*
2 scale.cc -- implement Scale
4 source file of the GNU LilyPond music typesetter
6 (c) 2006--2008 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 tones of a pitch above the tonic.")
25 bool type_ok = scm_is_vector (steps);
27 vector<Rational> tones;
28 if (type_ok)
30 int len = scm_c_vector_length (steps);
31 for (int i = 0 ; i < len; i++)
33 SCM step = scm_c_vector_ref (steps, i);
34 type_ok = type_ok && scm_is_rational (step);
35 if (type_ok)
37 Rational from_c (scm_to_int (scm_numerator (step)),
38 scm_to_int (scm_denominator (step)));
39 tones.push_back (from_c);
45 SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational");
47 Scale *s = new Scale (tones);
49 SCM retval = s->self_scm ();
50 s->unprotect ();
52 return retval;
55 LY_DEFINE (ly_default_scale, "ly:default-scale",
56 0, 0, 0, (),
57 "Get the global default scale.")
59 return default_global_scale
60 ? SCM_BOOL_F
61 : default_global_scale->self_scm ();
65 Scale * default_global_scale = 0;
67 LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
68 1, 0, 0, (SCM scale),
69 "Set the global default scale.")
71 LY_ASSERT_SMOB (Scale, scale, 1);
73 Scale *s = Scale::unsmob (scale);
74 if (default_global_scale)
75 default_global_scale->unprotect ();
76 default_global_scale = s;
77 s->protect ();
79 return SCM_UNSPECIFIED;
82 int
83 Scale::step_count () const
85 return step_tones_.size ();
88 Rational
89 Scale::tones_at_step (int step, int octave) const
91 int normalized_step = normalize_step (step);
93 octave += (step - normalized_step) / step_count ();
95 // There are 6 tones in an octave.
96 return step_tones_[normalized_step] + Rational (octave*6);
99 Rational
100 Scale::step_size (int step) const
102 int normalized_step = normalize_step (step);
104 // Wrap around if we are asked for the final note of the
105 // scale (6 is the number of tones of the octave above the
106 // first note).
107 if (normalized_step + 1 == step_count ())
108 return Rational(6) - step_tones_[normalized_step];
110 return step_tones_[normalized_step + 1] - step_tones_[normalized_step];
114 Scale::normalize_step (int step) const
116 int ret = step % step_count ();
117 if (ret < 0)
118 ret += step_count ();
120 return ret;
124 Scale::print_smob (SCM x, SCM port, scm_print_state *)
126 (void) x;
128 scm_puts ("#<Scale>", port);
129 return 1;
134 Scale::mark_smob (SCM x)
136 (void) x;
137 return SCM_UNSPECIFIED;
140 Scale::Scale (vector<Rational> const &tones)
142 step_tones_ = tones;
144 smobify_self ();
147 Scale::Scale (Scale const &src)
149 step_tones_ = src.step_tones_;
150 smobify_self ();
154 Scale::~Scale ()
158 IMPLEMENT_SMOBS (Scale);
159 IMPLEMENT_DEFAULT_EQUAL_P (Scale);