release commit
[lilypond.git] / lily / event.cc
blob75948dac04d13e376988b7d4b7b23346c2f1a83d
1 /*
2 event.cc -- implement Event
4 source file of the GNU LilyPond music typesetter
6 (c) 1996--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "event.hh"
10 #include "warn.hh"
11 #include "event.hh"
13 Moment
14 Event::get_length () const
16 Duration *d = unsmob_duration (get_mus_property ("duration"));
17 if (!d)
19 Moment m ;
20 return m;
22 return d->get_length ();
25 void
26 Event::compress (Moment m)
28 Duration *d = unsmob_duration (get_mus_property ("duration"));
29 if (d)
30 set_mus_property ("duration", d ->compressed (m.main_part_).smobbed_copy ());
33 void
34 Event::transpose (Pitch delta)
37 TODO: should change music representation such that
38 _all_ pitch values are transposed automatically.
41 Pitch *p = unsmob_pitch (get_mus_property ("pitch"));
42 if (!p)
43 return ;
45 Pitch np = p->transposed (delta);
47 if (abs (np.get_alteration ()) > DOUBLE_SHARP)
49 warning (_f ("Transposition by %s makes alteration larger than two",
50 delta.to_string ()));
53 set_mus_property ("pitch", np.smobbed_copy ());
56 Pitch
57 Event::to_relative_octave (Pitch last)
59 Pitch *old_pit = unsmob_pitch (get_mus_property ("pitch"));
60 if (old_pit)
62 Pitch new_pit = *old_pit;
63 new_pit = new_pit.to_relative_octave (last);
64 set_mus_property ("pitch", new_pit.smobbed_copy ());
66 return new_pit;
68 return last;
71 Event::Event ()
72 : Music ()
76 ADD_MUSIC(Event);
77 LY_DEFINE(ly_music_duration_length, "ly:music-duration-length", 1, 0,0,
78 (SCM mus),
79 "Extract the duration field from @var{mus}, and return the length.")
81 Music* m = unsmob_music(mus);
82 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
84 Duration *d = unsmob_duration (m->get_mus_property ("duration"));
86 Moment l ;
88 if (d)
90 l = d->get_length ();
92 else
93 programming_error("Music has no duration");
94 return l.smobbed_copy();
99 LY_DEFINE(ly_music_duration_compress, "ly:music-duration-compress", 2, 0,0,
100 (SCM mus, SCM factor),
101 "Extract the duration field from @var{mus}, and compress it.")
103 Music* m = unsmob_music(mus);
104 Moment * f = unsmob_moment (factor);
105 SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
106 SCM_ASSERT_TYPE(f, factor, SCM_ARG2, __FUNCTION__, "Moment");
108 Duration *d = unsmob_duration (m->get_mus_property ("duration"));
109 if (d)
110 m->set_mus_property ("duration", d->compressed (f->main_part_).smobbed_copy());
111 return SCM_UNSPECIFIED;
117 This is hairy, since the scale in a key-change event may contain
118 octaveless notes.
121 TODO: this should use ly:pitch.
123 LY_DEFINE(ly_transpose_key_alist, "ly:transpose-key-alist",
124 2, 0,0, (SCM l, SCM pitch),
125 "Make a new key alist of @var{l} transposed by pitch @var{pitch}")
127 SCM newlist = SCM_EOL;
128 Pitch *p = unsmob_pitch (pitch);
130 for (SCM s = l; gh_pair_p (s); s = ly_cdr (s))
132 SCM key = ly_caar (s);
133 SCM alter = ly_cdar (s);
134 if (gh_pair_p (key))
136 Pitch orig (gh_scm2int (ly_car (key)),
137 gh_scm2int (ly_cdr (key)),
138 gh_scm2int (alter));
140 orig =orig.transposed (*p);
142 SCM key = gh_cons (scm_int2num (orig.get_octave ()),
143 scm_int2num (orig.get_notename ()));
145 newlist = gh_cons (gh_cons (key, scm_int2num (orig.get_alteration ())),
146 newlist);
148 else if (gh_number_p (key))
150 Pitch orig (0, gh_scm2int (key), gh_scm2int (alter));
151 orig = orig.transposed (*p);
153 key =scm_int2num (orig.get_notename ());
154 alter = scm_int2num (orig.get_alteration());
155 newlist = gh_cons (gh_cons (key, alter), newlist);
158 return scm_reverse_x (newlist, SCM_EOL);
161 void
162 Key_change_ev::transpose (Pitch p)
164 SCM pa = get_mus_property ("pitch-alist");
166 set_mus_property ("pitch-alist", ly_transpose_key_alist (pa, p.smobbed_copy()));
167 Pitch tonic = *unsmob_pitch (get_mus_property ("tonic"));
168 set_mus_property ("tonic",
169 tonic.smobbed_copy ());
172 bool
173 alist_equal_p (SCM a, SCM b)
175 for (SCM s = a;
176 gh_pair_p (s); s = ly_cdr (s))
178 SCM key = ly_caar (s);
179 SCM val = ly_cdar (s);
180 SCM l = scm_assoc (key, b);
182 if (l == SCM_BOOL_F
183 || !gh_equal_p ( ly_cdr (l), val))
185 return false;
187 return true;
189 ADD_MUSIC (Key_change_ev);