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