OLD | NEW |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 Jan Nieuwenhuizen <janneke@gnu.org> | 5 Jan Nieuwenhuizen <janneke@gnu.org> |
6 | 6 |
7 LilyPond is free software: you can redistribute it and/or modify | 7 LilyPond is free software: you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation, either version 3 of the License, or | 9 the Free Software Foundation, either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "libc-extension.hh" | 38 #include "libc-extension.hh" |
39 #include "main.hh" | 39 #include "main.hh" |
40 #include "note-head.hh" | 40 #include "note-head.hh" |
41 #include "output-def.hh" | 41 #include "output-def.hh" |
42 #include "pointer-group-interface.hh" | 42 #include "pointer-group-interface.hh" |
43 #include "spanner.hh" | 43 #include "spanner.hh" |
44 #include "staff-symbol-referencer.hh" | 44 #include "staff-symbol-referencer.hh" |
45 #include "stencil.hh" | 45 #include "stencil.hh" |
46 #include "stem.hh" | 46 #include "stem.hh" |
47 #include "warn.hh" | 47 #include "warn.hh" |
| 48 #include "string-convert.hh" |
48 | 49 |
49 Real | 50 Real |
50 get_detail (SCM alist, SCM sym, Real def) | 51 get_detail (SCM alist, SCM sym, Real def) |
51 { | 52 { |
52 SCM entry = scm_assq (sym, alist); | 53 SCM entry = scm_assq (sym, alist); |
53 | 54 |
54 if (scm_is_pair (entry)) | 55 if (scm_is_pair (entry)) |
55 return robust_scm2double (scm_cdr (entry), def); | 56 return robust_scm2double (scm_cdr (entry), def); |
56 return def; | 57 return def; |
57 } | 58 } |
58 | 59 |
59 void | 60 void |
60 Beam_quant_parameters::fill (Grob *him) | 61 Beam_quant_parameters::fill (Grob *him) |
61 { | 62 { |
62 SCM details = him->get_property ("details"); | 63 SCM details = him->get_property ("details"); |
63 | 64 |
64 // General | 65 // General |
65 BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); | 66 BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); |
66 REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); | 67 REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); |
67 | 68 |
68 // forbidden quants | 69 // forbidden quants |
69 SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-d
emerit"), 10.0); | 70 SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-d
emerit"), 10.0) |
| 71 // For stems that are non-standard, the forbidden beam quanting |
| 72 // doesn't really work, so decrease their importance. |
| 73 * exp(- 8*fabs (1.0 - robust_scm2double(him->get_property ("length-fraction"
), 1.0))); |
70 STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-
demerit-factor"), 5); | 74 STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-
demerit-factor"), 5); |
71 HORIZONTAL_INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("horizont
al-inter-quant"), 500); | 75 HORIZONTAL_INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("horizont
al-inter-quant"), 500); |
72 | 76 |
73 STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-l
imit-penalty"), 5000); | 77 STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-l
imit-penalty"), 5000); |
74 DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direc
tion-penalty"), 800); | 78 DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direc
tion-penalty"), 800); |
75 HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-p
enalty"), 20); | 79 HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-p
enalty"), 20); |
76 MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direct
ion-factor"), 400); | 80 MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direct
ion-factor"), 400); |
77 IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor")
, 10); | 81 IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor")
, 10); |
78 ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope
"), 0.02); | 82 ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope
"), 0.02); |
79 | 83 |
80 // Collisions | 84 // Collisions |
81 COLLISION_PENALTY = get_detail (details, ly_symbol2scm ("collision-penalty"),
500); | 85 COLLISION_PENALTY = get_detail (details, ly_symbol2scm ("collision-penalty"),
500); |
82 COLLISION_PADDING = get_detail (details, ly_symbol2scm ("collision-padding"),
0.5); | 86 |
| 87 /* For grace notes, beams get scaled down to 80%, but glyphs go down |
| 88 to 63% (magstep -4 for accidentals). To make the padding |
| 89 commensurate with glyph size for grace notes, we take the square |
| 90 of the length fraction, yielding a 64% decrease. |
| 91 */ |
| 92 COLLISION_PADDING = get_detail (details, ly_symbol2scm ("collision-padding"),
0.5) |
| 93 * sqr (robust_scm2double(him->get_property ("length-fraction"), 1.0)); |
83 STEM_COLLISION_FACTOR = get_detail (details, ly_symbol2scm ("stem-collision-fa
ctor"), 0.1); | 94 STEM_COLLISION_FACTOR = get_detail (details, ly_symbol2scm ("stem-collision-fa
ctor"), 0.1); |
84 } | 95 } |
85 | 96 |
86 // Add x if x is positive, add |x|*fac if x is negative. | 97 // Add x if x is positive, add |x|*fac if x is negative. |
87 static Real | 98 static Real |
88 shrink_extra_weight (Real x, Real fac) | 99 shrink_extra_weight (Real x, Real fac) |
89 { | 100 { |
90 return fabs (x) * ((x < 0) ? fac : 1.0); | 101 return fabs (x) * ((x < 0) ? fac : 1.0); |
91 } | 102 } |
92 | 103 |
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 /* | 1194 /* |
1184 TODO: The fixed value SECONDARY_BEAM_DEMERIT is probably flawed: | 1195 TODO: The fixed value SECONDARY_BEAM_DEMERIT is probably flawed: |
1185 because for 32nd and 64th beams the forbidden quants are relatively | 1196 because for 32nd and 64th beams the forbidden quants are relatively |
1186 more important than stem lengths. | 1197 more important than stem lengths. |
1187 */ | 1198 */ |
1188 void | 1199 void |
1189 Beam_scoring_problem::score_forbidden_quants (Beam_configuration *config) const | 1200 Beam_scoring_problem::score_forbidden_quants (Beam_configuration *config) const |
1190 { | 1201 { |
1191 Real dy = config->y.delta (); | 1202 Real dy = config->y.delta (); |
1192 | 1203 |
1193 Real extra_demerit = parameters_.SECONDARY_BEAM_DEMERIT | 1204 Real extra_demerit = |
1194 / max (edge_beam_counts_[LEFT], edge_beam_counts_[RIGHT])
; | 1205 parameters_.SECONDARY_BEAM_DEMERIT |
1195 | 1206 / max (edge_beam_counts_[LEFT], edge_beam_counts_[RIGHT]); |
| 1207 |
1196 Real dem = 0.0; | 1208 Real dem = 0.0; |
1197 Real eps = parameters_.BEAM_EPS; | 1209 Real eps = parameters_.BEAM_EPS; |
1198 | 1210 |
1199 for (LEFT_and_RIGHT (d)) | 1211 for (LEFT_and_RIGHT (d)) |
1200 { | 1212 { |
1201 for (int j = 1; j <= edge_beam_counts_[d]; j++) | 1213 for (int j = 1; j <= edge_beam_counts_[d]; j++) |
1202 { | 1214 { |
1203 Direction stem_dir = edge_dirs_[d]; | 1215 Direction stem_dir = edge_dirs_[d]; |
1204 | 1216 |
1205 /* | 1217 /* |
1206 The 2.2 factor is to provide a little leniency for | 1218 The fudge_factor is to provide a little leniency for |
1207 borderline cases. If we do 2.0, then the upper outer line | 1219 borderline cases. If we do 2.0, then the upper outer line |
1208 will be in the gap of the (2, sit) quant, leading to a | 1220 will be in the gap of the (2, sit) quant, leading to a |
1209 false demerit. | 1221 false demerit. By increasing the fudge factor to 2.2, we |
| 1222 fix this case. |
1210 */ | 1223 */ |
1211 Real gap1 = config->y[d] - stem_dir * ((j - 1) * beam_translation_ + b
eam_thickness_ / 2 - line_thickness_ / 2.2); | 1224 Real fudge_factor = 2.2; |
1212 Real gap2 = config->y[d] - stem_dir * (j * beam_translation_ - beam_th
ickness_ / 2 + line_thickness_ / 2.2); | 1225 Real gap1 = config->y[d] - stem_dir * ((j - 1) * beam_translation_ + b
eam_thickness_ / 2 - line_thickness_ / fudge_factor); |
| 1226 Real gap2 = config->y[d] - stem_dir * (j * beam_translation_ - beam_th
ickness_ / 2 + line_thickness_ / fudge_factor); |
1213 | 1227 |
1214 Interval gap; | 1228 Interval gap; |
1215 gap.add_point (gap1); | 1229 gap.add_point (gap1); |
1216 gap.add_point (gap2); | 1230 gap.add_point (gap2); |
1217 | 1231 |
1218 for (Real k = -staff_radius_; | 1232 for (Real k = -staff_radius_; |
1219 k <= staff_radius_ + eps; k += 1.0) | 1233 k <= staff_radius_ + eps; k += 1.0) |
1220 if (gap.contains (k)) | 1234 if (gap.contains (k)) |
1221 { | 1235 { |
1222 Real dist = min (fabs (gap[UP] - k), fabs (gap[DOWN] - k)); | 1236 Real dist = min (fabs (gap[UP] - k), fabs (gap[DOWN] - k)); |
(...skipping 10 matching lines...) Expand all Loading... |
1233 */ | 1247 */ |
1234 Real fixed_demerit = 0.39; | 1248 Real fixed_demerit = 0.39; |
1235 | 1249 |
1236 dem += extra_demerit | 1250 dem += extra_demerit |
1237 * (fixed_demerit | 1251 * (fixed_demerit |
1238 + (1 - fixed_demerit) * (dist / gap.length ()) * 2); | 1252 + (1 - fixed_demerit) * (dist / gap.length ()) * 2); |
1239 } | 1253 } |
1240 } | 1254 } |
1241 } | 1255 } |
1242 | 1256 |
| 1257 config->add (dem, "Fl"); |
| 1258 dem = 0.0; |
1243 if (max (edge_beam_counts_[LEFT], edge_beam_counts_[RIGHT]) >= 2) | 1259 if (max (edge_beam_counts_[LEFT], edge_beam_counts_[RIGHT]) >= 2) |
1244 { | 1260 { |
1245 Real straddle = 0.0; | 1261 Real straddle = 0.0; |
1246 Real sit = (beam_thickness_ - line_thickness_) / 2; | 1262 Real sit = (beam_thickness_ - line_thickness_) / 2; |
1247 Real inter = 0.5; | 1263 Real inter = 0.5; |
1248 Real hang = 1.0 - (beam_thickness_ - line_thickness_) / 2; | 1264 Real hang = 1.0 - (beam_thickness_ - line_thickness_) / 2; |
1249 | 1265 |
1250 for (LEFT_and_RIGHT (d)) | 1266 for (LEFT_and_RIGHT (d)) |
1251 { | 1267 { |
1252 if (edge_beam_counts_[d] >= 2 | 1268 if (edge_beam_counts_[d] >= 2 |
(...skipping 17 matching lines...) Expand all Loading... |
1270 && fabs (my_modf (config->y[d]) - straddle) < eps) | 1286 && fabs (my_modf (config->y[d]) - straddle) < eps) |
1271 dem += extra_demerit; | 1287 dem += extra_demerit; |
1272 | 1288 |
1273 if (edge_dirs_[d] == DOWN && dy >= eps | 1289 if (edge_dirs_[d] == DOWN && dy >= eps |
1274 && fabs (my_modf (config->y[d]) - straddle) < eps) | 1290 && fabs (my_modf (config->y[d]) - straddle) < eps) |
1275 dem += extra_demerit; | 1291 dem += extra_demerit; |
1276 } | 1292 } |
1277 } | 1293 } |
1278 } | 1294 } |
1279 | 1295 |
1280 config->add (dem, "F"); | 1296 config->add (dem, "Fs"); |
1281 } | 1297 } |
1282 | 1298 |
1283 void | 1299 void |
1284 Beam_scoring_problem::score_collisions (Beam_configuration *config) const | 1300 Beam_scoring_problem::score_collisions (Beam_configuration *config) const |
1285 { | 1301 { |
1286 Real demerits = 0.0; | 1302 Real demerits = 0.0; |
1287 for (vsize i = 0; i < collisions_.size (); i++) | 1303 for (vsize i = 0; i < collisions_.size (); i++) |
1288 { | 1304 { |
1289 Interval collision_y = collisions_[i].y_; | 1305 Interval collision_y = collisions_[i].y_; |
1290 Real x = collisions_[i].x_; | 1306 Real x = collisions_[i].x_; |
1291 | 1307 |
1292 Real center_beam_y = y_at (x, config); | 1308 Real center_beam_y = y_at (x, config); |
1293 Interval beam_y = center_beam_y + collisions_[i].beam_y_; | 1309 Interval beam_y = center_beam_y + collisions_[i].beam_y_; |
1294 | 1310 |
1295 Real dist = infinity_f; | 1311 Real dist = infinity_f; |
1296 if (!intersection (beam_y, collision_y).is_empty ()) | 1312 if (!intersection (beam_y, collision_y).is_empty ()) |
1297 dist = 0.0; | 1313 dist = 0.0; |
1298 else | 1314 else |
1299 dist = min (beam_y.distance (collision_y[DOWN]), | 1315 dist = min (beam_y.distance (collision_y[DOWN]), |
1300 beam_y.distance (collision_y[UP])); | 1316 beam_y.distance (collision_y[UP])); |
1301 | 1317 |
| 1318 ······ |
1302 Real scale_free | 1319 Real scale_free |
1303 = max (parameters_.COLLISION_PADDING - dist, 0.0) | 1320 = max (parameters_.COLLISION_PADDING - dist, 0.0) |
1304 / parameters_.COLLISION_PADDING; | 1321 / parameters_.COLLISION_PADDING; |
1305 demerits | 1322 Real collision_demerit = collisions_[i].base_penalty_ * |
1306 += collisions_[i].base_penalty_ * | |
1307 pow (scale_free, 3) * parameters_.COLLISION_PENALTY; | 1323 pow (scale_free, 3) * parameters_.COLLISION_PENALTY; |
| 1324 |
| 1325 if (collision_demerit > 0) { |
| 1326 demerits += collision_demerit; |
| 1327 } |
1308 } | 1328 } |
1309 | 1329 |
1310 config->add (demerits, "C"); | 1330 config->add (demerits, "C"); |
1311 } | 1331 } |
OLD | NEW |