2 grouping.cc -- implement Rhythmic_grouping
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
10 #include "grouping.hh"
11 #include "interval.hh"
14 Rhythmic_grouping::init()
21 Rhythmic_grouping::OK()const
24 assert(bool(children.size()) != bool(interval_));
26 for (int i= 0; i < children.size(); i++) {
29 assert(children[i-1]->interval().right ==
30 children[i]->interval().left);
36 Rhythmic_grouping::length() const
38 return interval().length();
42 Rhythmic_grouping::interval()const
48 MInterval(children[0]->interval().left,
49 children.top()->interval().right);
53 Rhythmic_grouping::split(Rhythmic_grouping r)
58 r.intersect(interval());
61 for (int i= 0; i < children.size(); i++) {
62 if (!children[i]->interval_) {
63 Rhythmic_grouping here(r);
64 children[i]->split(here);
71 Rhythmic_grouping::intervals()
74 if (interval_ || children.size() == 1) {
75 MInterval i(interval());
76 MInterval r1(i), r2(i);
77 r1.right = r2.left = i.center();
78 r.push(r1); r.push(r2);
80 for (int i=0; i < children.size(); i++)
81 r.push(children[i]->interval());
87 Rhythmic_grouping::intersect(MInterval t)
90 interval_->intersect(t);
94 for (int i=0; i < children.size(); i++) {
95 MInterval inter = intersection(t, children[i]->interval());
96 if (inter.empty_b() || inter.length() <= Rational( 0 )) {
100 children[i]->intersect(t);
103 for (int i=0; i < children.size(); ) {
113 Put our children in branches of #this#.
114 The min and max time intervals coincide with elements of #splitpoints#
116 I really should be documenting what is happening here, but I find
117 that difficult, since I don't really understand what's going on here.
121 Rhythmic_grouping::split(Array<MInterval> splitpoints)
123 //check on splitpoints..
124 int j = 0, i = 0, starti = 0, startj = 0;
126 Array<Rhythmic_grouping*> ch;
128 if ( i >= children.size() || j >= splitpoints.size())
132 children[starti]->interval().left== splitpoints[startj].left);
133 if (children[i]->interval().right < splitpoints[j].right) {
135 } else if (children[i]->interval().right > splitpoints[j].right ) {
140 ch.push(children[i]);
142 Rhythmic_grouping *newchild=new Rhythmic_grouping(
143 children.slice(starti, i+1));
160 Rhythmic_grouping::Rhythmic_grouping(MInterval t, int n)
164 interval_ = new MInterval(t);
167 Moment dt = t.length()/Rational(n);
168 MInterval basic = MInterval(t.left, t.left+dt);
169 for (int i= 0; i < n; i++)
170 children.push(new Rhythmic_grouping( dt*Rational(i) + basic ));
174 Rhythmic_grouping::Rhythmic_grouping(Array<Rhythmic_grouping*> r)
180 Rhythmic_grouping::~Rhythmic_grouping()
186 Rhythmic_grouping::copy(Rhythmic_grouping const&s)
188 interval_ = (s.interval_)? new MInterval(*s.interval_) : 0;
189 for (int i=0; i < s.children.size(); i++)
190 children.push(new Rhythmic_grouping(*s.children[i]));
194 Rhythmic_grouping::operator=(Rhythmic_grouping const &s)
200 Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s)
207 Rhythmic_grouping::junk()
210 for (int i=0; i < children.size(); i++)
216 Rhythmic_grouping::print()const
221 mtor<<" Interval "<< interval_->str();
222 for (int i=0; i < children.size(); i++) {
223 children[i]->print();
230 Rhythmic_grouping::child_fit_b(Moment start)
233 return ( children.top()->interval().right== start);
239 Rhythmic_grouping::add_child(Moment start, Moment len)
241 Moment stop = start+len;
243 assert(child_fit_b(start));
244 children.push(new Rhythmic_grouping(MInterval(start, stop)));
247 Rhythmic_grouping::Rhythmic_grouping()
253 min_elt(Array<int> v)
256 for (int j = 0 ; j < v.size(); j++)
262 Rhythmic_grouping::generate_beams(Array<int> flags, int &flagidx)
264 assert (!interval_) ;
266 Array< Array<int> > children_beams;
267 for (int i=0; i < children.size(); i++) {
268 Array<int> child_beams;
269 if (children[i]->interval_) {
270 int f = flags[flagidx++];
273 child_beams = children[i]->
274 generate_beams(flags, flagidx);
276 children_beams.push(child_beams);
280 for (int i=0; i < children_beams.size(); i++) {
281 bool add_left = (i >0);
282 bool add_right = (i < children_beams.size() -1);
285 m = min_elt(children_beams[i]);
287 nextm = min_elt(children_beams[i+1]);
289 if (children_beams[i].size() == 1) {
296 beams.push(lastm <? m);
297 beams.concat(children_beams[i]);
299 beams.push(m <? nextm);
304 assert(!(beams.size()%2));
309 Rhythmic_grouping::translate(Moment m)
314 for (int i=0; i < children.size(); i++)
315 children[i]->translate(m);
319 Rhythmic_grouping::extend(MInterval m)const
321 assert(m.left >= interval().left);
322 while (m.right >interval().right ) {
323 Array<Rhythmic_grouping*> a(children);
324 for (int i=0; i < a.size(); i++) {
325 a[i] =new Rhythmic_grouping(*children[i]);
326 a[i]->translate(children.top()->interval().right);
328 ((Rhythmic_grouping*)this)->children.concat(a);
330 assert(m.right <= interval().right);
335 parse_grouping(Array<int> beat_i_arr, Array<Moment> elt_length_arr)
338 assert(beat_i_arr.size() == elt_length_arr.size());
340 Array<Rhythmic_grouping*> children;
341 for (int i=0; i < beat_i_arr.size(); i++) {
343 here += elt_length_arr[i] * Moment(beat_i_arr[i]);
345 new Rhythmic_grouping(MInterval(last, here),
348 return Rhythmic_grouping(children);