]> git.donarmstrong.com Git - lilypond.git/blob - lily/event.cc
*** empty log message ***
[lilypond.git] / lily / event.cc
1 /*
2   event.cc -- implement Event
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "event.hh"
10 #include "warn.hh"
11 #include "event.hh"
12   
13 Moment
14 Event::get_length () const
15 {
16   Duration *d = unsmob_duration (get_mus_property ("duration"));
17   if (!d)
18     {
19       Moment m ;
20       return m;
21     }
22   return d->get_length ();
23 }
24
25 void
26 Event::compress (Moment m)
27 {
28   Duration *d =  unsmob_duration (get_mus_property ("duration"));
29   if (d)
30     set_mus_property ("duration", d ->compressed (m.main_part_).smobbed_copy ());
31 }
32
33 void
34 Event::transpose (Pitch delta)
35 {
36   Pitch *p = unsmob_pitch (get_mus_property ("pitch"));
37   if (!p)
38     return ;
39
40   Pitch np = *p;
41   np.transpose (delta);
42   
43   if (abs (np.alteration_) > 2)
44     {
45         warning (_f ("Transposition by %s makes accidental larger than two",
46           delta.string ()));
47     }
48
49   set_mus_property ("pitch", np.smobbed_copy ());
50 }
51
52 Pitch
53  Event::to_relative_octave (Pitch last)
54 {
55   Pitch *old_pit = unsmob_pitch (get_mus_property ("pitch"));
56   if (old_pit)
57     {
58       Pitch new_pit = *old_pit;
59       new_pit.to_relative_octave (last);
60       set_mus_property ("pitch", new_pit.smobbed_copy ());
61   
62       return new_pit;
63     }
64   return last;
65 }
66   
67 Event::Event ()
68   : Music ()
69 {
70 }
71
72 ADD_MUSIC(Event);
73 LY_DEFINE(music_duration_length, "music-duration-length", 1, 0,0,
74           (SCM mus),
75           "Extract the duration field from @var{mus}, and return the length.")
76 {
77   Music* m =   unsmob_music(mus);
78   SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
79   
80   Duration *d = unsmob_duration (m->get_mus_property ("duration"));
81
82   Moment l ;
83   
84   if (d)
85     {
86       l = d->get_length ();  
87     }
88   else
89     programming_error("Music has no duration");
90   return l.smobbed_copy();
91   
92 }
93
94
95 LY_DEFINE(music_duration_compress, "ly:music-duration-compress", 2, 0,0,
96           (SCM mus, SCM factor),
97           "Extract the duration field from @var{mus}, and compress it.")
98 {
99   Music* m =   unsmob_music(mus);
100   Moment * f = unsmob_moment (factor);
101   SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
102   SCM_ASSERT_TYPE(f, factor, SCM_ARG2, __FUNCTION__, "Moment");
103   
104   Duration *d = unsmob_duration (m->get_mus_property ("duration"));
105   if (d)
106     m->set_mus_property ("duration", d->compressed (f->main_part_).smobbed_copy());
107   return SCM_UNSPECIFIED;
108 }
109
110
111
112 /*
113   This is hairy, since the scale in a key-change event may contain
114   octaveless notes.
115  */
116 LY_DEFINE(transpose_key_alist, "ly:transpose-key-alist",
117           2, 0,0, (SCM l, SCM pitch),
118           "Make a new key alist of @var{l} transposed by pitch @var{pitch}")
119 {
120   SCM newlist = SCM_EOL;
121   Pitch *p = unsmob_pitch (pitch);
122   
123   for (SCM s = l; gh_pair_p (s); s = ly_cdr (s))
124     {
125       SCM key = ly_caar (s);
126       SCM alter = ly_cdar (s);
127       if (gh_pair_p (key))
128         {
129           Pitch orig (gh_scm2int (ly_car (key)),
130                               gh_scm2int (ly_cdr (key)),
131                               gh_scm2int (alter));
132
133           orig.transpose (*p);
134
135           SCM key = gh_cons (scm_int2num (orig.get_octave ()),
136                              scm_int2num (orig.notename_));
137
138           newlist = gh_cons (gh_cons (key, scm_int2num (orig.alteration_)),
139                              newlist);
140         }
141       else if (gh_number_p (key))
142         {
143           Pitch orig (0, gh_scm2int (key), gh_scm2int (alter));
144           orig.transpose (*p);
145
146           key =scm_int2num (orig.notename_);
147           alter = scm_int2num (orig.alteration_);
148           newlist = gh_cons (gh_cons (key, alter), newlist);
149         }
150     }
151   return scm_reverse_x (newlist, SCM_EOL);
152 }
153
154 void
155 Key_change_req::transpose (Pitch p)
156 {
157   SCM pa = get_mus_property ("pitch-alist");
158
159   set_mus_property ("pitch-alist", transpose_key_alist (pa, p.smobbed_copy()));
160 }
161
162
163 bool
164 alist_equal_p (SCM a, SCM b)
165 {
166   for (SCM s = a;
167        gh_pair_p (s); s = ly_cdr (s))
168     {
169       SCM key = ly_caar (s);
170       SCM val = ly_cdar (s);
171       SCM l = scm_assoc (key, b);
172
173       if (l == SCM_BOOL_F
174           || !gh_equal_p ( ly_cdr (l), val))
175
176         return false;
177     }
178   return true;
179 }
180
181 bool
182 Key_change_req::do_equal_b (Event const * m )const
183 {
184   Key_change_req const * kc =dynamic_cast<Key_change_req const*> (m);
185
186   if(!kc)
187     return false;
188   return alist_equal_p (get_mus_property ("pitch-alist"),
189                         kc->get_mus_property ("pitch-alist"));
190 }
191
192 ADD_MUSIC (Key_change_req);