2 music.cc -- implement Music
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "input-smob.hh"
12 #include "music-list.hh"
15 #include "ly-smobs.icc"
18 SCM ly_deep_mus_copy (SCM);
21 Music::internal_is_music_type (SCM k)const
23 SCM ifs = get_mus_property ("types");
25 return scm_memq (k, ifs) != SCM_BOOL_F;
31 SCM nm = get_mus_property ("name");
34 return ly_symbol2string (nm);
38 return classname (this);
43 Music::transpose (Pitch)
48 Music::compress (Moment)
52 Music::Music (Music const &m)
54 immutable_property_alist_ = m.immutable_property_alist_;
55 mutable_property_alist_ = SCM_EOL;
59 First we smobify_self, then we copy over the stuff. If we don't,
60 stack vars that hold the copy might be optimized away, meaning
61 that they won't be protected from GC.
64 mutable_property_alist_ = ly_deep_mus_copy (m.mutable_property_alist_);
65 set_spot (*m.origin ());
71 immutable_property_alist_ = SCM_EOL;
72 mutable_property_alist_ = SCM_EOL;
77 Music::get_property_alist (bool m) const
79 return (m) ? mutable_property_alist_ : immutable_property_alist_;
83 Music::mark_smob (SCM m)
85 Music * mus = (Music *)SCM_CELL_WORD_1 (m);
86 scm_gc_mark (mus->immutable_property_alist_);
87 scm_gc_mark (mus->mutable_property_alist_);
92 Music::get_length () const
94 SCM l = get_mus_property ("length");
95 if (unsmob_moment (l))
96 return *unsmob_moment (l);
97 else if (gh_procedure_p (l))
99 SCM res = gh_call1 (l, self_scm ());
100 return *unsmob_moment (res);
107 Music::start_mom () const
109 SCM l = get_mus_property ("start-moment-function");
110 if (gh_procedure_p (l))
112 SCM res = gh_call1 (l, self_scm ());
113 return *unsmob_moment (res);
121 print_alist (SCM a, SCM port)
124 SCM_EOL -> catch malformed lists.
126 for (SCM s = a; gh_pair_p (s); s = ly_cdr (s))
128 scm_display (ly_caar (s), port);
129 scm_puts (" = ", port);
130 scm_write (ly_cdar (s), port);
131 scm_puts ("\n", port);
136 Music::print_smob (SCM s, SCM p, scm_print_state*)
138 scm_puts ("#<Music ", p);
139 Music* m = unsmob_music (s);
141 SCM nm = m->get_mus_property ("name");
142 if (gh_symbol_p (nm) || gh_string_p (nm))
148 scm_puts (classname (m),p);
152 Printing properties takes a lot of time, especially during backtraces.
153 For inspecting, it is better to explicitly use an inspection
162 Music::to_relative_octave (Pitch m)
168 IMPLEMENT_TYPE_P (Music, "ly:music?");
170 IMPLEMENT_SMOBS (Music);
171 IMPLEMENT_DEFAULT_EQUAL_P (Music);
173 /****************************/
176 Music::internal_get_mus_property (SCM sym) const
178 SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
182 s = scm_sloppy_assq (sym, immutable_property_alist_);
183 return (s == SCM_BOOL_F) ? SCM_EOL : ly_cdr (s);
187 Music::internal_set_mus_property (SCM s, SCM v)
189 if (internal_type_checking_global_b)
190 if (!type_check_assignment (s, v, ly_symbol2scm ("music-type?")))
193 mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
201 Music::set_spot (Input ip)
203 set_mus_property ("origin", make_input (ip));
207 Music::origin () const
209 Input *ip = unsmob_input (get_mus_property ("origin"));
210 return ip ? ip : & dummy_input_global;
219 LY_DEFINE(ly_get_music_length,
220 "ly:get-music-length", 1, 0, 0, (SCM mus),
221 "Get the length (in musical time) of music expression @var{mus}.")
223 Music * sc = unsmob_music (mus);
224 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
225 return sc->get_length().smobbed_copy();
228 LY_DEFINE(ly_get_mus_property,
229 "ly:get-mus-property", 2, 0, 0, (SCM mus, SCM sym),
230 "Get the property @var{sym} of music expression @var{mus}.\n"
231 "If @var{sym} is undefined, return @code{'()}.\n"
234 Music * sc = unsmob_music (mus);
235 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
236 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
238 return sc->internal_get_mus_property (sym);
241 LY_DEFINE(ly_set_mus_property,
242 "ly:set-mus-property!", 3, 0, 0,
243 (SCM mus, SCM sym, SCM val),
244 "Set property @var{sym} in music expression @var{mus} to @var{val}.")
246 Music * sc = unsmob_music (mus);
247 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
248 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
250 bool ok = type_check_assignment (sym, val, ly_symbol2scm ("music-type?"));
253 sc->internal_set_mus_property (sym, val);
256 return SCM_UNSPECIFIED;
260 LY_DEFINE(ly_music_name, "ly:music-name", 1, 0, 0,
262 "Return the name of @var{music}.")
264 Music * m = unsmob_music (mus);
265 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__ ,"music");
267 const char * nm = classname (m);
268 return scm_makfrom0str (nm);
273 // to do property args
274 LY_DEFINE(ly_extended_make_music,
275 "ly:make-bare-music", 2, 0, 0, (SCM type, SCM props),
276 "Make a music object/expression of type @var{type}, init with\n"
277 "@var{props}. Warning: this interface will likely change in the near\n"
280 "Music is the data type that music expressions are stored in. The data\n"
281 "type does not yet offer many manipulations.\n"
283 "WARNING: only for internal use. Please use make-music-by-name. \n"
286 SCM_ASSERT_TYPE(gh_string_p (type), type, SCM_ARG1, __FUNCTION__, "string");
288 SCM s = make_music (ly_scm2string (type))->self_scm ();
289 unsmob_music (s)->immutable_property_alist_ = props;
290 scm_gc_unprotect_object (s);
294 // to do property args
295 LY_DEFINE(ly_get_mutable_properties,
296 "ly:get-mutable-properties", 1, 0, 0, (SCM mus),
297 "Return an alist signifying the mutable properties of @var{mus}.\n"
298 "The immutable properties are not available; they should be initialized\n"
299 "by the functions make-music-by-name function.\n"
302 Music *m = unsmob_music (mus);
303 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "music");
305 return m->get_property_alist (true);
308 LY_DEFINE(ly_music_list_p,"music-list?", 1, 0, 0,
309 (SCM l),"Type predicate: return true if @var{l} is a list of music objects.")
311 if (scm_list_p (l) != SCM_BOOL_T)
314 while (gh_pair_p (l))
316 if (!unsmob_music (gh_car (l)))
326 LY_DEFINE(ly_deep_mus_copy,
327 "ly:music-deep-copy", 1,0,0, (SCM m),
328 "Copy @var{m} and all sub expressions of @var{m}")
330 if (unsmob_music (m))
332 SCM ss = unsmob_music (m)->clone ()->self_scm ();
333 scm_gc_unprotect_object (ss);
336 else if (gh_pair_p (m))
338 return gh_cons (ly_deep_mus_copy (ly_car (m)), ly_deep_mus_copy (ly_cdr (m)));
344 LY_DEFINE(ly_music_transpose,
345 "ly:music-transpose", 2,0,0, (SCM m, SCM p),
346 "Transpose @var{m} such that central C is mapped to @var{p}. "
349 Music * sc = unsmob_music (m);
350 Pitch * sp = unsmob_pitch (p);
351 SCM_ASSERT_TYPE(sc, m, SCM_ARG1, __FUNCTION__, "music");
352 SCM_ASSERT_TYPE(sp, p, SCM_ARG2, __FUNCTION__, "pitch");
355 return sc->self_scm(); // SCM_UNDEFINED ?
363 make_music_by_name (SCM sym)
365 if (!make_music_proc)
366 make_music_proc = scm_primitive_eval (ly_symbol2scm ("make-music-by-name"));
368 SCM rv = scm_call_1 (make_music_proc, sym);
373 scm_gc_protect_object (rv);
374 return unsmob_music (rv);