X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam-quanting.cc;h=695cb80b6eb2b8a950758b403b7e3bc3cb021507;hb=f9214bac21e9926dc3248416f58190c98c4167a9;hp=417fca00d27104642a7c9dbc62e15da6bfb76a89;hpb=545092a25d8ca41dc90b87482474b3719f7130a9;p=lilypond.git diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index 417fca00d2..695cb80b6e 100644 --- a/lily/beam-quanting.cc +++ b/lily/beam-quanting.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2005 Han-Wen Nienhuys + (c) 1997--2007 Han-Wen Nienhuys Jan Nieuwenhuizen */ @@ -12,12 +12,15 @@ #include using namespace std; -#include "warn.hh" -#include "staff-symbol-referencer.hh" -#include "stem.hh" +#include "grob.hh" +#include "align-interface.hh" +#include "international.hh" #include "output-def.hh" #include "pointer-group-interface.hh" -#include "align-interface.hh" +#include "staff-symbol-referencer.hh" +#include "stem.hh" +#include "warn.hh" +#include "main.hh" Real get_detail (SCM alist, SCM sym, Real def) @@ -34,15 +37,17 @@ Beam_quant_parameters::fill (Grob *him) { SCM details = him->get_property ("details"); + /* + TODO: put in define-grobs.scm + */ INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("inter-quant-penalty"), 1000.0); SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-demerit"), 10.0); STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-demerit-factor"), 5); REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); - - // possibly ridiculous, but too short stems just won't do STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-limit-penalty"), 5000); DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direction-penalty"), 800); + HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-penalty"), 20); MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direction-factor"), 400); IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor"), 10); ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope"), 0.02); @@ -60,8 +65,8 @@ struct Quant_score Real yr; Real demerits; -#if DEBUG_QUANTING - String score_card_; +#if DEBUG_BEAM_SCORING + string score_card_; #endif }; @@ -77,11 +82,11 @@ struct Quant_score */ int -best_quant_score_idx (Array const &qscores) +best_quant_score_idx (vector const &qscores) { Real best = 1e6; int best_idx = -1; - for (int i = qscores.size (); i--;) + for (vsize i = qscores.size (); i--;) { if (qscores[i].demerits < best) { @@ -122,8 +127,8 @@ Beam::quanting (SCM smob, SCM posns) Real quants [] = {straddle, sit, inter, hang }; int num_quants = int (sizeof (quants) / sizeof (Real)); - Array quantsl; - Array quantsr; + vector quantsl; + vector quantsr; /* going to REGION_SIZE == 2, yields another 0.6 second with @@ -138,19 +143,19 @@ Beam::quanting (SCM smob, SCM posns) Do stem computations. These depend on YL and YR linearly, so we can precompute for every stem 2 factors. */ - Link_array stems + vector stems = extract_grob_array (me, "stems"); - Array stem_infos; - Array base_lengths; - Array stem_xposns; + vector stem_infos; + vector base_lengths; + vector stem_xposns; Drul_array dirs_found (0, 0); Grob *common[2]; for (int a = 2; a--;) common[a] = common_refpoint_of_array (stems, me, Axis (a)); - Grob *fvs = first_visible_stem (me); - Grob *lvs = last_visible_stem (me); + Grob *fvs = first_normal_stem (me); + Grob *lvs = last_normal_stem (me); Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; Real xr = fvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; @@ -162,21 +167,21 @@ Beam::quanting (SCM smob, SCM posns) stem_y != 0.0, when we're cross staff. */ - for (int i = 0; i < stems.size (); i++) + for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; Stem_info si (Stem::get_stem_info (s)); si.scale (1 / ss); - stem_infos.push (si); - dirs_found[stem_infos.top ().dir_] = true; + stem_infos.push_back (si); + dirs_found[stem_infos.back ().dir_] = true; bool f = to_boolean (s->get_property ("french-beaming")) && s != lvs && s != fvs; - base_lengths.push (calc_stem_y (me, s, common, xl, xr, + base_lengths.push_back (calc_stem_y (me, s, common, xl, xr, Interval (0, 0), f) / ss); - stem_xposns.push (s->relative_coordinate (common[X_AXIS], X_AXIS)); + stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS)); } bool xstaff = false; @@ -187,7 +192,7 @@ Beam::quanting (SCM smob, SCM posns) } Direction ldir = Direction (stem_infos[0].dir_); - Direction rdir = Direction (stem_infos.top ().dir_); + Direction rdir = Direction (stem_infos.back ().dir_); bool is_knee = dirs_found[LEFT] && dirs_found[RIGHT]; int region_size = (int) parameters.REGION_SIZE; @@ -204,28 +209,28 @@ Beam::quanting (SCM smob, SCM posns) for (int i = -region_size; i < region_size; i++) for (int j = 0; j < num_quants; j++) { - quantsl.push (i + quants[j] + int (yl)); - quantsr.push (i + quants[j] + int (yr)); + quantsl.push_back (i + quants[j] + int (yl)); + quantsr.push_back (i + quants[j] + int (yr)); } - Array qscores; + vector qscores; - for (int l = 0; l < quantsl.size (); l++) - for (int r = 0; r < quantsr.size (); r++) + for (vsize l = 0; l < quantsl.size (); l++) + for (vsize r = 0; r < quantsr.size (); r++) { Quant_score qs; qs.yl = quantsl[l]; qs.yr = quantsr[r]; qs.demerits = 0.0; - qscores.push (qs); + qscores.push_back (qs); } /* This is a longish function, but we don't separate this out into neat modular separate subfunctions, as the subfunctions would be called for many values of YL, YR. By precomputing various parameters outside of the loop, we can save a lot of time. */ - for (int i = qscores.size (); i--;) + for (vsize i = qscores.size (); i--;) { Real d = score_slopes_dy (qscores[i].yl, qscores[i].yr, dy_mus, yr- yl, @@ -233,7 +238,7 @@ Beam::quanting (SCM smob, SCM posns) xstaff, ¶meters); qscores[i].demerits += d; -#if DEBUG_QUANTING +#if DEBUG_BEAM_SCORING qscores[i].score_card_ += to_string ("S%.2f", d); #endif } @@ -241,12 +246,12 @@ Beam::quanting (SCM smob, SCM posns) Real rad = Staff_symbol_referencer::staff_radius (me); Drul_array edge_beam_counts (Stem::beam_multiplicity (stems[0]).length () + 1, - Stem::beam_multiplicity (stems.top ()).length () + 1); + Stem::beam_multiplicity (stems.back ()).length () + 1); Real beam_translation = get_beam_translation (me) / ss; Real reasonable_score = (is_knee) ? 200000 : 100; - for (int i = qscores.size (); i--;) + for (vsize i = qscores.size (); i--;) if (qscores[i].demerits < reasonable_score) { Real d = score_forbidden_quants (qscores[i].yl, qscores[i].yr, @@ -254,12 +259,12 @@ Beam::quanting (SCM smob, SCM posns) edge_beam_counts, ldir, rdir, ¶meters); qscores[i].demerits += d; -#if DEBUG_QUANTING +#if DEBUG_BEAM_SCORING qscores[i].score_card_ += to_string (" F %.2f", d); #endif } - for (int i = qscores.size (); i--;) + for (vsize i = qscores.size (); i--;) if (qscores[i].demerits < reasonable_score) { Real d = score_stem_lengths (stems, stem_infos, @@ -269,24 +274,22 @@ Beam::quanting (SCM smob, SCM posns) qscores[i].yl, qscores[i].yr, ¶meters); qscores[i].demerits += d; -#if DEBUG_QUANTING +#if DEBUG_BEAM_SCORING qscores[i].score_card_ += to_string (" L %.2f", d); #endif } int best_idx = best_quant_score_idx (qscores); -#if DEBUG_QUANTING +#if DEBUG_BEAM_SCORING SCM inspect_quants = me->get_property ("inspect-quants"); - if (to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting"))) + if (to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring"))) && scm_is_pair (inspect_quants)) { Drul_array ins = ly_scm2interval (inspect_quants); - int i = 0; - Real mindist = 1e6; - for (; i < qscores.size (); i++) + for (vsize i = 0; i < qscores.size (); i++) { Real d = fabs (qscores[i].yl- ins[LEFT]) + fabs (qscores[i].yr - ins[RIGHT]); if (d < mindist) @@ -296,7 +299,7 @@ Beam::quanting (SCM smob, SCM posns) } } if (mindist > 1e5) - programming_error ("can't find quant"); + programming_error ("cannot find quant"); } #endif @@ -312,15 +315,15 @@ Beam::quanting (SCM smob, SCM posns) qscores[best_idx].yr); } -#if DEBUG_QUANTING +#if DEBUG_BEAM_SCORING if (best_idx >= 0 - && to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting")))) + && to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring")))) { qscores[best_idx].score_card_ += to_string ("i%d", best_idx); // debug quanting me->set_property ("quant-score", - scm_makfrom0str (qscores[best_idx].score_card_.to_str0 ())); + ly_string2scm (qscores[best_idx].score_card_)); } #endif @@ -328,10 +331,10 @@ Beam::quanting (SCM smob, SCM posns) } Real -Beam::score_stem_lengths (Link_array const &stems, - Array const &stem_infos, - Array const &base_stem_ys, - Array const &stem_xs, +Beam::score_stem_lengths (vector const &stems, + vector const &stem_infos, + vector const &base_stem_ys, + vector const &stem_xs, Real xl, Real xr, bool knee, Real yl, Real yr, @@ -342,7 +345,7 @@ Beam::score_stem_lengths (Link_array const &stems, Drul_array score (0, 0); Drul_array count (0, 0); - for (int i = 0; i < stems.size (); i++) + for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; if (Stem::is_invisible (s)) @@ -400,10 +403,19 @@ Beam::score_slopes_dy (Real yl, Real yr, TODO: find a way to incorporate the complexity of the beam in this penalty. */ - if (fabs (dy / dx) > parameters->ROUND_TO_ZERO_SLOPE - && sign (dy_damp) != sign (dy)) - dem += parameters->DAMPING_DIRECTION_PENALTY; - + if (sign (dy_damp) != sign (dy)) + { + if (!dy) + { + if (fabs (dy_damp / dx) > parameters->ROUND_TO_ZERO_SLOPE) + dem += parameters->DAMPING_DIRECTION_PENALTY; + else + dem += parameters->HINT_DIRECTION_PENALTY; + } + else + dem += parameters->DAMPING_DIRECTION_PENALTY; + } + dem += parameters->MUSICAL_DIRECTION_FACTOR * max (0.0, (fabs (dy) - fabs (dy_mus)));