]> git.donarmstrong.com Git - lilypond.git/blob - lily/beaming-pattern.cc
Issue 4550 (1/2) Avoid "using namespace std;" in included files
[lilypond.git] / lily / beaming-pattern.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "context.hh"
21 #include "beaming-pattern.hh"
22 #include "misc.hh"
23
24 using std::vector;
25
26 /*
27   Represents a stem belonging to a beam. Sometimes (for example, if the stem
28   belongs to a rest and stemlets aren't used) the stem will be invisible.
29
30   The rhythmic_importance_ of an element tells us the significance of the
31   moment at which this element occurs. For example, an element that occurs at
32   a beat is more significant than one that doesn't. Smaller number are
33   more important. The rhythmic_importance_ is decided and filled in by
34   Beaming_pattern. A rhythmic_importance_ smaller than zero has extra
35   significance: it represents the start of a beat and therefore beams may
36   need to be subdivided.
37 */
38 Beam_rhythmic_element::Beam_rhythmic_element ()
39 {
40   start_moment_ = 0;
41   rhythmic_importance_ = 0;
42   beam_count_drul_[LEFT] = 0;
43   beam_count_drul_[RIGHT] = 0;
44   invisible_ = false;
45   factor_ = Rational (1);
46   tuplet_start_ = false;
47 }
48
49 Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
50                                               Rational factor, bool tuplet_start)
51 {
52   start_moment_ = m;
53   rhythmic_importance_ = 0;
54   beam_count_drul_[LEFT] = i;
55   beam_count_drul_[RIGHT] = i;
56   invisible_ = inv;
57   factor_ = factor;
58   tuplet_start_ = tuplet_start;
59 }
60
61 void
62 Beam_rhythmic_element::de_grace ()
63 {
64   if (start_moment_.grace_part_)
65     {
66       start_moment_.main_part_ = start_moment_.grace_part_;
67       start_moment_.grace_part_ = 0;
68     }
69 }
70
71 int
72 Beam_rhythmic_element::count (Direction d) const
73 {
74   return beam_count_drul_[d];
75 }
76
77 /*
78   Finds the appropriate direction for the flags at the given index that
79   hang below the neighbouring flags. If
80   the stem has no more flags than either of its neighbours, this returns
81   CENTER.
82 */
83 Direction
84 Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
85 {
86   // The extremal stems shouldn't be messed with, so it's appropriate to
87   // return CENTER here also.
88   if (i == 0 || i == infos_.size () - 1)
89     return CENTER;
90
91   int count = infos_[i].count (LEFT); // Both directions should still be the same
92   int left_count = infos_[i - 1].count (RIGHT);
93   int right_count = infos_[i + 1].count (LEFT);
94
95   // If we are told to subdivide beams and we are next to a beat, point the
96   // beamlet away from the beat.
97   if (options.subdivide_beams_)
98     {
99       if (infos_[i].rhythmic_importance_ < 0)
100         return RIGHT;
101       else if (infos_[i + 1].rhythmic_importance_ < 0)
102         return LEFT;
103     }
104
105   if (count <= left_count && count <= right_count)
106     return CENTER;
107   else if (!options.strict_beat_beaming_)
108     {
109       // Try to avoid sticking-out flags as much as possible by pointing
110       // my flags at the neighbor with the most flags.
111       if (right_count > left_count)
112         return RIGHT;
113       else if (left_count > right_count)
114         return LEFT;
115     }
116
117   // If all else fails, point the beamlet away from the important moment.
118   return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
119          ? RIGHT : LEFT;
120 }
121
122 void
123 Beaming_pattern::de_grace ()
124 {
125   for (vsize i = 0; i < infos_.size (); i++)
126     {
127       infos_[i].de_grace ();
128     }
129 }
130
131 void
132 Beaming_pattern::beamify (Beaming_options const &options)
133 {
134   if (infos_.size () <= 1)
135     return;
136
137   int subdivide_beam_count = intlog2(options.base_moment_.main_part_.den())-2;
138
139   unbeam_invisible_stems ();
140
141   if (infos_[0].start_moment_.grace_part_)
142     de_grace ();
143
144   if (infos_[0].start_moment_ < Moment (0))
145     for (vsize i = 0; i < infos_.size (); i++)
146       infos_[i].start_moment_ += options.measure_length_;
147
148   find_rhythmic_importance (options);
149
150   vector <Direction> flag_directions;
151   // Get the initial flag directions
152   for (vsize i = 0; i < infos_.size (); i++)
153     flag_directions.push_back (flag_direction (options, i));
154
155   // Correct flag directions for subdivision
156   for (vsize i = 1; i < infos_.size () - 1; i++)
157     {
158       if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
159         flag_directions[i] = RIGHT;
160       if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
161         flag_directions[i] = LEFT;
162     }
163
164   // Set the count on each side of the stem
165   // We need to run this code twice to make both the
166   // left and the right counts work properly
167   for (int i = 0; i < 2; i++)
168     for (vsize i = 1; i < infos_.size () - 1; i++)
169       {
170         Direction non_flag_dir = -flag_directions[i];
171         if (non_flag_dir)
172           {
173             int importance = infos_[i + 1].rhythmic_importance_;
174             int count = (importance < 0 && options.subdivide_beams_) 
175                         ? subdivide_beam_count
176                         : min (min (infos_[i].count (non_flag_dir),
177                                         infos_[i + non_flag_dir].count (-non_flag_dir)),
178                                    infos_[i - non_flag_dir].count (non_flag_dir));
179
180             infos_[i].beam_count_drul_[non_flag_dir] = count;
181           }
182       }
183 }
184
185 /*
186    Set the tuplet start moment as necessary
187 */
188 void
189 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
190 {
191   int tuplet_number = (int) factor.den ();
192   if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
193     *tuplet_start_moment = start_moment;
194   else if (tuplet_number == 1)
195     *tuplet_start_moment = Moment (-1, 1);
196 }
197
198 /*
199    Get the group start position, the next group starting position, and the
200    next beat starting position, given start_moment, base_moment,
201    grouping, and factor
202 */
203 void
204 find_location (SCM grouping, Moment base_moment, Moment start_moment,
205                Rational factor, Moment *group_pos, Moment *next_group_pos,
206                Moment *next_beat_pos)
207 {
208   *group_pos = Moment (0);
209   *next_group_pos = Moment (0);
210   *next_beat_pos = base_moment;
211
212   while (*next_beat_pos <= start_moment)
213     *next_beat_pos += base_moment;
214
215   while (*next_group_pos < *next_beat_pos)
216     {
217       I64 group_count = 1;  //default -- 1 base moments in a beam
218       if (scm_is_pair (grouping))
219         {
220           group_count = scm_to_int (scm_car (grouping));
221           grouping = scm_cdr (grouping);
222         }
223
224       // If we have a tuplet, the count should be determined from
225       // the maximum tuplet size for beamed tuplets.
226       U64 tuplet_number = factor.den ();
227       if (tuplet_number > 1U)
228         {
229           // We use 1/8 as the base moment for the tuplet because it's
230           // the largest beamed value.  If the tuplet is shorter, it's
231           // OK, the code still works
232           I64 test_count = ( Moment (Rational (1, 8) / factor) / base_moment).num ();
233           if (test_count > group_count) group_count = test_count;
234         }
235       *group_pos = *next_group_pos;
236       *next_group_pos = *group_pos + Rational(group_count) * base_moment;
237     }
238 }
239
240 void
241 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
242 {
243   Moment group_pos (0);  // 0 is the start of the first group
244   Moment next_group_pos (0);
245   Moment next_beat_pos (options.base_moment_);
246   Moment tuplet_start_moment (-1, 1);
247   I64 tuplet_number = 1;
248
249   SCM grouping = options.grouping_;
250   vsize i = 0;
251
252   // Find where we are in the beat structure of the measure
253   if (infos_.size ())
254     find_location (grouping, options.base_moment_, infos_[i].start_moment_,
255                    infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
256
257   // Mark the importance of stems that start at a beat or a beat group.
258   while (i < infos_.size ())
259     {
260       if ((next_beat_pos > next_group_pos)
261           || (infos_[i].start_moment_ > next_beat_pos))
262         // Find the new group ending point
263         find_location (grouping, options.base_moment_, infos_[i].start_moment_,
264                        infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
265       // Mark the start of this beat group
266       if (infos_[i].start_moment_ == group_pos)
267         infos_[i].rhythmic_importance_ = -2;
268       // Work through the end of the beat group or the end of the beam
269       while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
270         {
271           // Set the tuplet start as necessary
272           update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
273           Moment dt = infos_[i].start_moment_ - group_pos;
274           Rational tuplet = infos_[i].factor_;
275           Moment tuplet_moment (tuplet);
276           Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
277           tuplet_number = tuplet.den ();
278           // set the beat end and increment the next beat
279           if (infos_[i].start_moment_ == next_beat_pos)
280             {
281               infos_[i].rhythmic_importance_ = -1;
282               next_beat_pos += options.base_moment_;
283             }
284           // The rhythmic importance of a stem between beats depends on its fraction
285           // of a beat: those stems with a lower denominator are deemed more
286           // important.  For tuplets, we need to make sure that we use
287           // the fraction of the tuplet, instead of the fraction of
288           // a beat.
289           Moment ratio = (tuplet_number == 1)
290                          ? dt / options.base_moment_
291                          : tuplet_dt / Moment (1, 8) / tuplet_moment;
292           if (infos_[i].rhythmic_importance_ >= 0)
293             infos_[i].rhythmic_importance_ = (int) ratio.den ();
294
295           i++;
296         }
297
298       if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
299         {
300           if (tuplet_number == 1)
301             infos_[i].rhythmic_importance_ = -1;
302           next_beat_pos += options.base_moment_;
303           if (infos_[i].start_moment_ == next_group_pos)
304             infos_[i].rhythmic_importance_ = -2;
305         }
306     }
307 }
308
309 /*
310   Invisible stems should be treated as though they have the same number of
311   beams as their least-beamed neighbour. Here we go through the stems and
312   modify the invisible stems to satisfy this requirement.
313 */
314 void
315 Beaming_pattern::unbeam_invisible_stems ()
316 {
317   for (vsize i = 1; i < infos_.size (); i++)
318     if (infos_[i].invisible_)
319       {
320         int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
321         infos_[i].beam_count_drul_[LEFT] = b;
322         infos_[i].beam_count_drul_[RIGHT] = b;
323       }
324
325   if (infos_.size () > 1)
326     for (vsize i = infos_.size () - 1; i--;)
327       if (infos_[i].invisible_)
328         {
329           int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
330           infos_[i].beam_count_drul_[LEFT] = b;
331           infos_[i].beam_count_drul_[RIGHT] = b;
332         }
333 }
334
335 void
336 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor, bool tuplet_start)
337 {
338   infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor, tuplet_start));
339 }
340
341 Beaming_pattern::Beaming_pattern ()
342 {
343 }
344
345 int
346 Beaming_pattern::beamlet_count (int i, Direction d) const
347 {
348   return infos_.at (i).beam_count_drul_[d];
349 }
350
351 Moment
352 Beaming_pattern::start_moment (int i) const
353 {
354   return infos_.at (i).start_moment_;
355 }
356
357 Moment
358 Beaming_pattern::end_moment (int i) const
359 {
360   Duration dur (2 + max (beamlet_count (i, LEFT),
361                          beamlet_count (i, RIGHT)),
362                 0);
363
364   return infos_.at (i).start_moment_
365          + infos_.at (i).factor_ * dur.get_length ();
366 }
367
368 bool
369 Beaming_pattern::invisibility (int i) const
370 {
371   return infos_.at (i).invisible_;
372 }
373
374 Rational
375 Beaming_pattern::factor (int i) const
376 {
377   return infos_.at (i).factor_;
378 }
379
380 bool
381 Beaming_pattern::tuplet_start (int i) const
382 {
383   return infos_.at (i).tuplet_start_;
384 }
385
386 /*
387     Split a beaming pattern at index i and return a new
388     Beaming_pattern containing the removed elements
389 */
390 Beaming_pattern *
391 Beaming_pattern::split_pattern (int i)
392 {
393   Beaming_pattern *new_pattern = 0;
394   int count;
395
396   new_pattern = new Beaming_pattern ();
397   for (vsize j = i + 1; j < infos_.size (); j++)
398     {
399       count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
400       new_pattern->add_stem (start_moment (j),
401                              count,
402                              invisibility (j),
403                              factor (j),
404                              tuplet_start (j));
405     }
406   for (vsize j = i + 1; j < infos_.size ();)
407     infos_.pop_back ();
408   return (new_pattern);
409 }
410
411 void
412 Beaming_options::from_context (Context *context)
413 {
414   grouping_ = context->get_property ("beatStructure");
415   subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
416   strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
417   base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
418                                     Moment (1, 4));
419   measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
420                                        Moment (4, 4));
421 }
422
423 Beaming_options::Beaming_options ()
424 {
425   grouping_ = SCM_EOL;
426   subdivide_beams_ = false;
427   strict_beat_beaming_ = false;
428 }