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 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;
45 SCM nm = get_mus_property ("name");
48 return ly_symbol2string (nm);
52 return classname (this);
57 Music::transpose (Pitch)
62 Music::compress (Moment)
67 Music::Music (Music const &m)
69 immutable_property_alist_ = m.immutable_property_alist_;
70 mutable_property_alist_ = SCM_EOL;
74 First we smobify_self, then we copy over the stuff. If we don't,
75 stack vars that hold the copy might be optimized away, meaning
76 that they won't be protected from GC.
79 mutable_property_alist_ = ly_deep_mus_copy (m.mutable_property_alist_);
80 set_spot (*m.origin ());
86 immutable_property_alist_ = SCM_EOL;
87 mutable_property_alist_ = SCM_EOL;
92 Music::get_property_alist (bool m) const
94 return (m) ? mutable_property_alist_ : immutable_property_alist_;
98 Music::mark_smob (SCM m)
100 Music * mus = (Music *)SCM_CELL_WORD_1 (m);
101 scm_gc_mark (mus->immutable_property_alist_);
102 scm_gc_mark (mus->mutable_property_alist_);
107 Music::get_length () const
109 SCM l = get_mus_property ("length");
110 if (unsmob_moment (l))
111 return *unsmob_moment (l);
112 else if (gh_procedure_p (l))
114 SCM res = gh_call1 (l, self_scm ());
115 return *unsmob_moment (res);
122 Music::start_mom () const
124 SCM l = get_mus_property ("start-moment-function");
125 if (gh_procedure_p (l))
127 SCM res = gh_call1 (l, self_scm ());
128 return *unsmob_moment (res);
136 print_alist (SCM a, SCM port)
139 SCM_EOL -> catch malformed lists.
141 for (SCM s = a; gh_pair_p (s); s = ly_cdr (s))
143 scm_display (ly_caar (s), port);
144 scm_puts (" = ", port);
145 scm_write (ly_cdar (s), port);
146 scm_puts ("\n", port);
151 Music::print_smob (SCM s, SCM p, scm_print_state*)
153 scm_puts ("#<Music ", p);
154 Music* m = unsmob_music (s);
155 scm_puts (classname (m),p);
158 Printing these takes a lot of time, especially during backtraces.
159 For inspecting, it is better to explicitly use an inspection
168 Music::to_relative_octave (Pitch m)
174 IMPLEMENT_TYPE_P (Music, "ly:music?");
176 IMPLEMENT_SMOBS (Music);
177 IMPLEMENT_DEFAULT_EQUAL_P (Music);
179 /****************************/
182 Music::internal_get_mus_property (SCM sym) const
184 SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
188 s = scm_sloppy_assq (sym, immutable_property_alist_);
189 return (s == SCM_BOOL_F) ? SCM_EOL : ly_cdr (s);
193 Music::internal_set_mus_property (SCM s, SCM v)
195 if (internal_type_checking_global_b)
196 if (!type_check_assignment (s, v, ly_symbol2scm ("music-type?")))
199 mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
207 Music::set_spot (Input ip)
209 set_mus_property ("origin", make_input (ip));
213 Music::origin () const
215 Input *ip = unsmob_input (get_mus_property ("origin"));
216 return ip ? ip : & dummy_input_global;
225 LY_DEFINE(ly_get_music_length,
226 "ly:get-music-length", 1, 0, 0, (SCM mus),
227 "Get the length (in musical time) of music expression @var{mus}.")
229 Music * sc = unsmob_music (mus);
230 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
231 return sc->get_length().smobbed_copy();
234 LY_DEFINE(ly_get_mus_property,
235 "ly:get-mus-property", 2, 0, 0, (SCM mus, SCM sym),
236 "Get the property @var{sym} of music expression @var{mus}.")
238 Music * sc = unsmob_music (mus);
239 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
240 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
242 return sc->internal_get_mus_property (sym);
245 LY_DEFINE(ly_set_mus_property,
246 "ly:set-mus-property!", 3, 0, 0,
247 (SCM mus, SCM sym, SCM val),
248 "Set property @var{sym} in music expression @var{mus} to @var{val}.")
250 Music * sc = unsmob_music (mus);
251 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
252 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
254 bool ok = type_check_assignment (sym, val, ly_symbol2scm ("music-type?"));
257 sc->internal_set_mus_property (sym, val);
260 return SCM_UNSPECIFIED;
264 LY_DEFINE(ly_music_name, "ly:music-name", 1, 0, 0,
266 "Return the name of @var{music}.")
268 Music * m = unsmob_music (mus);
269 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__ ,"music");
271 const char * nm = classname (m);
272 return scm_makfrom0str (nm);
277 // to do property args
278 LY_DEFINE(ly_extended_make_music,
279 "ly:make-bare-music", 2, 0, 0, (SCM type, SCM props),
280 "Make a music object/expression of type @var{type}, init with\n"
281 "@var{props}. Warning: this interface will likely change in the near\n"
284 "Music is the data type that music expressions are stored in. The data\n"
285 "type does not yet offer many manipulations.\n"
287 "WARNING: only for internal use. Please use make-music-by-name. \n"
290 SCM_ASSERT_TYPE(gh_string_p (type), type, SCM_ARG1, __FUNCTION__, "string");
292 SCM s = make_music (ly_scm2string (type))->self_scm ();
293 unsmob_music (s)->immutable_property_alist_ = props;
294 scm_gc_unprotect_object (s);
298 // to do property args
299 LY_DEFINE(ly_get_mutable_properties,
300 "ly:get-mutable-properties", 1, 0, 0, (SCM mus),
301 "Return an alist signifying the mutable properties of @var{mus}.\n"
302 "The immutable properties are not available; they should be initialized\n"
303 "by the functions make-music-by-name function.\n"
306 Music *m = unsmob_music (mus);
307 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "music");
309 return m->get_property_alist (true);
312 LY_DEFINE(ly_music_list_p,"music-list?", 1, 0, 0,
313 (SCM l),"Type predicate: return true if @var{l} is a list of music objects.")
315 if (scm_list_p (l) != SCM_BOOL_T)
318 while (gh_pair_p (l))
320 if (!unsmob_music (gh_car (l)))
333 make_music_by_name (SCM sym)
335 if (!make_music_proc)
336 make_music_proc = scm_primitive_eval (ly_symbol2scm ("make-music-by-name"));
338 SCM rv = scm_call_1 (make_music_proc, sym);
343 scm_gc_protect_object (rv);
344 return unsmob_music (rv);