2 rhythmic-grouping.cc -- implement Rhythmic_grouping
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "rhythmic-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_mom () 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 () <= Moment (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 Link_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 Link_array<Rhythmic_grouping> slice = children.slice (starti, i+1);
164 Rhythmic_grouping *newchild=new Rhythmic_grouping (slice);
181 Rhythmic_grouping::Rhythmic_grouping (MInterval t, int n)
186 interval_ = new MInterval (t);
189 Moment dt = t.length ()/Moment (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*Moment (i) + basic));
196 Rhythmic_grouping::Rhythmic_grouping (Link_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 junk_pointer_array (children);
237 Rhythmic_grouping::print() const
242 DOUT <<" Interval "<< interval_->str();
243 for (int i=0; i < children.size(); i++)
245 children[i]->print();
252 Rhythmic_grouping::child_fit_b (Moment start)
255 return (children.top()->interval ()[RIGHT]== start);
261 Rhythmic_grouping::add_child (Moment start, Moment len)
263 Moment stop = start+len;
264 assert (child_fit_b (start));
265 children.push (new Rhythmic_grouping (MInterval (start, stop)));
268 Rhythmic_grouping::Rhythmic_grouping()
274 min_elt (Array<int> v)
277 for (int j = 0 ; j < v.size(); j++)
283 Rhythmic_grouping::generate_beams (Array<int> flags, int &flagidx)
285 assert (!interval_) ;
287 Array< Array<int> > children_beams;
288 for (int i=0; i < children.size(); i++)
290 Array<int> child_beams;
291 if (children[i]->interval_)
293 int f = flags[flagidx++];
294 child_beams.push (f);
298 child_beams = children[i]->
299 generate_beams (flags, flagidx);
301 children_beams.push (child_beams);
305 for (int i=0; i < children_beams.size(); i++)
307 bool add_left = (i >0);
308 bool add_right = (i < children_beams.size() -1);
311 m = min_elt (children_beams[i]);
313 nextm = min_elt (children_beams[i+1]);
315 if (children_beams[i].size() == 1)
325 beams.push (lastm <? m);
326 beams.concat (children_beams[i]);
328 beams.push (m <? nextm);
333 assert (!(beams.size()%2));
338 Rhythmic_grouping::translate (Moment m)
343 for (int i=0; i < children.size(); i++)
344 children[i]->translate (m);
348 Rhythmic_grouping::extend (MInterval m) const
350 assert (m[LEFT] >= interval()[LEFT]);
351 while (m[RIGHT] >interval()[RIGHT])
353 Link_array<Rhythmic_grouping> a (children);
354 for (int i=0; i < a.size(); i++)
356 a[i] =new Rhythmic_grouping (*children[i]);
357 a[i]->translate (children.top()->interval ()[RIGHT]);
359 ((Rhythmic_grouping*)this)->children.concat (a);
361 assert (m[RIGHT] <= interval()[RIGHT]);
366 parse_grouping (Array<int> beat_i_arr, Array<Moment> elt_length_arr)
369 assert (beat_i_arr.size() == elt_length_arr.size ());
371 Link_array<Rhythmic_grouping> children;
372 for (int i=0; i < beat_i_arr.size(); i++)
375 here += elt_length_arr[i] * Moment (beat_i_arr[i]);
377 new Rhythmic_grouping (MInterval (last, here),
380 return Rhythmic_grouping (children);