]> git.donarmstrong.com Git - lilypond.git/blob - lily/music-sequence.cc
unsmob_pitch -> Pitch::unsmob and related
[lilypond.git] / lily / music-sequence.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1998--2014 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 "music-sequence.hh"
21
22 #include "warn.hh"
23 #include "program-option.hh"
24 #include "duration.hh"
25 #include "moment.hh"
26 #include "music.hh"
27 #include "input.hh"
28
29 void
30 transpose_music_list (SCM lst, Pitch rq)
31 {
32   for (SCM s = lst; scm_is_pair (s); s = scm_cdr (s))
33     unsmob_music (scm_car (s))->transpose (rq);
34 }
35
36 Moment
37 Music_sequence::cumulative_length (SCM l)
38 {
39   Moment cumulative;
40   Moment last_len;
41
42   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
43     {
44       Moment l = unsmob_music (scm_car (s))->get_length ();
45       if (last_len.grace_part_ && l.main_part_)
46         last_len.grace_part_ = Rational (0);
47       cumulative += last_len;
48       last_len = l;
49     }
50
51   last_len.grace_part_ = Rational (0);
52   cumulative += last_len;
53
54   return cumulative;
55 }
56
57 Moment
58 Music_sequence::maximum_length (SCM l)
59 {
60   Moment dur = 0;
61   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
62     {
63       Music *m = unsmob_music (scm_car (s));
64       if (!m)
65         programming_error ("Music sequence should have music elements");
66       else
67         {
68           Moment l = m->get_length ();
69           dur = max (dur, l);
70         }
71     }
72
73   return dur;
74 }
75
76 MAKE_SCHEME_CALLBACK (Music_sequence, maximum_length_callback, 1);
77 SCM
78 Music_sequence::maximum_length_callback (SCM m)
79 {
80   Music *me = unsmob_music (m);
81   return maximum_length (me->get_property ("elements")).smobbed_copy ();
82 }
83
84 MAKE_SCHEME_CALLBACK (Music_sequence, event_chord_length_callback, 1);
85 SCM
86 Music_sequence::event_chord_length_callback (SCM m)
87 {
88   Music *me = unsmob_music (m);
89   Duration *d = Duration::unsmob (me->get_property ("duration"));
90   // Preset duration is used in chord repetitions.
91   if (d)
92     {
93       Moment mom = d->get_length ();
94       return mom.smobbed_copy ();
95     }
96   return maximum_length (me->get_property ("elements")).smobbed_copy ();
97 }
98
99 MAKE_SCHEME_CALLBACK (Music_sequence, cumulative_length_callback, 1);
100 SCM
101 Music_sequence::cumulative_length_callback (SCM m)
102 {
103   Music *me = unsmob_music (m);
104   return cumulative_length (me->get_property ("elements")).smobbed_copy ();
105 }
106
107 MAKE_SCHEME_CALLBACK (Music_sequence, minimum_start_callback, 1);
108 SCM
109 Music_sequence::minimum_start_callback (SCM m)
110 {
111   Music *me = unsmob_music (m);
112   return minimum_start (me->get_property ("elements")).smobbed_copy ();
113 }
114
115 MAKE_SCHEME_CALLBACK (Music_sequence, first_start_callback, 1);
116 SCM
117 Music_sequence::first_start_callback (SCM m)
118 {
119   Music *me = unsmob_music (m);
120   return first_start (me->get_property ("elements")).smobbed_copy ();
121 }
122
123 Pitch
124 music_list_to_relative (SCM l, Pitch p, bool ret_first)
125 {
126   Pitch first = p;
127   int count = 0;
128
129   Pitch last = p;
130   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
131     {
132       if (Music *m = unsmob_music (scm_car (s)))
133         {
134           last = m->to_relative_octave (last);
135           if (!count++)
136             first = last;
137         }
138     }
139
140   return (ret_first) ? first : last;
141 }
142
143 void
144 compress_music_list (SCM l, Moment m)
145 {
146   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
147     unsmob_music (scm_car (s))->compress (m);
148 }
149
150 Moment
151 Music_sequence::minimum_start (SCM l)
152 {
153   Moment m;
154
155   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
156     m = min (m, unsmob_music (scm_car (s))->start_mom ());
157   return m;
158 }
159
160 Moment
161 Music_sequence::first_start (SCM l)
162 {
163
164   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
165     {
166       Music *mus = unsmob_music (scm_car (s));
167       Moment start = mus->start_mom ();
168       if (mus->get_length ().to_bool () || start.to_bool ())
169         return start;
170     }
171   return Moment ();
172 }
173
174 MAKE_SCHEME_CALLBACK (Music_sequence, simultaneous_relative_callback, 2);
175 SCM
176 Music_sequence::simultaneous_relative_callback (SCM music, SCM pitch)
177 {
178   Music *me = unsmob_music (music);
179   Pitch p = *Pitch::unsmob (pitch);
180   return music_list_to_relative (me->get_property ("elements"),
181                                  p, false).smobbed_copy ();
182 }
183
184 MAKE_SCHEME_CALLBACK (Music_sequence, event_chord_relative_callback, 2);
185 SCM
186 Music_sequence::event_chord_relative_callback (SCM music, SCM pitch)
187 {
188   Music *me = unsmob_music (music);
189   Pitch p = *Pitch::unsmob (pitch);
190   return music_list_to_relative (me->get_property ("elements"),
191                                  p, true).smobbed_copy ();
192 }