X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam-quanting.cc;h=900f76626241f62b555007ce3b0303d8a7b17139;hb=a65798c5638c4d0a3b323e3e3012a754efe6984b;hp=e150a51594d3b0a4c8119f780769abac28e76254;hpb=8f5cd22af76fcb5c77853a5ede8b94ebef97caef;p=lilypond.git diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index e150a51594..900f766262 100644 --- a/lily/beam-quanting.cc +++ b/lily/beam-quanting.cc @@ -1,10 +1,21 @@ /* - beam-quanting.cc -- implement Beam quanting functions + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter - - (c) 1997--2006 Han-Wen Nienhuys + Copyright (C) 1997--2010 Han-Wen Nienhuys Jan Nieuwenhuizen + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "beam.hh" @@ -37,15 +48,13 @@ Beam_quant_parameters::fill (Grob *him) { SCM details = him->get_property ("details"); - 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); @@ -111,17 +120,16 @@ 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; + Real beam_thickness = Beam::get_beam_thickness (me) / ss; Real slt = Staff_symbol_referencer::line_thickness (me) / ss; Real dy_mus = robust_scm2double (me->get_property ("least-squares-dy"), 0); Real straddle = 0.0; - Real sit = (thickness - slt) / 2; + Real sit = (beam_thickness - slt) / 2; Real inter = 0.5; - Real hang = 1.0 - (thickness - slt) / 2; + Real hang = 1.0 - (beam_thickness - slt) / 2; Real quants [] = {straddle, sit, inter, hang }; int num_quants = int (sizeof (quants) / sizeof (Real)); @@ -132,7 +140,6 @@ Beam::quanting (SCM smob, SCM posns) going to REGION_SIZE == 2, yields another 0.6 second with wtk1-fugue2. - (result indexes between 70 and 575) ? --hwn. */ @@ -152,16 +159,14 @@ Beam::quanting (SCM smob, SCM posns) 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. */ @@ -177,17 +182,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_); @@ -253,7 +260,7 @@ Beam::quanting (SCM smob, SCM posns) if (qscores[i].demerits < reasonable_score) { Real d = score_forbidden_quants (qscores[i].yl, qscores[i].yr, - rad, slt, thickness, beam_translation, + rad, slt, beam_thickness, beam_translation, edge_beam_counts, ldir, rdir, ¶meters); qscores[i].demerits += d; @@ -321,7 +328,7 @@ Beam::quanting (SCM smob, SCM posns) // debug quanting me->set_property ("quant-score", - scm_makfrom0str (qscores[best_idx].score_card_.c_str ())); + ly_string2scm (qscores[best_idx].score_card_)); } #endif @@ -346,7 +353,7 @@ Beam::score_stem_lengths (vector 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]; @@ -377,8 +384,7 @@ Beam::score_stem_lengths (vector 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]; } @@ -401,10 +407,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))); @@ -437,7 +452,7 @@ Real Beam::score_forbidden_quants (Real yl, Real yr, Real radius, Real slt, - Real thickness, Real beam_translation, + Real beam_thickness, Real beam_translation, Drul_array beam_counts, Direction ldir, Direction rdir, @@ -465,8 +480,8 @@ Beam::score_forbidden_quants (Real yl, Real yr, will be in the gap of the (2, sit) quant, leading to a false demerit. */ - Real gap1 = y[d] - stem_dir * ((j - 1) * beam_translation + thickness / 2 - slt / 2.2); - Real gap2 = y[d] - stem_dir * (j * beam_translation - thickness / 2 + slt / 2.2); + Real gap1 = y[d] - stem_dir * ((j - 1) * beam_translation + beam_thickness / 2 - slt / 2.2); + Real gap2 = y[d] - stem_dir * (j * beam_translation - beam_thickness / 2 + slt / 2.2); Interval gap; gap.add_point (gap1); @@ -494,9 +509,9 @@ Beam::score_forbidden_quants (Real yl, Real yr, if (max (beam_counts[LEFT], beam_counts[RIGHT]) >= 2) { Real straddle = 0.0; - Real sit = (thickness - slt) / 2; + Real sit = (beam_thickness - slt) / 2; Real inter = 0.5; - Real hang = 1.0 - (thickness - slt) / 2; + Real hang = 1.0 - (beam_thickness - slt) / 2; Direction d = LEFT; do