]> git.donarmstrong.com Git - lilypond.git/blob - lily/scale.cc
Run `make grand-replace'.
[lilypond.git] / lily / scale.cc
1 /* 
2   scale.cc -- implement Scale
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2006--2008 Han-Wen Nienhuys <hanwen@lilypond.org>
7       2007--2008 Rune Zedeler
8       2008       Joe Neeman <joeneeman@gmail.com>
9 */
10
11 #include "scale.hh"
12
13 #include "ly-smobs.icc"
14
15 /*
16   todo: put string <-> pitch here too.
17
18 */
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.")
24 {
25   bool type_ok = scm_is_vector (steps);
26
27   vector<Rational> tones; 
28   if (type_ok)
29     {
30       int len = scm_c_vector_length (steps);
31       for (int i = 0 ; i < len; i++)
32         {
33           SCM step = scm_c_vector_ref (steps, i);
34           type_ok = type_ok && scm_is_rational (step);
35           if (type_ok)
36             {
37               Rational from_c (scm_to_int (scm_numerator (step)),
38                                scm_to_int (scm_denominator (step)));
39               tones.push_back (from_c);
40             }
41         }
42     }
43   
44   
45   SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of rational");
46
47   Scale *s = new Scale (tones);
48
49   SCM retval =  s->self_scm ();
50   s->unprotect ();
51   
52   return retval;
53 }
54
55 LY_DEFINE (ly_default_scale, "ly:default-scale",
56            0, 0, 0, (),
57            "Get the global default scale.")
58 {
59   return default_global_scale
60     ? SCM_BOOL_F
61     : default_global_scale->self_scm ();
62 }
63
64
65 Scale * default_global_scale = 0;
66
67 LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
68            1, 0, 0, (SCM scale),
69            "Set the global default scale.")
70 {
71   LY_ASSERT_SMOB (Scale, scale, 1);
72
73   Scale *s = Scale::unsmob (scale);
74   if (default_global_scale)
75     default_global_scale->unprotect ();
76   default_global_scale = s;
77   s->protect ();
78   
79   return SCM_UNSPECIFIED;
80 }
81
82 int
83 Scale::step_count () const
84 {
85   return step_tones_.size ();
86 }
87
88 Rational
89 Scale::tones_at_step (int step, int octave) const
90 {
91   int normalized_step = normalize_step (step);
92
93   octave += (step - normalized_step) / step_count ();
94
95   // There are 6 tones in an octave.
96   return step_tones_[normalized_step] + Rational (octave*6);
97 }
98
99 Rational
100 Scale::step_size (int step) const
101 {
102   int normalized_step = normalize_step (step);
103
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];
109
110   return step_tones_[normalized_step + 1] - step_tones_[normalized_step];
111 }
112
113 int
114 Scale::normalize_step (int step) const
115 {
116   int ret = step % step_count ();
117   if (ret < 0)
118     ret += step_count ();
119
120   return ret;
121 }
122
123 int
124 Scale::print_smob (SCM x, SCM port, scm_print_state *)
125 {
126   (void) x;
127   
128   scm_puts ("#<Scale>", port); 
129   return 1;
130 }
131
132
133 SCM
134 Scale::mark_smob (SCM x)
135 {
136   (void) x;
137   return SCM_UNSPECIFIED;
138 }
139
140 Scale::Scale (vector<Rational> const &tones)
141 {
142   step_tones_ = tones;
143
144   smobify_self ();
145 }
146
147 Scale::Scale (Scale const &src)
148 {
149   step_tones_ = src.step_tones_;
150   smobify_self ();
151 }
152
153
154 Scale::~Scale ()
155 {
156 }
157
158 IMPLEMENT_SMOBS (Scale);
159 IMPLEMENT_DEFAULT_EQUAL_P (Scale);