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>
13 #include "ly-smobs.icc"
16 todo: put string <-> pitch here too.
19 LY_DEFINE (ly_make_scale
, "ly:make-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
;
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
);
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 ();
55 LY_DEFINE (ly_default_scale
, "ly:default-scale",
57 "Get the global default scale.")
59 return default_global_scale
61 : default_global_scale
->self_scm ();
65 Scale
* default_global_scale
= 0;
67 LY_DEFINE (ly_set_default_scale
, "ly:set-default-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
;
79 return SCM_UNSPECIFIED
;
83 Scale::step_count () const
85 return step_tones_
.size ();
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);
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
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 ();
118 ret
+= step_count ();
124 Scale::print_smob (SCM x
, SCM port
, scm_print_state
*)
128 scm_puts ("#<Scale>", port
);
134 Scale::mark_smob (SCM x
)
137 return SCM_UNSPECIFIED
;
140 Scale::Scale (vector
<Rational
> const &tones
)
147 Scale::Scale (Scale
const &src
)
149 step_tones_
= src
.step_tones_
;
158 IMPLEMENT_SMOBS (Scale
);
159 IMPLEMENT_DEFAULT_EQUAL_P (Scale
);