start_moment_ = 0;
beam_count_drul_[LEFT] = 0;
beam_count_drul_[RIGHT] = 0;
+
}
Beaming_info::Beaming_info (Moment m, int i)
}
int
-Beaming_info_list::best_splitpoint_index (Moment beat_length,
- bool subdivide_beams,
- bool *at_beat_subdivide) const
+Beaming_info_list::best_splitpoint_index (bool *at_boundary) const
{
+ *at_boundary = true;
+ for (vsize i = 1; i < infos_.size (); i++)
+ {
+ if (infos_[i].group_start_ == infos_[i].start_moment_)
+ return i;
+ }
+
+ for (vsize i = 1; i < infos_.size (); i++)
+ {
+ if (infos_[i].beat_start_ == infos_[i].start_moment_)
+ return i;
+ }
+
+ *at_boundary = false;
+
int min_denominator = INT_MAX;
int min_index = -1;
+
Moment beat_pos;
-
- for (vsize i = 1; i < infos_.size (); i++)
+ for (vsize i = 1; i < infos_.size (); i++)
{
- beat_pos = infos_[i].start_moment_ / beat_length;
- int den = beat_pos.den ();
- if (infos_[i].beam_count_drul_[LEFT] == infos_[i - 1].beam_count_drul_[RIGHT]
- && !subdivide_beams)
- den *= 2;
-
- if (den < min_denominator)
+ Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_;
+ if (dt.den () < min_denominator)
{
+ min_denominator = dt.den ();
min_index = i;
- min_denominator = den;
}
}
- *at_beat_subdivide = (min_denominator == 1 && subdivide_beams);
-
return min_index;
}
}
void
-Beaming_info_list::beamify ()
+Beaming_info_list::beamify (Context *context)
{
- bool subdivide_beams = to_boolean (context_->get_property ("subdivideBeams"));
- Moment beat_length = robust_scm2moment (context_->get_property ("beatLength"), Moment (1, 4));
+ if (infos_.size () <= 1)
+ return;
+
+ bool subdivide_beams = to_boolean (context->get_property ("subdivideBeams"));
+ Moment beat_length = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4));
+
+ SCM grouping = context->get_property ("beatGrouping");
+ Moment measure_pos (0);
+
+ vector<Moment> group_starts;
+ vector<Moment> beat_starts;
+
+ while (measure_pos <= infos_.back().start_moment_)
+ {
+ int count = 2;
+ if (scm_is_pair (grouping))
+ {
+ count = scm_to_int (scm_car (grouping));
+ grouping = scm_cdr (grouping);
+ }
- beamify (beat_length, subdivide_beams);
-}
+ group_starts.push_back (measure_pos);
+ for (int i = 0; i < count; i++)
+ {
+ beat_starts.push_back (measure_pos + beat_length * i);
+ }
+ measure_pos += beat_length * count;
+ }
+
+ vsize j = 0;
+ vsize k = 0;
+ for (vsize i = 0; i < infos_.size(); i++)
+ {
+ while (j < group_starts.size()-1
+ && group_starts[j+1] <= infos_[i].start_moment_)
+ j++;
+ infos_[i].group_start_ = group_starts[j];
+ while (k < beat_starts.size()-1
+ && beat_starts[k+1] <= infos_[i].start_moment_)
+ k++;
-Beaming_info_list *
-make_beaming_info_list (Context *context)
-{
- Beaming_info_list *l = new Beaming_info_list;
- l->context_ = context;
- return l;
-}
+ infos_[i].beat_start_ = beat_starts[k];
+ }
+
+ beamify (subdivide_beams);
+}
void
-Beaming_info_list::beamify (Moment beat_length,
- bool subdivide_beams)
+Beaming_info_list::beamify (bool subdivide_beams)
{
if (infos_.size () <= 1)
return;
-
- Drul_array<Beaming_info_list> splits (*this, *this);
+ Drul_array<Beaming_info_list> splits;
- bool split = false;
- int m = best_splitpoint_index (beat_length, subdivide_beams, &split);
+ bool at_boundary = false;
+ int m = best_splitpoint_index (&at_boundary);
splits[LEFT].infos_ = vector<Beaming_info> (infos_.begin (),
infos_.begin () + m);
do
{
- splits[d].beamify (beat_length, subdivide_beams);
+ splits[d].beamify (subdivide_beams);
}
while (flip (&d) != LEFT);
- int middle_beams = (split ? 1
+ int middle_beams = ((at_boundary && subdivide_beams)
+ ? 1
: min (splits[RIGHT].beam_extend_count (LEFT),
splits[LEFT].beam_extend_count (RIGHT)));
}
-
void
Beaming_info_list::add_stem (Moment m, int b)
{
infos_.push_back (Beaming_info (m, b));
}
-
Beaming_info_list::Beaming_info_list ()
{
- context_ = 0;
}
-
+int
+Beaming_info_list::beamlet_count (int i, Direction d) const
+{
+ return infos_.at (i).beam_count_drul_[d];
+}
Moment start_moment_;
Drul_array<int> beam_count_drul_;
+ Moment beat_start_;
+ Moment group_start_;
+
Beaming_info (Moment, int);
Beaming_info ();
Generate beaming given durations of notes. Beam uses this to
set_beaming () for each of its stems.
*/
-struct Beaming_info_list
+class Beaming_info_list
{
- vector<Beaming_info> infos_;
- Context *context_;
-
+public:
Beaming_info_list ();
- int beam_extend_count (Direction) const;
- int best_splitpoint_index (Moment, bool, bool *split) const;
- void beamify ();
- void beamify (Moment, bool);
+ void beamify (Context*);
void add_stem (Moment d, int beams);
+ int beamlet_count (int idx, Direction d) const;
+
+private:
+ vector<Beaming_info> infos_;
+ void beamify (bool);
+ int beam_extend_count (Direction) const;
+ int best_splitpoint_index (bool *split) const;
};
Beaming_info_list *make_beaming_info_list (Context *);