X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam-quanting.cc;h=17ad169a1fc34d18a2372d57ce2346bae0c2789c;hb=3827988ac5a8d758508b68b4de399bf351504d03;hp=5b9b2dbaed808658d9a714472cf634161d2f3152;hpb=64313890b232c731d432e5b096f30bffc3f3756d;p=lilypond.git diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index 5b9b2dbaed..17ad169a1f 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--2006 Han-Wen Nienhuys + (c) 1997--2007 Han-Wen Nienhuys Jan Nieuwenhuizen */ @@ -12,6 +12,7 @@ #include using namespace std; +#include "grob.hh" #include "align-interface.hh" #include "international.hh" #include "output-def.hh" @@ -19,6 +20,7 @@ using namespace std; #include "staff-symbol-referencer.hh" #include "stem.hh" #include "warn.hh" +#include "main.hh" Real get_detail (SCM alist, SCM sym, Real def) @@ -35,15 +37,17 @@ Beam_quant_parameters::fill (Grob *him) { SCM details = him->get_property ("details"); + /* + TODO: The default values should be copied to 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); @@ -61,8 +65,8 @@ struct Quant_score Real yr; Real demerits; -#if DEBUG_QUANTING - std::string score_card_; +#if DEBUG_BEAM_SCORING + string score_card_; #endif }; @@ -78,7 +82,7 @@ struct Quant_score */ int -best_quant_score_idx (std::vector const &qscores) +best_quant_score_idx (vector const &qscores) { Real best = 1e6; int best_idx = -1; @@ -109,7 +113,6 @@ Beam::quanting (SCM smob, SCM posns) /* Calculations are relative to a unit-scaled staff, i.e. the quants are divided by the current staff_space. - */ Real ss = Staff_symbol_referencer::staff_space (me); Real thickness = Beam::get_thickness (me) / ss; @@ -123,14 +126,13 @@ Beam::quanting (SCM smob, SCM posns) Real quants [] = {straddle, sit, inter, hang }; int num_quants = int (sizeof (quants) / sizeof (Real)); - std::vector quantsl; - std::vector quantsr; + vector quantsl; + vector quantsr; /* going to REGION_SIZE == 2, yields another 0.6 second with wtk1-fugue2. - (result indexes between 70 and 575) ? --hwn. */ @@ -139,27 +141,25 @@ 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"); - std::vector stem_infos; - std::vector base_lengths; - std::vector 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; /* - We store some info to quickly interpolate. - - Sometimes my head is screwed on backwards. The stemlength are - AFFINE linear in YL and YR. If YL == YR == 0, then we might have + We store some info to quickly interpolate. The stemlength are + affine linear in YL and YR. If YL == YR == 0, then we might have stem_y != 0.0, when we're cross staff. */ @@ -175,17 +175,19 @@ Beam::quanting (SCM smob, SCM posns) bool f = to_boolean (s->get_property ("french-beaming")) && s != lvs && s != fvs; - base_lengths.push_back (calc_stem_y (me, s, common, xl, xr, - Interval (0, 0), f) / ss); - stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS)); - } + if (Stem::is_normal_stem (s)) + { + base_lengths.push_back (calc_stem_y (me, s, common, xl, xr, CENTER, + Interval (0, 0), f) / ss); + } + else + { + base_lengths.push_back (0); + } - bool xstaff = false; - if (lvs && fvs) - { - Grob *commony = fvs->common_refpoint (lvs, Y_AXIS); - xstaff = Align_interface::has_interface (commony); + stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS)); } + bool xstaff = Align_interface::has_interface (common[Y_AXIS]); Direction ldir = Direction (stem_infos[0].dir_); Direction rdir = Direction (stem_infos.back ().dir_); @@ -209,7 +211,7 @@ Beam::quanting (SCM smob, SCM posns) quantsr.push_back (i + quants[j] + int (yr)); } - std::vector qscores; + vector qscores; for (vsize l = 0; l < quantsl.size (); l++) for (vsize r = 0; r < quantsr.size (); r++) @@ -234,7 +236,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 } @@ -255,7 +257,7 @@ 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 } @@ -270,16 +272,16 @@ 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); @@ -295,7 +297,7 @@ Beam::quanting (SCM smob, SCM posns) } } if (mindist > 1e5) - programming_error ("can't find quant"); + programming_error ("cannot find quant"); } #endif @@ -311,15 +313,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_.c_str ())); + ly_string2scm (qscores[best_idx].score_card_)); } #endif @@ -327,10 +329,10 @@ Beam::quanting (SCM smob, SCM posns) } Real -Beam::score_stem_lengths (Link_array const &stems, - std::vector const &stem_infos, - std::vector const &base_stem_ys, - std::vector 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, @@ -344,7 +346,7 @@ Beam::score_stem_lengths (Link_array const &stems, for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; - if (Stem::is_invisible (s)) + if (!Stem::is_normal_stem (s)) continue; Real x = stem_xs[i]; @@ -375,8 +377,7 @@ Beam::score_stem_lengths (Link_array const &stems, Direction d = DOWN; do score[d] /= max (count[d], 1); - while (flip (&d) != DOWN) - ; + while (flip (&d) != DOWN); return score[LEFT] + score[RIGHT]; } @@ -399,10 +400,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)));