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++)
30 assert (children[i-1]->interval().right ==
31 children[i]->interval().left);
37 Rhythmic_grouping::length() const
39 return interval().length ();
43 Rhythmic_grouping::interval() const
49 MInterval (children[0]->interval().left,
50 children.top()->interval ().right);
54 Rhythmic_grouping::split (Rhythmic_grouping r)
59 r.intersect (interval());
60 split (r.intervals());
62 for (int i= 0; i < children.size(); i++)
64 if (!children[i]->interval_)
66 Rhythmic_grouping here (r);
67 children[i]->split (here);
74 Rhythmic_grouping::intervals()
77 if (interval_ || children.size() == 1)
79 MInterval i (interval());
80 MInterval r1(i), r2(i);
81 r1.right = r2.left = i.center();
82 r.push (r1); r.push (r2);
86 for (int i=0; i < children.size(); i++)
87 r.push (children[i]->interval());
93 Rhythmic_grouping::intersect (MInterval t)
97 interval_->intersect (t);
101 for (int i=0; i < children.size(); i++)
103 MInterval inter = intersection (t, children[i]->interval());
104 if (inter.empty_b() || inter.length () <= Rational (0))
111 children[i]->intersect (t);
114 for (int i=0; i < children.size();)
125 Put our children in branches of #this#.
126 The min and max time intervals coincide with elements of #splitpoints#
128 I really should be documenting what is happening here, but I find
129 that difficult, since I don't really understand what's going on here.
133 Rhythmic_grouping::split (Array<MInterval> splitpoints)
135 //check on splitpoints..
136 int j = 0, i = 0, starti = 0, startj = 0;
138 Array<Rhythmic_grouping*> ch;
141 if (i >= children.size() || j >= splitpoints.size ())
145 children[starti]->interval().left== splitpoints[startj].left);
146 if (children[i]->interval().right < splitpoints[j].right)
150 else if (children[i]->interval().right > splitpoints[j].right)
159 ch.push (children[i]);
163 Rhythmic_grouping *newchild=new Rhythmic_grouping (
164 children.slice (starti, i+1));
181 Rhythmic_grouping::Rhythmic_grouping (MInterval t, int n)
186 interval_ = new MInterval (t);
189 Moment dt = t.length()/Rational (n);
190 MInterval basic = MInterval (t.left, t.left+dt);
191 for (int i= 0; i < n; i++)
192 children.push (new Rhythmic_grouping (dt*Rational (i) + basic));
196 Rhythmic_grouping::Rhythmic_grouping (Array<Rhythmic_grouping*> r)
202 Rhythmic_grouping::~Rhythmic_grouping()
208 Rhythmic_grouping::copy (Rhythmic_grouping const&s)
210 interval_ = (s.interval_)? new MInterval (*s.interval_) : 0;
211 for (int i=0; i < s.children.size(); i++)
212 children.push (new Rhythmic_grouping (*s.children[i]));
216 Rhythmic_grouping::operator=(Rhythmic_grouping const &s)
222 Rhythmic_grouping::Rhythmic_grouping (Rhythmic_grouping const&s)
229 Rhythmic_grouping::junk()
232 for (int i=0; i < children.size(); i++)
238 Rhythmic_grouping::print() const
243 DOUT <<" Interval "<< interval_->str();
244 for (int i=0; i < children.size(); i++)
246 children[i]->print();
253 Rhythmic_grouping::child_fit_b (Moment start)
256 return (children.top()->interval ().right== start);
262 Rhythmic_grouping::add_child (Moment start, Moment len)
264 Moment stop = start+len;
265 assert (child_fit_b (start));
266 children.push (new Rhythmic_grouping (MInterval (start, stop)));
269 Rhythmic_grouping::Rhythmic_grouping()
275 min_elt (Array<int> v)
278 for (int j = 0 ; j < v.size(); j++)
284 Rhythmic_grouping::generate_beams (Array<int> flags, int &flagidx)
286 assert (!interval_) ;
288 Array< Array<int> > children_beams;
289 for (int i=0; i < children.size(); i++)
291 Array<int> child_beams;
292 if (children[i]->interval_)
294 int f = flags[flagidx++];
295 child_beams.push (f);
299 child_beams = children[i]->
300 generate_beams (flags, flagidx);
302 children_beams.push (child_beams);
306 for (int i=0; i < children_beams.size(); i++)
308 bool add_left = (i >0);
309 bool add_right = (i < children_beams.size() -1);
312 m = min_elt (children_beams[i]);
314 nextm = min_elt (children_beams[i+1]);
316 if (children_beams[i].size() == 1)
326 beams.push (lastm <? m);
327 beams.concat (children_beams[i]);
329 beams.push (m <? nextm);
334 assert (!(beams.size()%2));
339 Rhythmic_grouping::translate (Moment m)
344 for (int i=0; i < children.size(); i++)
345 children[i]->translate (m);
349 Rhythmic_grouping::extend (MInterval m) const
351 assert (m.left >= interval().left);
352 while (m.right >interval().right)
354 Array<Rhythmic_grouping*> a (children);
355 for (int i=0; i < a.size(); i++)
357 a[i] =new Rhythmic_grouping (*children[i]);
358 a[i]->translate (children.top()->interval ().right);
360 ((Rhythmic_grouping*)this)->children.concat (a);
362 assert (m.right <= interval().right);
367 parse_grouping (Array<int> beat_i_arr, Array<Moment> elt_length_arr)
370 assert (beat_i_arr.size() == elt_length_arr.size ());
372 Array<Rhythmic_grouping*> children;
373 for (int i=0; i < beat_i_arr.size(); i++)
376 here += elt_length_arr[i] * Moment (beat_i_arr[i]);
378 new Rhythmic_grouping (MInterval (last, here),
381 return Rhythmic_grouping (children);