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