Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / scale.cc
blob5de25f5c43c3df00f09fe9750146e91d3640890e
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2006--2011 Han-Wen Nienhuys <hanwen@lilypond.org>
5 2007--2008 Rune Zedeler
6 2008 Joe Neeman <joeneeman@gmail.com>
8 LilyPond is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 LilyPond is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22 #include "scale.hh"
24 #include "ly-smobs.icc"
27 todo: put string <-> pitch here too.
30 LY_DEFINE (ly_make_scale, "ly:make-scale",
31 1, 0, 0, (SCM steps),
32 "Create a scale."
33 " The argument is a vector of rational numbers, each of which"
34 " represents the number of 200 cent tones of a pitch above the"
35 " tonic.")
37 bool type_ok = scm_is_vector (steps);
39 vector<Rational> tones;
40 if (type_ok)
42 int len = scm_c_vector_length (steps);
43 for (int i = 0 ; i < len; i++)
45 SCM step = scm_c_vector_ref (steps, i);
46 type_ok = type_ok && scm_is_rational (step);
47 if (type_ok)
49 Rational from_c (scm_to_int (scm_numerator (step)),
50 scm_to_int (scm_denominator (step)));
51 tones.push_back (from_c);
57 SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational");
59 Scale *s = new Scale (tones);
61 SCM retval = s->self_scm ();
62 s->unprotect ();
64 return retval;
67 LY_DEFINE (ly_default_scale, "ly:default-scale",
68 0, 0, 0, (),
69 "Get the global default scale.")
71 return default_global_scale
72 ? default_global_scale->self_scm ()
73 : SCM_BOOL_F;
77 Scale * default_global_scale = 0;
79 LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
80 1, 0, 0, (SCM scale),
81 "Set the global default scale. This determines the tuning of"
82 " pitches with no accidentals or key signatures. The first"
83 " pitch is C. Alterations are calculated relative to this"
84 " scale. The number of pitches in this scale determines the"
85 " number of scale steps that make up an octave. Usually the"
86 " 7-note major scale.")
88 LY_ASSERT_SMOB (Scale, scale, 1);
90 Scale *s = Scale::unsmob (scale);
91 if (default_global_scale)
92 default_global_scale->unprotect ();
93 default_global_scale = s;
94 s->protect ();
96 return SCM_UNSPECIFIED;
99 int
100 Scale::step_count () const
102 return step_tones_.size ();
105 Rational
106 Scale::tones_at_step (int step, int octave) const
108 int normalized_step = normalize_step (step);
110 octave += (step - normalized_step) / step_count ();
112 // There are 6 tones in an octave.
113 return step_tones_[normalized_step] + Rational (octave*6);
116 Rational
117 Scale::step_size (int step) const
119 int normalized_step = normalize_step (step);
121 // Wrap around if we are asked for the final note of the
122 // scale (6 is the number of tones of the octave above the
123 // first note).
124 if (normalized_step + 1 == step_count ())
125 return Rational(6) - step_tones_[normalized_step];
127 return step_tones_[normalized_step + 1] - step_tones_[normalized_step];
131 Scale::normalize_step (int step) const
133 int ret = step % step_count ();
134 if (ret < 0)
135 ret += step_count ();
137 return ret;
141 Scale::print_smob (SCM /* x */,
142 SCM port,
143 scm_print_state *)
145 scm_puts ("#<Scale>", port);
146 return 1;
150 Scale::mark_smob (SCM)
152 return SCM_UNSPECIFIED;
155 Scale::Scale (vector<Rational> const &tones)
157 step_tones_ = tones;
159 smobify_self ();
162 Scale::Scale (Scale const &src)
164 step_tones_ = src.step_tones_;
165 smobify_self ();
169 Scale::~Scale ()
173 IMPLEMENT_SMOBS (Scale);
174 IMPLEMENT_DEFAULT_EQUAL_P (Scale);