]> git.donarmstrong.com Git - lilypond.git/blob - lily/scale.cc
Run grand replace for 2015.
[lilypond.git] / lily / scale.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2006--2015 Han-Wen Nienhuys <hanwen@lilypond.org>
5       2007--2008 Rune Zedeler
6       2008       Joe Neeman <joeneeman@gmail.com>
7
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.
12
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.
17
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/>.
20 */
21
22 #include "scale.hh"
23
24
25 /*
26   todo: put string <-> pitch here too.
27 */
28 LY_DEFINE (ly_make_scale, "ly:make-scale",
29            1, 0, 0, (SCM steps),
30            "Create a scale."
31            "  The argument is a vector of rational numbers, each of which"
32            " represents the number of 200 cent tones of a pitch above the"
33            " tonic.")
34 {
35   bool type_ok = scm_is_vector (steps);
36
37   vector<Rational> tones;
38   if (type_ok)
39     {
40       int len = scm_c_vector_length (steps);
41       for (int i = 0; i < len; i++)
42         {
43           SCM step = scm_c_vector_ref (steps, i);
44           type_ok = type_ok && scm_is_rational (step);
45           if (type_ok)
46             {
47               Rational from_c (scm_to_int (scm_numerator (step)),
48                                scm_to_int (scm_denominator (step)));
49               tones.push_back (from_c);
50             }
51         }
52     }
53
54   SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational");
55
56   Scale *s = new Scale (tones);
57
58   SCM retval = s->self_scm ();
59   s->unprotect ();
60
61   return retval;
62 }
63
64 LY_DEFINE (ly_default_scale, "ly:default-scale",
65            0, 0, 0, (),
66            "Get the global default scale.")
67 {
68   return default_global_scale
69          ? default_global_scale->self_scm ()
70          : SCM_BOOL_F;
71 }
72
73 Scale *default_global_scale = 0;
74
75 LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
76            1, 0, 0, (SCM scale),
77            "Set the global default scale.  This determines the tuning of"
78            " pitches with no accidentals or key signatures.  The first"
79            " pitch is C.  Alterations are calculated relative to this"
80            " scale.  The number of pitches in this scale determines the"
81            " number of scale steps that make up an octave.  Usually the"
82            " 7-note major scale.")
83 {
84   LY_ASSERT_SMOB (Scale, scale, 1);
85
86   Scale *s = Scale::unsmob (scale);
87   if (default_global_scale)
88     default_global_scale->unprotect ();
89   default_global_scale = s;
90   s->protect ();
91
92   return SCM_UNSPECIFIED;
93 }
94
95 int
96 Scale::step_count () const
97 {
98   return step_tones_.size ();
99 }
100
101 Rational
102 Scale::tones_at_step (int step, int octave) const
103 {
104   int normalized_step = normalize_step (step);
105
106   octave += (step - normalized_step) / step_count ();
107
108   // There are 6 tones in an octave.
109   return step_tones_[normalized_step] + Rational (octave * 6);
110 }
111
112 Rational
113 Scale::step_size (int step) const
114 {
115   int normalized_step = normalize_step (step);
116
117   // Wrap around if we are asked for the final note of the
118   // scale (6 is the number of tones of the octave above the
119   // first note).
120   if (normalized_step + 1 == step_count ())
121     return Rational (6) - step_tones_[normalized_step];
122
123   return step_tones_[normalized_step + 1] - step_tones_[normalized_step];
124 }
125
126 int
127 Scale::normalize_step (int step) const
128 {
129   int ret = step % step_count ();
130   if (ret < 0)
131     ret += step_count ();
132
133   return ret;
134 }
135
136
137
138 Scale::Scale (vector<Rational> const &tones)
139 {
140   step_tones_ = tones;
141
142   smobify_self ();
143 }
144
145 Scale::Scale (Scale const &src)
146   : Smob<Scale> ()
147 {
148   step_tones_ = src.step_tones_;
149   smobify_self ();
150 }
151
152 Scale::~Scale ()
153 {
154 }