]> git.donarmstrong.com Git - lilypond.git/blob - lily/music-sequence.cc
* lily/music.cc (var): add ly:music-transpose function.
[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--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include "music-list.hh"
10 #include "warn.hh"
11 #include "pitch.hh"
12 #include "input.hh"
13
14 SCM
15 Music_sequence::music_list ()const
16 {
17   return get_mus_property ("elements");
18 }
19
20 /*
21   Ugh this sucks. Linear. do not use.
22  */
23 void
24 Music_sequence::append_music (Music *m)
25 {
26   set_mus_property ("elements",
27                     gh_append2 (music_list (), gh_cons (m->self_scm (), SCM_EOL)));
28   scm_gc_unprotect_object (m->self_scm ());
29 }
30
31 Music_sequence::Music_sequence ( )
32   : Music ()
33 {
34 }
35
36 void
37 Music_sequence::transpose (Pitch rq)
38 {
39   transpose_list (music_list (), rq);
40 }
41
42 void
43 Music_sequence::transpose_list (SCM l,  Pitch rq)
44 {
45   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
46     unsmob_music (ly_car (s))->transpose (rq);    
47 }
48
49 Moment
50 Music_sequence::cumulative_length (SCM l) 
51 {
52   Moment cumulative;
53   Moment last_len; 
54
55   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
56     {
57       Moment l = unsmob_music (ly_car (s))->get_length ();
58       if (last_len.grace_part_ && l.main_part_)
59         {
60           last_len.grace_part_ = Rational (0);
61         }
62       cumulative += last_len;
63       last_len = l;
64     }
65
66   last_len.grace_part_ = Rational (0);
67   cumulative += last_len;
68
69   return  cumulative;
70 }
71
72 Pitch
73 Music_sequence::to_relative_octave (Pitch p)
74 {
75   return do_relative_octave (p, false);
76 }
77
78
79 Moment
80 Music_sequence::maximum_length (SCM l)
81 {
82   Moment dur = 0;
83   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
84     {
85       Music * m = unsmob_music (ly_car (s));
86       Moment l = m->get_length ();
87       dur = dur >? l;
88     }
89
90   return dur;
91 }
92
93
94 Pitch
95 Music_sequence::do_relative_octave (Pitch p, bool ret_first)
96 {
97   Pitch first;
98   int count=0;
99
100   Pitch last = p;
101   for (SCM s = music_list (); gh_pair_p (s);  s = ly_cdr (s))
102     {
103       Music *m = unsmob_music (ly_car (s));
104       if (!m)
105         {
106           programming_error ("Music_sequence should only contain music!");
107         }
108       else
109         {
110           last = m->to_relative_octave (last);
111           if (!count ++)
112             first = last;
113         }
114     }
115
116   if (ret_first && first != last)
117     {
118       String str = _("Changing relative definition causes pitch change.");
119       str += "\nWas: " +  first.to_string ()
120         + "Will be: " + last.to_string () + "\n";
121       
122       origin()->warning (str);
123     }
124   return last;
125 }
126
127 void
128 Music_sequence::compress (Moment m)
129 {
130   compress_list (music_list (), m);
131 }
132
133 void
134 Music_sequence::compress_list (SCM l, Moment m)
135 {
136   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
137     unsmob_music (ly_car (s))->compress (m);
138 }
139
140 ADD_MUSIC (Music_sequence);
141
142 Moment
143 Music_sequence::minimum_start (SCM l)
144 {
145   Moment m;
146   
147   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
148     {
149       m = m <? unsmob_music (ly_car (s))->start_mom ();
150     }
151   return m;
152 }
153
154 Moment
155 Music_sequence::first_start (SCM l) 
156 {
157   Moment m;
158   
159   for (SCM s = l; gh_pair_p (s);  s = ly_cdr (s))
160     {
161       Music * mus = unsmob_music (ly_car (s));
162       Moment l = mus->get_length ();
163       Moment s = mus->start_mom ();
164       if (l.to_bool () || s.to_bool ())
165         return s;
166     }
167   return m;
168 }
169