]> git.donarmstrong.com Git - lilypond.git/blob - lily/repeated-music.cc
c047349fef64d91c11d2fac1c894cede8c70fdec
[lilypond.git] / lily / repeated-music.cc
1 /*   
2   repeated-music.cc --  implement Repeated_music
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "repeated-music.hh"
11 #include "music-list.hh"
12 #include "pitch.hh"
13 #include "warn.hh"
14 #include "music-sequence.hh"
15 #include "scm-option.hh"
16
17 Music *
18 Repeated_music::body ()const
19 {
20   return unsmob_music (get_mus_property ("element"));
21 }
22
23 SCM
24 Repeated_music::alternatives ()const
25 {
26   return get_mus_property ("elements");
27 }
28
29
30
31
32 Pitch
33 Repeated_music::to_relative_octave (Pitch p)
34 {
35   if (lily_1_8_relative)
36     {
37       if (body ())
38         p = body ()->to_relative_octave (p);
39
40       Pitch last = p ; 
41       if (alternatives ())
42         {
43           lily_1_8_compatibility_used = true; 
44
45           for (SCM s = alternatives (); gh_pair_p (s);  s = ly_cdr (s))
46             unsmob_music (ly_car (s))->to_relative_octave (p);
47         }     
48
49       return last;
50     }
51   else
52     {
53       return Music::to_relative_octave (p);
54     }
55 }
56
57
58 Moment
59 Repeated_music::alternatives_get_length (bool fold) const
60 {
61   if (!alternatives ())
62     return 0;
63   
64   if (fold)
65     return Music_sequence::maximum_length (alternatives ());
66
67   Moment m =0;
68   int done =0;
69
70   SCM p = alternatives ();
71   while (gh_pair_p (p) && done < repeat_count ())
72     {
73       m = m + unsmob_music (ly_car (p))->get_length ();
74       done ++;
75       if (repeat_count () - done < scm_ilength (alternatives ()))
76         p = ly_cdr (p);
77     }
78   return m;
79 }
80
81 /*
82   Sum all duration of all available alternatives. This is for the case
83   of volta repeats, where the alternatives are iterated just as they
84   were entered.  */
85 Moment
86 Repeated_music::alternatives_volta_get_length () const
87 {
88   if (!alternatives ())
89     return 0;
90
91   Moment m;
92   SCM p = alternatives ();
93   while (gh_pair_p (p))
94     {
95       m = m + unsmob_music (ly_car (p))->get_length ();
96       p = ly_cdr (p);
97     }
98   return m;
99 }
100
101
102 /*
103   Length of the body in THIS. Disregards REPEAT-COUNT. 
104  */
105 Moment
106 Repeated_music::body_get_length () const
107 {
108   Moment m = 0;
109   if (body ())
110     {
111       m = body ()->get_length ();
112     }
113   return m;
114 }
115
116 int
117 Repeated_music::repeat_count () const
118 {
119   return gh_scm2int (get_mus_property ("repeat-count"));
120 }
121
122
123 MAKE_SCHEME_CALLBACK (Repeated_music,unfolded_music_length, 1);
124 MAKE_SCHEME_CALLBACK (Repeated_music,folded_music_length, 1);
125 MAKE_SCHEME_CALLBACK (Repeated_music,volta_music_length, 1);
126
127 SCM
128 Repeated_music::unfolded_music_length (SCM m)
129 {
130   Repeated_music* r = dynamic_cast<Repeated_music*> (unsmob_music (m));
131   
132   Moment l = Moment (r->repeat_count ()) * r->body_get_length () + r->alternatives_get_length (false);
133   return l.smobbed_copy ();
134 }
135
136 SCM
137 Repeated_music::folded_music_length (SCM m)
138 {
139   Repeated_music* r = dynamic_cast<Repeated_music*> (unsmob_music (m));
140  
141   Moment l =  r->body_get_length () + r->alternatives_get_length (true);
142   return l.smobbed_copy ();
143 }
144
145 SCM
146 Repeated_music::volta_music_length (SCM m)
147 {
148   Repeated_music* r = dynamic_cast<Repeated_music*> (unsmob_music (m));
149   Moment l =  r->body_get_length () + r->alternatives_volta_get_length ();
150   return l.smobbed_copy ();
151 }
152
153 ADD_MUSIC (Repeated_music);
154
155 Repeated_music::Repeated_music ()
156   : Music ()
157 {
158 }
159
160
161 MAKE_SCHEME_CALLBACK (Repeated_music,minimum_start, 1);
162 MAKE_SCHEME_CALLBACK (Repeated_music,first_start, 1);
163
164 SCM
165 Repeated_music::minimum_start (SCM m)
166 {
167   Music * me = unsmob_music (m);
168   Music * body = unsmob_music (me->get_mus_property ("element"));
169
170   if (body)
171     return body->start_mom ().smobbed_copy();
172   else
173     {
174       return Music_sequence::minimum_start (me->get_mus_property ("elements")).smobbed_copy();
175     }
176 }
177
178 SCM
179 Repeated_music::first_start (SCM m)
180 {
181   Music * me = unsmob_music (m);
182   Music * body = unsmob_music (me->get_mus_property ("element"));
183
184   Moment rv =  (body) ? body->start_mom () :
185     Music_sequence::first_start (me->get_mus_property ("elements"));
186
187   return rv.smobbed_copy ();
188 }