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)));
38 immutable_property_alist_ = SCM_EOL;
39 mutable_property_alist_ = SCM_EOL;
43 Music::Music (Music const &m)
45 immutable_property_alist_ = m.immutable_property_alist_;
46 mutable_property_alist_ = SCM_EOL;
50 First we smobify_self, then we copy over the stuff. If we don't,
51 stack vars that hold the copy might be optimized away, meaning
52 that they won't be protected from GC.
55 mutable_property_alist_ = ly_deep_mus_copy (m.mutable_property_alist_);
56 set_spot (*m.origin ());
63 immutable_property_alist_ = l;
64 mutable_property_alist_ = SCM_EOL;
70 Music::mark_smob (SCM m)
72 Music * mus = (Music *)SCM_CELL_WORD_1 (m);
73 scm_gc_mark (mus->immutable_property_alist_);
74 scm_gc_mark (mus->mutable_property_alist_);
79 Music::compress (Moment)
86 Music::length_mom () const
88 SCM l = get_mus_property ("length");
89 if (unsmob_moment (l))
90 return *unsmob_moment (l);
91 else if (gh_procedure_p (l))
93 SCM res = gh_call1 (l, self_scm ());
94 return *unsmob_moment (res);
101 Music::start_mom () const
103 SCM l = get_mus_property ("start-moment-function");
104 if (gh_procedure_p (l))
106 SCM res = gh_call1 (l, self_scm ());
107 return *unsmob_moment (res);
115 print_alist (SCM a, SCM port)
118 SCM_EOL -> catch malformed lists.
120 for (SCM s = a; s != SCM_EOL; s = ly_cdr (s))
122 scm_display (ly_caar (s), port);
123 scm_puts (" = ", port);
124 scm_write (ly_cdar (s), port);
125 scm_puts ("\n", port);
130 Music::print_smob (SCM s, SCM p, scm_print_state*)
132 scm_puts ("#<Music ", p);
133 Music* m = unsmob_music (s);
134 scm_puts (classname (m),p);
136 print_alist (m->mutable_property_alist_, p);
137 print_alist (m->immutable_property_alist_, p);
144 Music::to_relative_octave (Pitch m)
151 Music::transpose (Pitch delta)
153 Pitch *p = unsmob_pitch (get_mus_property ("pitch"));
158 np.transpose (delta);
160 if (abs (np.alteration_) > 2)
162 warning (_f ("Transposition by %s makes accidental larger than two",
166 set_mus_property ("pitch", np.smobbed_copy ());
169 IMPLEMENT_TYPE_P (Music, "music?");
171 IMPLEMENT_SMOBS (Music);
172 IMPLEMENT_DEFAULT_EQUAL_P (Music);
174 /****************************/
177 Music::internal_get_mus_property (SCM sym) const
179 SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
183 s = scm_sloppy_assq (sym, immutable_property_alist_);
184 return (s == SCM_BOOL_F) ? SCM_EOL : ly_cdr (s);
188 Music::internal_set_mus_property (SCM s, SCM v)
190 if (internal_type_checking_global_b)
191 if (!type_check_assignment (s, v, ly_symbol2scm ("music-type?")))
194 mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
202 Music::set_spot (Input ip)
204 set_mus_property ("origin", make_input (ip));
208 Music::origin () const
210 Input *ip = unsmob_input (get_mus_property ("origin"));
211 return ip ? ip : & dummy_input_global;
220 LY_DEFINE(ly_get_mus_property,
221 "ly-get-mus-property", 2, 0, 0, (SCM mus, SCM sym),
222 "Get the property @var{sym} of music expression @var{mus}.")
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 return sc->internal_get_mus_property (sym);
231 LY_DEFINE(ly_set_mus_property,
232 "ly-set-mus-property!", 3, 0, 0,
233 (SCM mus, SCM sym, SCM val),
234 "Set property @var{sym} in music expression @var{mus} to @var{val}.")
236 Music * sc = unsmob_music (mus);
237 SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music");
238 SCM_ASSERT_TYPE(gh_symbol_p (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
240 bool ok = type_check_assignment (sym, val, ly_symbol2scm ("music-type?"));
243 sc->internal_set_mus_property (sym, val);
246 return SCM_UNSPECIFIED;
250 // to do property args
251 LY_DEFINE(ly_make_music,
252 "ly-make-music", 1, 0, 0, (SCM type),
254 Make a music object/expression of type @var{name}. Warning: this
255 interface will likely change in the near future.
259 Music is the data type that music expressions are stored in. The data
260 type does not yet offer many manipulations.
263 SCM_ASSERT_TYPE(gh_string_p (type), type, SCM_ARG1, __FUNCTION__, "string");
265 SCM s = make_music (ly_scm2string (type))->self_scm ();
266 scm_gc_unprotect_object (s);
271 LY_DEFINE(ly_music_name, "ly-music-name", 1, 0, 0,
273 "Return the name of @var{music}.")
275 Music * m = unsmob_music (mus);
276 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__ ,"music");
278 const char * nm = classname (m);
279 return scm_makfrom0str (nm);
282 LY_DEFINE(ly_music_list_p,"music-list?", 1, 0, 0,
283 (SCM l),"Type predicate: return true if @var{l} is a list of music objects.")
285 if (scm_list_p (l) != SCM_BOOL_T)
288 while (gh_pair_p (l))
290 if (!unsmob_music (gh_car (l)))