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