2 music.cc -- implement Music
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "input-smob.hh"
11 #include "music-list.hh"
14 #include "ly-smobs.icc"
17 ly_deep_mus_copy (SCM m)
21 SCM ss = unsmob_music (m)->clone ()->self_scm ();
22 scm_gc_unprotect_object (ss);
25 else if (gh_pair_p (m))
27 return gh_cons (ly_deep_mus_copy (gh_car (m)), ly_deep_mus_copy (gh_cdr (m)));
36 immutable_property_alist_ = SCM_EOL;
37 mutable_property_alist_ = SCM_EOL;
41 Music::Music (Music const &m)
43 immutable_property_alist_ = m.immutable_property_alist_;
44 mutable_property_alist_ = SCM_EOL;
47 First we smobify_self, then we copy over the stuff. If we don't,
48 stack vars that hold the copy might be optimized away, meaning
49 that they won't be protected from GC.
52 mutable_property_alist_ = ly_deep_mus_copy (m.mutable_property_alist_);
53 set_spot (*m.origin ());
59 immutable_property_alist_ = l;
60 mutable_property_alist_ = SCM_EOL;
66 Music::mark_smob (SCM m)
68 Music * mus = (Music *)SCM_CELL_WORD_1 (m);
69 scm_gc_mark (mus->immutable_property_alist_);
70 scm_gc_mark (mus->mutable_property_alist_);
75 Music::compress (Moment)
82 Music::length_mom () const
84 SCM l = get_mus_property ("length");
85 if (unsmob_moment (l))
86 return *unsmob_moment (l);
87 else if (gh_procedure_p (l))
89 SCM res = gh_call1 (l, self_scm ());
90 return *unsmob_moment (res);
97 print_alist (SCM a, SCM port)
99 for (SCM s = a; gh_pair_p (s); s = gh_cdr (s))
101 scm_display (gh_caar (s), port);
102 scm_puts (" = ", port);
103 scm_write (gh_cdar (s), port);
104 scm_puts ("\n", port);
109 Music::print_smob (SCM s, SCM p, scm_print_state*)
111 scm_puts ("#<Music ", p);
112 Music* m = unsmob_music (s);
113 scm_puts (classname (m),p);
115 print_alist (m->mutable_property_alist_, p);
116 print_alist (m->immutable_property_alist_, p);
123 Music::to_relative_octave (Pitch m)
130 Music::transpose (Pitch)
134 IMPLEMENT_TYPE_P (Music, "music?");
135 IMPLEMENT_UNSMOB (Music,music);
136 IMPLEMENT_SMOBS (Music);
137 IMPLEMENT_DEFAULT_EQUAL_P (Music);
139 /****************************/
142 Music::get_mus_property (const char *nm) const
144 SCM sym = ly_symbol2scm (nm);
145 return get_mus_property (sym);
149 Music::get_mus_property (SCM sym) const
151 SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
155 s = scm_sloppy_assq (sym, immutable_property_alist_);
156 return (s == SCM_BOOL_F) ? SCM_EOL : gh_cdr (s);
160 Remove the value associated with KEY, and return it. The result is
161 that a next call will yield SCM_EOL (and not the underlying
165 Music::remove_mus_property (const char* key)
167 SCM val = get_mus_property (key);
169 set_mus_property (key, SCM_EOL);
174 Music::set_mus_property (const char* k, SCM v)
176 SCM s = ly_symbol2scm (k);
177 set_mus_property (s, v);
180 void paranoia_check (Music*);
183 Music::set_immutable_mus_property (const char*k, SCM v)
185 SCM s = ly_symbol2scm (k);
186 set_immutable_mus_property (s, v);
190 Music::set_immutable_mus_property (SCM s, SCM v)
192 immutable_property_alist_ = gh_cons (gh_cons (s,v), mutable_property_alist_);
193 mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, s);
196 Music::set_mus_property (SCM s, SCM v)
198 mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
204 Music::set_spot (Input ip)
206 set_mus_property ("origin", make_input (ip));
212 Music::origin () const
214 Input *ip = unsmob_input (get_mus_property ("origin"));
215 return ip ? ip : & dummy_input_global;
228 ly_get_mus_property (SCM mus, SCM sym)
230 Music * sc = unsmob_music (mus);
234 return sc->get_mus_property (sym);
238 warning (_ ("ly_get_mus_property (): Not a Music"));
239 scm_write (mus, scm_current_error_port ());
246 ly_set_mus_property (SCM mus, SCM sym, SCM val)
248 Music * sc = unsmob_music (mus);
250 if (!gh_symbol_p (sym))
252 warning (_ ("ly_set_mus_property (): Not a symbol"));
253 scm_write (mus, scm_current_error_port ());
255 return SCM_UNSPECIFIED;
260 sc->set_mus_property (sym, val);
264 warning (_ ("ly_set_mus_property (): not of type Music"));
265 scm_write (mus, scm_current_error_port ());
268 return SCM_UNSPECIFIED;
272 // to do property args
274 ly_make_music (SCM type)
276 if (!gh_string_p (type))
278 warning (_ ("ly_make_music (): Not a string"));
279 scm_write (type, scm_current_error_port ());
281 return SCM_UNSPECIFIED;
285 SCM s = get_music (ly_scm2string (type))->self_scm ();
286 scm_gc_unprotect_object (s);
292 ly_music_name (SCM mus)
294 Music * m = unsmob_music (mus);
298 warning (_ ("ly_music_name (): Not a music expression"));
299 scm_write (mus, scm_current_error_port ());
303 return ly_str02scm (nm);
309 scm_c_define_gsubr ("ly-get-mus-property", 2, 0, 0, (Scheme_function_unknown)ly_get_mus_property);
310 scm_c_define_gsubr ("ly-set-mus-property", 3, 0, 0, (Scheme_function_unknown)ly_set_mus_property);
311 scm_c_define_gsubr ("ly-make-music", 1, 0, 0, (Scheme_function_unknown)ly_make_music);
312 scm_c_define_gsubr ("ly-music-name", 1, 0, 0, (Scheme_function_unknown)ly_music_name);
314 ADD_SCM_INIT_FUNC (musicscm,init_functions);