2 music.cc -- implement Music
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "input-smob.hh"
12 #include "music-list.hh"
15 #include "ly-smobs.icc"
18 ly_deep_mus_copy (SCM m)
22 SCM ss = unsmob_music (m)->clone ()->self_scm ();
23 scm_gc_unprotect_object (ss);
26 else if (gh_pair_p (m))
28 return gh_cons (ly_deep_mus_copy (ly_car (m)), ly_deep_mus_copy (ly_cdr (m)));
35 Music::internal_is_music_type (SCM k)const
37 SCM ifs = get_mus_property ("types");
39 return scm_memq (k, ifs) != SCM_BOOL_F;
43 Music::transpose (Pitch)
48 Music::compress (Moment)
53 Music::Music (Music const &m)
55 immutable_property_alist_ = m.immutable_property_alist_;
56 mutable_property_alist_ = SCM_EOL;
60 First we smobify_self, then we copy over the stuff. If we don't,
61 stack vars that hold the copy might be optimized away, meaning
62 that they won't be protected from GC.
65 mutable_property_alist_ = ly_deep_mus_copy (m.mutable_property_alist_);
66 set_spot (*m.origin ());
72 immutable_property_alist_ = SCM_EOL;
73 mutable_property_alist_ = SCM_EOL;
78 Music::get_property_alist (bool m) const
80 return (m) ? mutable_property_alist_ : immutable_property_alist_;
84 Music::mark_smob (SCM m)
86 Music * mus = (Music *)SCM_CELL_WORD_1 (m);
87 scm_gc_mark (mus->immutable_property_alist_);
88 scm_gc_mark (mus->mutable_property_alist_);
93 Music::length_mom () const
95 SCM l = get_mus_property ("length");
96 if (unsmob_moment (l))
97 return *unsmob_moment (l);
98 else if (gh_procedure_p (l))
100 SCM res = gh_call1 (l, self_scm ());
101 return *unsmob_moment (res);
108 Music::start_mom () const
110 SCM l = get_mus_property ("start-moment-function");
111 if (gh_procedure_p (l))
113 SCM res = gh_call1 (l, self_scm ());
114 return *unsmob_moment (res);
122 print_alist (SCM a, SCM port)
125 SCM_EOL -> catch malformed lists.
127 for (SCM s = a; gh_pair_p (s); s = ly_cdr (s))
129 scm_display (ly_caar (s), port);
130 scm_puts (" = ", port);
131 scm_write (ly_cdar (s), port);
132 scm_puts ("\n", port);
137 Music::print_smob (SCM s, SCM p, scm_print_state*)
139 scm_puts ("#<Music ", p);
140 Music* m = unsmob_music (s);
141 scm_puts (classname (m),p);
143 print_alist (m->mutable_property_alist_, p);
144 print_alist (m->immutable_property_alist_, p);
151 Music::to_relative_octave (Pitch m)
157 IMPLEMENT_TYPE_P (Music, "music?");
159 IMPLEMENT_SMOBS (Music);
160 IMPLEMENT_DEFAULT_EQUAL_P (Music);
162 /****************************/
165 Music::internal_get_mus_property (SCM sym) const
167 SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
171 s = scm_sloppy_assq (sym, immutable_property_alist_);
172 return (s == SCM_BOOL_F) ? SCM_EOL : ly_cdr (s);
176 Music::internal_set_mus_property (SCM s, SCM v)
178 if (internal_type_checking_global_b)
179 if (!type_check_assignment (s, v, ly_symbol2scm ("music-type?")))
182 mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
190 Music::set_spot (Input ip)
192 set_mus_property ("origin", make_input (ip));
196 Music::origin () const
198 Input *ip = unsmob_input (get_mus_property ("origin"));
199 return ip ? ip : & dummy_input_global;
208 LY_DEFINE(ly_get_mus_property,
209 "ly-get-mus-property", 2, 0, 0, (SCM mus, SCM sym),
210 "Get the property @var{sym} of music expression @var{mus}.")
212 Music * sc = unsmob_music (mus);
213 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
214 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
216 return sc->internal_get_mus_property (sym);
219 LY_DEFINE(ly_set_mus_property,
220 "ly-set-mus-property!", 3, 0, 0,
221 (SCM mus, SCM sym, SCM val),
222 "Set property @var{sym} in music expression @var{mus} to @var{val}.")
224 Music * sc = unsmob_music (mus);
225 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
226 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
228 bool ok = type_check_assignment (sym, val, ly_symbol2scm ("music-type?"));
231 sc->internal_set_mus_property (sym, val);
234 return SCM_UNSPECIFIED;
238 LY_DEFINE(ly_music_name, "ly-music-name", 1, 0, 0,
240 "Return the name of @var{music}.")
242 Music * m = unsmob_music (mus);
243 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__ ,"music");
245 const char * nm = classname (m);
246 return scm_makfrom0str (nm);
251 // to do property args
252 LY_DEFINE(ly_extended_make_music,
253 "ly-make-bare-music", 2, 0, 0, (SCM type, SCM props),
255 Make a music object/expression of type @var{type}, init with
256 @var{props}. Warning: this interface will likely change in the near
259 Music is the data type that music expressions are stored in. The data
260 type does not yet offer many manipulations.
262 WARNING: deprecated; use make-music-by-name.
265 SCM_ASSERT_TYPE(gh_string_p (type), type, SCM_ARG1, __FUNCTION__, "string");
267 SCM s = make_music (ly_scm2string (type))->self_scm ();
268 unsmob_music (s)->immutable_property_alist_ = props;
269 scm_gc_unprotect_object (s);
273 // to do property args
274 LY_DEFINE(ly_get_mutable_properties,
275 "ly-get-mutable-properties", 1, 0, 0, (SCM mus),
277 Return an alist signifying the mutable properties of @var{mus}.
278 The immutable properties are not available; they should be initialized
279 by the functions make-music-by-name function.
282 Music *m = unsmob_music (mus);
283 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "music");
285 return m->get_property_alist (true);
288 LY_DEFINE(ly_music_list_p,"music-list?", 1, 0, 0,
289 (SCM l),"Type predicate: return true if @var{l} is a list of music objects.")
291 if (scm_list_p (l) != SCM_BOOL_T)
294 while (gh_pair_p (l))
296 if (!unsmob_music (gh_car (l)))
309 make_music_by_name (SCM sym)
311 if (!make_music_proc)
312 make_music_proc = scm_primitive_eval (ly_symbol2scm ("make-music-by-name"));
314 SCM rv = scm_call_1 (make_music_proc, sym);
319 scm_gc_protect_object (rv);
320 return unsmob_music (rv);