]> git.donarmstrong.com Git - lilypond.git/blob - lily/repeated-music.cc
Web-ja: update introduction
[lilypond.git] / lily / repeated-music.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "repeated-music.hh"
21 #include "music-sequence.hh"
22 #include "pitch.hh"
23 #include "warn.hh"
24 #include "program-option.hh"
25
26 Music *
27 Repeated_music::body (Music *me)
28 {
29   return unsmob<Music> (me->get_property ("element"));
30 }
31
32 SCM
33 Repeated_music::alternatives (Music *me)
34 {
35   return me->get_property ("elements");
36 }
37
38 Moment
39 Repeated_music::alternatives_get_length (Music *me, bool fold)
40 {
41   SCM alternative_list = alternatives (me);
42   int len = scm_ilength (alternative_list);
43   if (len <= 0)
44     return 0;
45
46   if (fold)
47     return Music_sequence::maximum_length (alternative_list);
48
49   Moment m = 0;
50   int done = 0;
51   int count = robust_scm2int (me->get_property ("repeat-count"), 0);
52
53   SCM p = alternative_list;
54   while (scm_is_pair (p) && done < count)
55     {
56       m = m + unsmob<Music> (scm_car (p))->get_length ();
57       done++;
58       if (count - done < len)
59         p = scm_cdr (p);
60     }
61   return m;
62 }
63
64 /*
65   Sum all duration of all available alternatives. This is for the case
66   of volta repeats, where the alternatives are iterated just as they
67   were entered.  */
68 Moment
69 Repeated_music::alternatives_volta_get_length (Music *me)
70 {
71   return Music_sequence::cumulative_length (alternatives (me));
72 }
73
74 /*
75   Length of the body in THIS. Disregards REPEAT-COUNT.
76 */
77 Moment
78 Repeated_music::body_get_length (Music *me)
79 {
80   Moment m = 0;
81   if (Music *body = unsmob<Music> (me->get_property ("element")))
82     m = body->get_length ();
83   return m;
84 }
85
86 MAKE_SCHEME_CALLBACK (Repeated_music, unfolded_music_length, 1);
87
88 SCM
89 Repeated_music::unfolded_music_length (SCM m)
90 {
91   Music *me = unsmob<Music> (m);
92
93   Moment l = Moment (repeat_count (me)) * body_get_length (me) + alternatives_get_length (me, false);
94   return l.smobbed_copy ();
95 }
96
97 MAKE_SCHEME_CALLBACK (Repeated_music, folded_music_length, 1);
98 SCM
99 Repeated_music::folded_music_length (SCM m)
100 {
101   Music *me = unsmob<Music> (m);
102
103   Moment l = body_get_length (me) + alternatives_get_length (me, true);
104   return l.smobbed_copy ();
105 }
106
107 int
108 Repeated_music::repeat_count (Music *me)
109 {
110   return scm_to_int (me->get_property ("repeat-count"));
111 }
112
113 MAKE_SCHEME_CALLBACK (Repeated_music, volta_music_length, 1);
114 SCM
115 Repeated_music::volta_music_length (SCM m)
116 {
117   Music *me = unsmob<Music> (m);
118   Moment l = body_get_length (me) + alternatives_volta_get_length (me);
119   return l.smobbed_copy ();
120 }
121
122 MAKE_SCHEME_CALLBACK (Repeated_music, minimum_start, 1);
123 SCM
124 Repeated_music::minimum_start (SCM m)
125 {
126   Music *me = unsmob<Music> (m);
127   Music *body = unsmob<Music> (me->get_property ("element"));
128
129   if (body)
130     return body->start_mom ().smobbed_copy ();
131   else
132     return Music_sequence::minimum_start (me->get_property ("elements")).smobbed_copy ();
133 }
134
135 MAKE_SCHEME_CALLBACK (Repeated_music, first_start, 1);
136 SCM
137 Repeated_music::first_start (SCM m)
138 {
139   Music *me = unsmob<Music> (m);
140   Music *body = unsmob<Music> (me->get_property ("element"));
141
142   Moment rv = (body) ? body->start_mom ()
143               : Music_sequence::first_start (me->get_property ("elements"));
144
145   return rv.smobbed_copy ();
146 }