From fa65a4be862681bc8b06207b9013a07b47ee7f56 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 17 Mar 2002 01:40:33 +0100 Subject: [PATCH] patch::: 1.5.41.jcn2 2002-03-17 Jan Nieuwenhuizen * lily/beam.cc (score_stem_lengths): new quanting stuff --- Generated by janneke@gnu.org, From = lilypond-1.5.41.jcn1, To = lilypond-1.5.41.jcn2 usage cd lilypond-source-dir; patch -E -p1 < lilypond-1.5.41.jcn2.diff Patches do not contain automatically generated files or (urg) empty directories, i.e., you should rerun autoconf, configure --- ChangeLog | 11 +- VERSION | 2 +- input/baerenreiter-sarabande.ly | 2 +- lily/beam.cc | 259 +++++++++++++++++++++++++++++++- lily/gourlay-breaking.cc | 8 +- lily/include/beam.hh | 7 +- lily/include/lily-guile.hh | 2 + lily/include/stem-info.hh | 5 + lily/simple-spacer.cc | 5 +- lily/stem.cc | 23 ++- scm/beam.scm | 4 +- scm/grob-description.scm | 10 +- 12 files changed, 319 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46d1ad78bc..6e406bea03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ ---- ../lilypond-1.5.41/ChangeLog Fri Mar 15 15:44:50 2002 +--- ../lilypond-1.5.41.jcn1/ChangeLog Sat Mar 16 16:04:22 2002 +++ b/ChangeLog Sun Mar 17 01:40:33 2002 +@@ -1,3 +1,7 @@ +2002-03-17 Jan Nieuwenhuizen + + * lily/beam.cc (score_stem_lengths): new quanting stuff + + 2002-03-16 Jan Nieuwenhuizen + + * lily/beam.cc (least_squares): Remember least-squares-dy for--- ../lilypond-1.5.41/ChangeLog Fri Mar 15 15:44:50 2002 ++ b/ChangeLog Sat Mar 16 16:04:22 2002 @@ -1,3 +1,16 @@ 2002-03-16 Jan Nieuwenhuizen diff --git a/VERSION b/VERSION index a8b541224c..dd48c06393 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 PATCH_LEVEL=41 -MY_PATCH_LEVEL=jcn1 +MY_PATCH_LEVEL=jcn2 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/baerenreiter-sarabande.ly b/input/baerenreiter-sarabande.ly index 175735eef1..5b62551dc6 100644 --- a/input/baerenreiter-sarabande.ly +++ b/input/baerenreiter-sarabande.ly @@ -90,7 +90,7 @@ sarabandeA = \context Voice \notes \relative c { \stemUp d4 d,16 a'( b cis d e f )g | \stemBoth - \break +% \break %%25 < { a16(b c)b c4. b16()a | b cis d cis d4. e16()f | } diff --git a/lily/beam.cc b/lily/beam.cc index 67d9b664ce..df22bb957a 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -41,6 +41,17 @@ #include "item.hh" #include "spanner.hh" #include "warn.hh" +#include "text-item.hh" // debug output. +#include "font-interface.hh" // debug output. + + + +Real +shrink_extra_weight(Real x) +{ + return fabs(x) * ((x < 0) ? 1.5 : 1.0); +} + void Beam::add_stem (Grob *me, Grob *s) @@ -146,7 +157,6 @@ Beam::get_default_dir (Grob *me) total[d] += current; count[d] ++; } - } while (flip (&d) != DOWN); SCM func = me->get_grob_property ("dir-function"); @@ -309,6 +319,207 @@ Beam::after_line_breaking (SCM smob) return SCM_UNSPECIFIED; } +struct Quant_score +{ + Real yl; + Real yr; + Real demerits; +}; + + +MAKE_SCHEME_CALLBACK (Beam, new_quanting, 1); +SCM +Beam::new_quanting (SCM smob) +{ + Grob *me = unsmob_grob (smob); + + SCM s = me->get_grob_property ("positions"); + Real yl = gh_scm2double (gh_car(s)); + Real yr = gh_scm2double (gh_cdr(s)); + + Real thick = gh_scm2double (me->get_grob_property ("thickness")); + // Staff_symbol_referencer::staff_space (me); + Real sthick = me->paper_l()->get_var ("stafflinethickness"); + // * Staff_symbol_referencer::staff_space (me); + + Real quants [] = {0.0, thick/2 - sthick / 2, 0.5, 1.0 - thick/2 + sthick/2}; + int num_quants = int(sizeof(quants)/sizeof (Real)); + Array quantsl; + Array quantsr; + + const int REGION_SIZE = 3; + + 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)); + } + + Array qscores; + + for(int l =0; l < quantsl.size(); l++) + for(int r =0; r < quantsr.size(); r++) + { + Quant_score qs; + qs.yl = quantsl[l]; + qs.yr = quantsr[r]; + qs.demerits = 0.0; + + qscores.push (qs); + } + + + SCM score_funcs = me->get_grob_property("quant-score-functions"); + for (SCM s = score_funcs; gh_pair_p (s); s = gh_cdr (s)) + { + SCM f = gh_car (s); + for (int i = qscores.size(); i--;) + { + if (qscores[i].demerits < 1000) + { + SCM score = gh_call3 (f, + me->self_scm(), + gh_double2scm (qscores[i].yl), + gh_double2scm (qscores[i].yr)); + + qscores[i].demerits += gh_scm2double (score); + } + } + } + + Real best = 1e6; + int best_idx = -1; + for (int i = qscores.size(); i--;) + { + if (qscores[i].demerits < best) + { + best = qscores [i].demerits ; + best_idx = i; + } + } + + + me->set_grob_property ("positions", + gh_cons (gh_double2scm (qscores[best_idx].yl), + gh_double2scm (qscores[best_idx].yr)) + ); + me->set_grob_property ("quant-score",gh_double2scm (qscores[best_idx].demerits)); + + return SCM_UNSPECIFIED; +} + +MAKE_SCHEME_CALLBACK (Beam, score_slopes_dy, 3); +SCM +Beam::score_slopes_dy (SCM smob, SCM syl, SCM syr) +{ + Grob*me = unsmob_grob(smob); + Real yl = gh_scm2double (syl); + Real yr = gh_scm2double (syr); + Real dy = yr - yl; + + SCM sdy = me->get_grob_property("least-squares-dy"); + SCM posns = me->get_grob_property ("positions"); + + Real dy_mus = gh_number_p (sdy) ? gh_scm2double (sdy) : 0.0; + Real dy_damp = - gh_scm2double (gh_car(posns)) + gh_scm2double (gh_cdr (posns)); + + Real dem = 0.0; + if (sign (dy_damp) != sign (dy)) + { + dem += 800; + } + + dem += 400* (0 >? (fabs(dy) - fabs(dy_mus))); + + + dem += shrink_extra_weight (fabs (dy_damp) - fabs(dy))* 10; + return gh_double2scm (dem); +} + +MAKE_SCHEME_CALLBACK (Beam, score_stem_lengths, 3); +SCM +Beam::score_stem_lengths (SCM smob, SCM syl, SCM syr) +{ + Grob*me = unsmob_grob(smob); + Real yl = gh_scm2double (syl); + Real yr = gh_scm2double (syr); + + Link_array stems= + Pointer_group_interface__extract_grobs (me, (Item*)0, "stems"); + + Real demerit_score = 0.0 ; + + for (int i=0; i < stems.size (); i++) + { + Item* s = stems[i]; + if (Stem::invisible_b (s)) + continue; + + Real current_y = calc_stem_y_f (me, s, Interval(yl,yr)); + Stem_info info = Stem::calc_stem_info (s); + Direction d = Directional_element_interface::get (s); + + demerit_score += 500 * ( 0 >? (info.miny_f_ - d*current_y)); + demerit_score += 500 * ( 0 >? (d * current_y - info.maxy_f_)); + + demerit_score += 5 * shrink_extra_weight (d * current_y - info.idealy_f_); + } + + demerit_score *= 2.0 /stems.size(); + + return gh_double2scm (demerit_score); +} +Real +my_modf(Real x) +{ + return x - floor(x); +} + + + +MAKE_SCHEME_CALLBACK (Beam, score_forbidden_quants, 3); +SCM +Beam::score_forbidden_quants (SCM smob, SCM syl, SCM syr) +{ + Grob*me = unsmob_grob(smob); + Real yl = gh_scm2double (syl); + Real yr = gh_scm2double (syr); + Real rad = Staff_symbol_referencer::staff_radius (me); + Real dem = 0.0; + if (fabs (yl) < 2*rad && fabs( my_modf(yl) - 0.5) < 1e-3) + dem += 1000; + if (fabs (yr) < 2*rad && fabs( my_modf(yr) - 0.5) < 1e-3) + dem += 1000; + + + int multiplicity = get_multiplicity (me); + // todo: use multiplicity of outer stems. + if (multiplicity >= 2) + { + Real slt = me->paper_l()->get_var("stafflinethickness"); + Real ss = Staff_symbol_referencer::staff_space(me); + Real thickness = gh_scm2double (me->get_grob_property ("thickness")) * ss; + + Real beam_space= (2*ss + slt - 3 *thickness) / 2.0; + if (multiplicity >= 4) + { + beam_space = (3*ss + slt - 4 * thickness) /3.0; + } + + Direction d = Directional_element_interface::get (me); + yl += d * (beam_space + thickness); + yr += d * (beam_space + thickness); + if (fabs (yl) < rad && fabs( my_modf(yl) - 0.5) < 0.1) + dem += 15; + if (fabs (yr) < rad && fabs( my_modf(yr) - 0.5) < 0.1) + dem += 15; + } + + return gh_double2scm ( dem); +} + + MAKE_SCHEME_CALLBACK (Beam, least_squares, 1); SCM @@ -329,11 +540,20 @@ Beam::least_squares (SCM smob) Interval ideal (Stem::calc_stem_info (first_visible_stem (me)).idealy_f_, Stem::calc_stem_info (last_visible_stem (me)).idealy_f_); + if (!ideal.delta ()) { Interval chord (Stem::chord_start_f (first_visible_stem (me)), Stem::chord_start_f (last_visible_stem (me))); - + + + /* + TODO : use scoring for this. + + complicated, because we take stem-info.ideal for determining + beam slopes. + + */ /* Make simple beam on middle line have small tilt */ if (!ideal[LEFT] && chord.delta () && count == 2) { @@ -343,7 +563,11 @@ Beam::least_squares (SCM smob) pos[-d] = - pos[d]; } else - pos = ideal; + { + pos = ideal; + pos[LEFT] *= dir ; + pos[RIGHT] *= dir ; + } } else { @@ -415,7 +639,9 @@ Beam::check_concave (SCM smob) else if ((c = f - iv[MIN]) < 0) concave += c; } - concave *= Directional_element_interface::get (me); + + Direction dir = Directional_element_interface::get (me); + concave *= dir; Real concaveness = concave / (stems.size () - 2); /* ugh: this is the a kludge to get input/regression/beam-concave.ly @@ -430,7 +656,7 @@ Beam::check_concave (SCM smob) Interval pos = ly_scm2interval (me->get_grob_property ("positions")); Real r = pos.linear_combination (0); me->set_grob_property ("positions", ly_interval2scm (Interval (r, r))); - me->remove_grob_property ("least-squares-dy"); + me->set_grob_property ("least-squares-dy", gh_double2scm (0)); } return SCM_UNSPECIFIED; @@ -471,7 +697,6 @@ Beam::slope_damping (SCM smob) return SCM_UNSPECIFIED; } - /* Prevent interference from stafflines. */ Interval Beam::quantise_interval (Grob *me, Interval pos, Direction quant_dir) @@ -624,6 +849,10 @@ Beam::end_after_line_breaking (SCM smob) return SCM_UNSPECIFIED; } +/* + Calculate the Y position of the stem-end, given the Y-left, Y-right + in POS, and for stem S. + */ Real Beam::calc_stem_y_f (Grob *me, Item* s, Interval pos) { @@ -959,6 +1188,7 @@ Beam::stem_beams (Grob *me, Item *here, Item *next, Item *prev, Real dydx) return leftbeams; } + MAKE_SCHEME_CALLBACK (Beam, brew_molecule, 1); SCM Beam::brew_molecule (SCM smob) @@ -1004,6 +1234,23 @@ Beam::brew_molecule (SCM smob) ->get_bound (LEFT)->relative_coordinate (0, X_AXIS), X_AXIS); + if (0) + { + /* + This code prints the demerits for each beam. Perhaps this + should be switchable for those who want to twiddle with the + parameters. + */ + SCM dem = me->get_grob_property ("quant-score"); + Real s = gh_scm2double (dem); + String str = to_str (s); + + SCM properties = Font_interface::font_alist_chain (me); + + Molecule tm = Text_item::text2molecule (me, gh_str02scm (str.ch_C()), properties); + mol.add_at_edge (Y_AXIS, UP, tm, 5.0); + } + return mol.smobbed_copy (); } diff --git a/lily/gourlay-breaking.cc b/lily/gourlay-breaking.cc index 96728b602a..b61a750562 100644 --- a/lily/gourlay-breaking.cc +++ b/lily/gourlay-breaking.cc @@ -207,9 +207,15 @@ Gourlay_breaking::combine_demerits (Column_x_positions const &prev, } } +#if 1 + /* + Q: do want globally non-cramped lines, or locally equally cramped lines. + */ Real demerit = abs (this_one.force_f_) + abs (prev.force_f_ - this_one.force_f_) + break_penalties; - +#else + Real demerit = abs (this_one.force_f_) + break_penalties; +#endif if (!this_one.satisfies_constraints_b_) { diff --git a/lily/include/beam.hh b/lily/include/beam.hh index c0c7c28933..86c539d8ff 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -35,7 +35,12 @@ public: DECLARE_SCHEME_CALLBACK (check_concave, (SCM)); DECLARE_SCHEME_CALLBACK (slope_damping, (SCM)); DECLARE_SCHEME_CALLBACK (quantise_position, (SCM)); - + DECLARE_SCHEME_CALLBACK (new_quanting, (SCM)); + DECLARE_SCHEME_CALLBACK (score_slopes_dy, (SCM, SCM,SCM)); + DECLARE_SCHEME_CALLBACK (score_stem_lengths, (SCM, SCM,SCM)); + DECLARE_SCHEME_CALLBACK (score_forbidden_quants, (SCM, SCM,SCM)); + + static Molecule stem_beams (Grob*,Item *here, Item *next, Item *prev, Real dydx); diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index d4ea1f8192..a5d1b283aa 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -219,10 +219,12 @@ typedef SCM (*Scheme_function_unknown) (); typedef SCM (*Scheme_function_0) (); typedef SCM (*Scheme_function_1) (SCM); typedef SCM (*Scheme_function_2) (SCM,SCM); +typedef SCM (*Scheme_function_3) (SCM,SCM, SCM); #else typedef SCM (*Scheme_function_0) (...); typedef SCM (*Scheme_function_1) (...); typedef SCM (*Scheme_function_2) (...); +typedef SCM (*Scheme_function_3) (...); #endif #define DECLARE_SCHEME_CALLBACK(NAME,ARGS) \ diff --git a/lily/include/stem-info.hh b/lily/include/stem-info.hh index 25c0a8eec2..d4496a442d 100644 --- a/lily/include/stem-info.hh +++ b/lily/include/stem-info.hh @@ -12,6 +12,11 @@ #include "real.hh" +/* + Parameters for a stem, (multiply with stemdirection, to get real values + for a downstem.) + + */ struct Stem_info { Real idealy_f_; diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index f6a36eaa48..fa75e433a7 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -317,9 +317,10 @@ void Simple_spacer::solve (Column_x_positions *positions) const { positions->force_f_ = force_f_; - if (compression_penalty_b_ && (force_f_ < 0)) + if ((force_f_ < 0)) { - + positions->force_f_ *= 1.3; + if (compression_penalty_b_) positions->force_f_ *= 2; // hmm. } diff --git a/lily/stem.cc b/lily/stem.cc index e69de92f54..3268f31bca 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -660,6 +660,19 @@ Stem::beam_l (Grob*me) Stem_info Stem::calc_stem_info (Grob*me) { + SCM scm_info = me->get_grob_property ("stem-info"); + + if (gh_pair_p (scm_info )) + { + Stem_info si ; + + si.idealy_f_ = gh_scm2double (gh_car (scm_info)); + si.maxy_f_ = gh_scm2double (gh_cadr (scm_info)); + si.miny_f_ = gh_scm2double (gh_caddr (scm_info)); + + return si; + } + Grob * beam = beam_l (me); Direction beam_dir = Directional_element_interface::get (beam); @@ -715,7 +728,7 @@ Stem::calc_stem_info (Grob*me) info.idealy_f_ += thick + (multiplicity - 1) * interbeam_f; } info.miny_f_ = info.idealy_f_; - info.maxy_f_ = INT_MAX; + info.maxy_f_ = 1000; // INT_MAX; info.idealy_f_ += stem_length; info.miny_f_ += minimum_length; @@ -749,7 +762,7 @@ Stem::calc_stem_info (Grob*me) { info.idealy_f_ -= thick; info.maxy_f_ = info.idealy_f_; - info.miny_f_ = -INT_MAX; + info.miny_f_ = - 1000 ; // INT_MAX; info.idealy_f_ -= stem_length; info.maxy_f_ -= minimum_length; @@ -770,6 +783,12 @@ Stem::calc_stem_info (Grob*me) info.miny_f_ += interstaff_f; info.maxy_f_ += interstaff_f ; + me->set_grob_property ("stem-info", + scm_list_n (gh_double2scm (info.idealy_f_), + gh_double2scm (info.maxy_f_ ), + gh_double2scm (info.miny_f_), + SCM_UNDEFINED)); + return info; } diff --git a/scm/beam.scm b/scm/beam.scm index 92da1b0b96..4ab5e2eb4b 100644 --- a/scm/beam.scm +++ b/scm/beam.scm @@ -59,7 +59,7 @@ (define (default-left-beam-pos-quants beam multiplicity dir dy staff-line) (default-beam-pos-quants beam multiplicity 1 staff-line)) - +;; (define (foo beam multiplicity dir dy staff-line) (let* ((beam-straddle 0) (thick (ly-get-grob-property beam 'thickness)) @@ -83,7 +83,7 @@ (define (default-right-beam-pos-quants beam multiplicity dir dy staff-line) (default-beam-pos-quants beam multiplicity 1 staff-line)) - +;; (define (foo beam multiplicity dir dy staff-line) (let* ((beam-straddle 0) (thick (ly-get-grob-property beam 'thickness)) diff --git a/scm/grob-description.scm b/scm/grob-description.scm index c583c4c7cf..d6e3d431a2 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -103,7 +103,8 @@ (position-callbacks . (,Beam::least_squares ,Beam::check_concave ,Beam::slope_damping - ,Beam::quantise_position)) + ,Beam::new_quanting + )) (thickness . 0.48) ; in staff-space (before-line-breaking-callback . ,Beam::before_line_breaking) @@ -120,6 +121,11 @@ (space-function . ,default-beam-space-function) (damping . 1) (auto-knee-gap . 7) + (font-name . "cmr10") + (quant-score-functions . (,Beam::score_forbidden_quants + ,Beam::score_slopes_dy + ,Beam::score_stem_lengths + )) (meta . ,(grob-description beam-interface)) )) @@ -707,7 +713,7 @@ . ( (molecule-callback . ,Staff_symbol::brew_molecule) (staff-space . 1.0) - (line-count . 15) + (line-count . 5) (layer . 0) (meta . ,(grob-description staff-symbol-interface )) )) -- 2.39.2