From: Jan Nieuwenhuizen Date: Sun, 12 Aug 2001 00:53:54 +0000 (+0200) Subject: patch::: 1.5.4.jcn4 X-Git-Tag: release/1.5.5~2 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=54404c570a48ddf9772c5ca64a154d0c0149e61e;p=lilypond.git patch::: 1.5.4.jcn4 1.5.4.jcn4 --- diff --git a/CHANGES b/CHANGES index d6b0577d38..ad19fd996e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ -1.5.4.jcn3 +1.5.4.jcn4 ========== +* New_spacing_spanner: revised spacing generation. + * Spelling fixes, notably staffs->staves, except for ChangeLogs. * Removed `Default' from accidental comment names. diff --git a/VERSION b/VERSION index a05fd3fda4..fead2c56c1 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 PATCH_LEVEL=4 -MY_PATCH_LEVEL=jcn3 +MY_PATCH_LEVEL=jcn4 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/flower/include/rational.hh b/flower/include/rational.hh index 270ee56341..ab4a3d41cf 100644 --- a/flower/include/rational.hh +++ b/flower/include/rational.hh @@ -44,8 +44,8 @@ public: Rational div_rat (Rational) const; Rational mod_rat (Rational) const; void negate (); - operator bool () const; - operator int () const; + // operator bool () const; + int to_int () const; operator double () const; Rational operator - () const; /** diff --git a/flower/rational.cc b/flower/rational.cc index 5c3c8c5cbd..d5e679a9e9 100644 --- a/flower/rational.cc +++ b/flower/rational.cc @@ -12,16 +12,6 @@ #include "string-convert.hh" #include "libc-extension.hh" -Rational::operator bool () const -{ - return sign_; -} - -Rational::operator int () const -{ - return sign_ * num_ / den_; -} - Rational::operator double () const { return (double)sign_ * num_ / den_; diff --git a/input/regression/stem-spacing.ly b/input/regression/stem-spacing.ly index 989c43c530..788da4fa70 100644 --- a/input/regression/stem-spacing.ly +++ b/input/regression/stem-spacing.ly @@ -5,7 +5,9 @@ texidoc=" In a limited number of cases, LilyPond corrects for optical spacing effects. In this example, space for opposite pointed stems is adjuste " + } + \score { \context Voice \notes\relative c { @@ -15,5 +17,18 @@ effects. In this example, space for opposite pointed stems is adjuste \paper { linewidth=-1.0 } - \midi { } } + +\score { + \context Voice \notes\relative c { + + \time 12/4 c''4 c c c a f' f, a + + } + \paper { + linewidth=-1.0 + \translator { \ScoreContext + SpacingSpanner \override #'stem-spacing-correction = #0.0 + } } +} + \ No newline at end of file diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 781f03393f..fdd0f1e633 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -117,7 +117,7 @@ Auto_beam_engraver::test_moment (Direction dir, Moment test_mom) function = gh_list (ly_symbol2scm ("end"), SCM_UNDEFINED); Moment one_beat = *unsmob_moment (get_property ("beatLength")); - int num = *unsmob_moment (get_property ("measureLength")) / one_beat; + int num = int ((*unsmob_moment (get_property ("measureLength")) / one_beat).main_part_); int den = one_beat.den (); SCM time = gh_list (gh_int2scm (num), gh_int2scm (den), SCM_UNDEFINED); @@ -163,7 +163,7 @@ Auto_beam_engraver::test_moment (Direction dir, Moment test_mom) moment = * unsmob_moment (gh_cdr (m)); Rational r; - if (moment) + if (moment.to_bool ()) { /* Ugh? measurePosition can be negative, when \partial We may have to fix this elsewhere (timing translator) diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc index 48268f7a0d..84646867d9 100644 --- a/lily/bar-number-engraver.cc +++ b/lily/bar-number-engraver.cc @@ -49,7 +49,7 @@ Bar_number_engraver::create_grobs () Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); if (gh_number_p (bn) && - !mp && now_mom () > Moment (0)) + !mp.to_bool () && now_mom () > Moment (0)) { create_items (); diff --git a/lily/chord-tremolo-iterator.cc b/lily/chord-tremolo-iterator.cc index ea1d410b6b..1cfbc590d3 100644 --- a/lily/chord-tremolo-iterator.cc +++ b/lily/chord-tremolo-iterator.cc @@ -39,7 +39,7 @@ Chord_tremolo_iterator::Chord_tremolo_iterator (Chord_tremolo_iterator const &sr void Chord_tremolo_iterator::process (Moment m) { - if (!m) + if (!m.to_bool () ) { Music_iterator *yeah = try_music (music_l ()); if (yeah) diff --git a/lily/folded-repeat-iterator.cc b/lily/folded-repeat-iterator.cc index 3012c66429..18cfe09204 100644 --- a/lily/folded-repeat-iterator.cc +++ b/lily/folded-repeat-iterator.cc @@ -71,7 +71,7 @@ Folded_repeat_iterator::construct_children () void Folded_repeat_iterator::process (Moment m) { - if (!m) + if (!m.to_bool () ) { bool success = try_music (music_l ()); if (!success) diff --git a/lily/include/moment.hh b/lily/include/moment.hh index a882bb0986..9a19370e4e 100644 --- a/lily/include/moment.hh +++ b/lily/include/moment.hh @@ -39,8 +39,8 @@ public: Rational grace_part_; void set_infinite (int k); - - operator bool (); + + bool to_bool () const; int den () const; int num () const; /* diff --git a/lily/include/new-spacing-spanner.hh b/lily/include/new-spacing-spanner.hh new file mode 100644 index 0000000000..0137a5c8a1 --- /dev/null +++ b/lily/include/new-spacing-spanner.hh @@ -0,0 +1,30 @@ +/* + spacing-spanner.hh -- declare New_spacing_spanner + + source file of the GNU LilyPond music typesetter + + (c) 1999--2001 Han-Wen Nienhuys + + */ + +#ifndef SPACING_SPANNER_HH +#define SPACING_SPANNER_HH + +#include "spanner.hh" +#include "spring.hh" + +class New_spacing_spanner +{ +public: + static void set_interface (Grob*); + static void do_measure (Grob*,Link_array const &) ; + static void stretch_to_regularity (Grob*, Array *, Link_array const &); + DECLARE_SCHEME_CALLBACK (set_springs, (SCM )); + static Real stem_dir_correction (Grob*,Grob*,Grob*) ; + static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ; + static Real note_spacing (Grob*,Grob*,Grob*,Moment) ; + static Real get_duration_space (Grob*,Moment dur, Moment shortest) ; +}; + +#endif /* SPACING_SPANNER_HH */ + diff --git a/lily/local-key-engraver.cc b/lily/local-key-engraver.cc index fb491fdf4c..ed71c53377 100644 --- a/lily/local-key-engraver.cc +++ b/lily/local-key-engraver.cc @@ -277,7 +277,7 @@ Local_key_engraver::process_music () daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); last_keysig_ = sig; } - else if (!mp) + else if (!mp.to_bool () ) { if (!to_boolean (get_property ("noResetKey"))) daddy_trans_l_->set_property ("localKeySignature", ly_deep_copy (sig)); diff --git a/lily/midi-def.cc b/lily/midi-def.cc index 20174ca73f..6f3a2cd642 100644 --- a/lily/midi-def.cc +++ b/lily/midi-def.cc @@ -24,7 +24,7 @@ Midi_def::get_tempo_i (Moment one_beat_mom) { Moment w = *unsmob_moment (scope_p_->scm_elem ("whole-in-seconds")); Moment wholes_per_min = Moment (60) /w; - int beats_per_min = wholes_per_min / one_beat_mom; + int beats_per_min = int ((wholes_per_min / one_beat_mom).main_part_); return int (beats_per_min); } diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 078dada743..17548174b4 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -23,7 +23,14 @@ Midi_note_event::Midi_note_event () int compare (Midi_note_event const& left, Midi_note_event const& right) { - return sign (left.key - right.key); + Moment m = (left.key - right.key); + + if (m<0) + return -1; + else if (m > 0) + return 1; + else + return 0; } Midi_walker::Midi_walker (Audio_staff* audio_staff_l, Midi_track* track_l) @@ -144,7 +151,7 @@ Midi_walker::process () //midi_p->channel_i_ = track_l_->number_i_; if (Midi_note* note_p = dynamic_cast (midi_p)) { - if (note_p->length_mom ()) + if (note_p->length_mom ().to_bool ()) do_start_note (note_p); } else diff --git a/lily/moment.cc b/lily/moment.cc index 5a3ff5f8fc..1f7f62e773 100644 --- a/lily/moment.cc +++ b/lily/moment.cc @@ -171,8 +171,8 @@ Moment::den () const { return main_part_.den (); } int Moment::num () const { return main_part_.num (); } - -Moment::operator bool () +bool +Moment::to_bool () const { return main_part_ || grace_part_; } diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index bd66558dad..21c2055324 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -127,7 +127,7 @@ Multi_measure_rest_engraver::stop_translation_timestep () Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); if (mmrest_p_ && (now_mom () >= start_moment_) - && !mp + && !mp.to_bool () && mmrest_p_->get_bound (LEFT) && mmrest_p_->get_bound (RIGHT)) { typeset_grob (mmrest_p_); @@ -160,7 +160,7 @@ Multi_measure_rest_engraver::start_translation_timestep () SCM smp = get_property ("measurePosition"); Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); - if (mmrest_p_ && !mp) + if (mmrest_p_ && !mp.to_bool ()) { lastrest_p_ = mmrest_p_; int cur = gh_scm2int (get_property ("currentBarNumber")); diff --git a/lily/new-spacing-spanner.cc b/lily/new-spacing-spanner.cc new file mode 100644 index 0000000000..009dd0f0aa --- /dev/null +++ b/lily/new-spacing-spanner.cc @@ -0,0 +1,510 @@ +/* + spacing-spanner.cc -- implement Spacing_spanner + + source file of the GNU LilyPond music typesetter + + (c) 1999--2001 Han-Wen Nienhuys + + */ + +#include "new-spacing-spanner.hh" +#include "paper-column.hh" +#include "dimensions.hh" +#include "paper-def.hh" +#include "warn.hh" +#include "paper-score.hh" +#include "line-of-score.hh" +#include "misc.hh" +#include "separation-item.hh" + + +void +New_spacing_spanner::set_interface (Grob*me) +{ + me->set_extent_callback (SCM_EOL, X_AXIS); + me->set_extent_callback (SCM_EOL, Y_AXIS) ; +} + +/* + + The algorithm is partly taken from : + + John S. Gourlay. ``Spacing a Line of Music,'' Technical Report + OSU-CISRC-10/87-TR35, Department of Computer and Information + Science, The Ohio State University, 1987. + + TOO HAIRY. + + TODO: write comments + + */ +void +New_spacing_spanner::do_measure (Grob*me, Link_array const & cols) +{ + Moment shortest; + Moment mean_shortest; + + /* + space as if this duration is present. + */ + Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing")); + shortest.set_infinite (1); + + int n = 0; + for (int i =0 ; i < cols.size (); i++) + { + if (Paper_column::musical_b (cols[i])) + { + Moment *when = unsmob_moment (cols[i]->get_grob_property ("when")); + + /* + ignore grace notes for shortest notes. + */ + if (when && when->grace_part_) + continue; + + SCM st = cols[i]->get_grob_property ("shortest-starter-duration"); + Moment this_shortest = *unsmob_moment (st); + shortest = shortest springs; + + Item * first_col = 0; + Item * last_col = 0; + + for (int i= 0; i < cols.size () - 1; i++) + { + Item * l = dynamic_cast (cols[i]); + + if (!Paper_column::musical_b (l)) + continue ; + + if (!first_col) + first_col = l; + + last_col = l; + int j = i+1; + for (; j < cols.size () -1 ; j++) + if (Paper_column::musical_b (cols[j])) + break ; + + Item * r = dynamic_cast (cols[j]); + Paper_column * lc = dynamic_cast (l); + Paper_column *rc = dynamic_cast (r); + if (!lc || !rc) + continue; + + Real note_space = note_spacing (me,lc, rc, shortest get_grob_property ("arithmetic-multiplier")); + + for (SCM s = lc->get_grob_property ("spacing-sequence"); gh_pair_p (s); s = gh_cdr (s)) + { + Grob *lm = unsmob_grob (gh_caar (s)); + Grob *rm = unsmob_grob (gh_cdar (s)); + + // TODO; configgable. + hinterfleisch += -headwid + Separation_item::my_width (lm)[RIGHT] - + 0.5 * Separation_item::my_width (rm)[LEFT]; + + + /* + UGH: KLUDGE! + */ + + // if (delta_t > Moment (1,32)) + hinterfleisch += stem_dir_correction (me, l, r); + } + + Real stretch_distance = note_space - headwid; + Spring s; + s.distance_f_ = hinterfleisch; + s.strength_f_ = 1 / stretch_distance; + + s.item_l_drul_[LEFT] = l; + s.item_l_drul_[RIGHT] = r; + + s.add_to_cols(); + if (r->find_prebroken_piece (LEFT)) + { + s.item_l_drul_[RIGHT] = r->find_prebroken_piece(LEFT); + s.add_to_cols(); + } + } + + Item * l = dynamic_cast (cols[0])->find_prebroken_piece (RIGHT); + + /* + TODO read different spacing hints from break-alignment. + */ + Spring s; + + Real break_dist = 0.0; + SCM espace = l->get_grob_property ("extra-space"); + if (gh_pair_p (espace)) + break_dist += gh_scm2double (gh_cdr (espace)); + + if (!break_dist) + break_dist = 1.0; + + Real break_stretch = 0.0; + + // todo: naming of "distance" + espace = l->get_grob_property ("stretch-distance"); + if (gh_pair_p (espace)) + break_stretch += gh_scm2double (gh_cdr (espace)); + + if (!break_stretch) + break_stretch = 1.0; + + s.distance_f_ = break_dist; + s.strength_f_ = 1/break_stretch; + s.item_l_drul_[LEFT] = l; + s.item_l_drul_[RIGHT] = first_col; + + s.add_to_cols (); + + s.item_l_drul_[LEFT] = dynamic_cast(cols[0]); + s.add_to_cols (); +} + +/* + Look at COLS, searching for columns that have 'regular-distance-to + set. A sequence of columns that have this property set should have + an equal distance (an equispaced run). Extract the projected + distance from SPRINGS, and scale SPRINGS for the equispaced run, to the + widest space necessary. + + + TODO: + + -- inefficient code; maybe it is easier to twiddle with the springs + after they've become grob properties (ie. have their + minimum-distances set) + + -- does not adjust strength field of the springs very well: result + awkward spacing at the start of a line. (?) + + -- will be confused when there are multiple equispaced runs in a measure. + + -- dealing with springs for line breaks is a little tricky; in any + case, we will only space per measure. + + -- we scale to actual distances, not to optical effects. Eg. if the + equispaced run contains optical corrections, then the scaling will + cancel those. + + -- Regular_spacing_engraver doesn't mark the first column of the + next bar, making the space before a barline too short, in this case + + + x<- 16ths--> x(8th) + x(8th) x(8th) <- equispaced run. + +*/ + +void +New_spacing_spanner::stretch_to_regularity (Grob *me, + Array * springs, + Link_array const & cols) +{ + /* + Find the starting column of the run. REGULAR-DISTANCE-TO points + back to a previous column, so we look ahead to find a column + pointing back to the first one. + + */ + Grob * first_regular_spaced_col = 0; + for (int i = 0 ; i < cols.size () && !first_regular_spaced_col; i++) + { + SCM rdt = cols[i]->get_grob_property ("regular-distance-to"); + if (cols.find_l (unsmob_grob (rdt))) + first_regular_spaced_col = unsmob_grob (rdt); + } + for (int i = springs->size (); i-- ;) + springs->elem (i).set_to_cols (); + + int i; + for (i = 0; i < springs->size () + && springs->elem (i).item_l_drul_[RIGHT] != first_regular_spaced_col; + i++) + ; + + + if (i==springs->size ()) + return ; + + Real maxdist = 0.0; + Real dist =0.0; + Grob *last_col = first_regular_spaced_col; + Grob *last_regular_spaced_col = first_regular_spaced_col; + + + /* + find the max distance for this run. + */ + for (int j = i; j < springs->size (); j++) + { + Spring *s = &(springs->elem_ref (j)); + if (s->item_l_drul_[LEFT] != last_col) + continue; + + dist += s->distance_f_; + + last_col = s->item_l_drul_[RIGHT]; + SCM rdt = last_col->get_grob_property ("regular-distance-to"); + if (unsmob_grob (rdt) == last_regular_spaced_col) + { + maxdist = maxdist >? dist; + dist = 0.0; + last_regular_spaced_col = last_col; + } + + } + + /* + Scale the springs + */ + dist =0.0; + last_col = first_regular_spaced_col; + last_regular_spaced_col = first_regular_spaced_col; + for (int j = i; j < springs->size (); j++) + { + Spring *s = &springs->elem_ref (j); + if (s->item_l_drul_[LEFT] != last_col) + continue; + dist += s->distance_f_; + + last_col = s->item_l_drul_[RIGHT]; + SCM rdt = last_col->get_grob_property ("regular-distance-to"); + if (unsmob_grob (rdt) == last_regular_spaced_col) + { + do { + springs->elem_ref (i).distance_f_ *= maxdist / dist; + springs->elem_ref (i).strength_f_ *= dist / maxdist; + } while (i++ < j); + last_regular_spaced_col = last_col; + dist =0.0; + } + } +} + +/** + Do something if breakable column has no spacing hints set. + */ +Real +New_spacing_spanner::default_bar_spacing (Grob*me, Grob *lc, Grob *rc, + Moment shortest) +{ + Real symbol_distance = lc->extent (lc,X_AXIS)[RIGHT] ; + Real durational_distance = 0; + Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc); + + /* + ugh should use shortest_playing distance + */ + if (delta_t.to_bool ()) + { + durational_distance = get_duration_space (me, delta_t, shortest); + } + + return symbol_distance >? durational_distance; +} + + +/** + Get the measure wide ant for arithmetic spacing. + + @see + John S. Gourlay. ``Spacing a Line of Music,'' Technical Report + OSU-CISRC-10/87-TR35, Department of Computer and Information Science, + The Ohio State University, 1987. + + */ +Real +New_spacing_spanner::get_duration_space (Grob*me, Moment d, Moment shortest) +{ + Real log = log_2 (shortest.main_part_); + Real k = gh_scm2double (me->get_grob_property ("arithmetic-basicspace")) + - log; + + Rational compdur = d.main_part_ + d.grace_part_ /Rational (3); + + return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier")); +} + + +Real +New_spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, + Moment shortest) +{ + Moment shortest_playing_len = 0; + SCM s = lc->get_grob_property ("shortest-playing-duration"); + + // SCM s = lc->get_grob_property ("mean-playing-duration"); + if (unsmob_moment (s)) + shortest_playing_len = *unsmob_moment (s); + + if (! shortest_playing_len.to_bool ()) + { + programming_error ("can't find a ruling note at " + Paper_column::when_mom (lc).str ()); + shortest_playing_len = 1; + } + + if (! shortest.to_bool ()) + { + programming_error ("no minimum in measure at " + Paper_column::when_mom (lc).str ()); + shortest = 1; + } + Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc); + Real dist = get_duration_space (me, shortest_playing_len, shortest); + + + /* + ugh: 0.1 is an arbitrary distance. + */ + dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_) + + 0.1 * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_); + + + + Moment *lm = unsmob_moment (lc->get_grob_property ("when")); + Moment *rm = unsmob_moment (rc->get_grob_property ("when")); + + if (lm && rm) + { + if (lm->grace_part_ && rm->grace_part_) + dist *= 0.5; + else if (!rm->grace_part_ && lm->grace_part_) + dist *= 0.7; + } + + + return dist; +} + + +/** + Correct for optical illusions. See [Wanske] p. 138. The combination + up-stem + down-stem should get extra space, the combination + down-stem + up-stem less. + + This should be more advanced, since relative heights of the note + heads also influence required correction. + + Also might not work correctly in case of multi voices or staff + changing voices + + TODO: lookup correction distances? More advanced correction? + Possibly turn this off? + + TODO: have to check wether the stems are in the same staff. + + This routine reads the DIR-LIST property of both its L and R arguments. */ +Real +New_spacing_spanner::stem_dir_correction (Grob*me, Grob*l, Grob*r) +{ + SCM dl = l->get_grob_property ("dir-list"); + SCM dr = r->get_grob_property ("dir-list"); + + if (scm_ilength (dl) != 1 || scm_ilength (dr) != 1) + return 0.; + + dl = gh_car (dl); + dr = gh_car (dr); + + assert (gh_number_p (dl) && gh_number_p (dr)); + int d1 = gh_scm2int (dl); + int d2 = gh_scm2int (dr); + + if (d1 == d2) + return 0.0; + + + Real correction = 0.0; + Real ssc = gh_scm2double (me->get_grob_property ("stem-spacing-correction")); + + if (d1 && d2 && d1 * d2 == -1) + { + correction = d1 * ssc; + } + else + programming_error ("Stem directions not set correctly for optical correction"); + return correction; +} + + +MAKE_SCHEME_CALLBACK (New_spacing_spanner, set_springs,1); +SCM +New_spacing_spanner::set_springs (SCM smob) +{ + Grob *me = unsmob_grob (smob); + Link_array all (me->pscore_l_->line_l_->column_l_arr ()) ; + + int j = 0; + + for (int i = 1; i < all.size (); i++) + { + Grob *sc = all[i]; + if (Item::breakable_b (sc)) + { + Link_array measure (all.slice (j, i+1)); + do_measure (me, measure); + j = i; + } + } + + /* + farewell, cruel world + */ + me->suicide (); + return SCM_UNSPECIFIED; +} + + + +/* + maximum-duration-for-spacing +From: bf250@freenet.carleton.ca (John Sankey) +To: gnu-music-discuss@gnu.org +Subject: note spacing suggestion +Date: Mon, 10 Jul 2000 11:28:03 -0400 (EDT) + +Currently, Lily spaces notes by starting with a basic distance, +arithmetic_multiplier, which it applies to the minimum duration note +of the bar. Then she adds a logarithmic increment, scaled from +arithmetic_basicspace, for longer notes. (Then, columns are aligned +and justified.) Fundamentally, this matches visual spacing to musical +weight and works well. + +A lot of the time in music, I see a section basically in melodic +notes that occasionally has a rapid ornamental run (scale). So, there +will be a section in 1/4 notes, then a brief passage in 1/32nds, then +a return to long notes. Currently, Lily gives the same horizontal +space to the 1/32nd notes in their bar (even if set in small size as +is commonly done for cadenzii) as she gives to 1/4 notes in bars +where 1/4 note is the minimum duration. The resulting visual weight +does not match the musical weight over the page. + +Looking at the music I am typesetting, I feel that Lily's spacing +could be significantly improved if, with no change in the basic +method used, arithmetic_multiplier could be applied referred to the +same duration throughout a piece. Of course, the current method +should be retained for those who have already set music in it, so I +suggest a property called something like arithmetic_base=16 to fix +1/16 duration as the reference for arithmetic_multiplier; the default +would be a dynamic base is it is now. + +Does anyone else feel that this would be a useful improvement for +their music? (Of course, if arithmetic_multiplier became a regular +property, this could be used to achieve a similar result by +tweaking.) + + */ diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 87a5bff3f2..69d16f6c67 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -21,6 +21,7 @@ class Note_heads_engraver : public Engraver { Link_array note_p_arr_; + Link_array dot_p_arr_; Link_array note_req_l_arr_; Moment note_end_mom_; diff --git a/lily/note-performer.cc b/lily/note-performer.cc index c2665f5495..c5c522405a 100644 --- a/lily/note-performer.cc +++ b/lily/note-performer.cc @@ -85,7 +85,8 @@ Note_performer::stop_translation_timestep () for (int i=0; i < note_p_arr_.size (); i++) { Audio_note* n = note_p_arr_[i]; - if (Moment m= n->delayed_until_mom_) + Moment m= n->delayed_until_mom_; + if (m.to_bool ()) { global_l->add_moment_to_process (m); delayed_p_arr_.push (n); diff --git a/lily/percent-repeat-iterator.cc b/lily/percent-repeat-iterator.cc index 3d1120981b..48a81ebe4d 100644 --- a/lily/percent-repeat-iterator.cc +++ b/lily/percent-repeat-iterator.cc @@ -44,7 +44,7 @@ Percent_repeat_iterator::construct_children () void Percent_repeat_iterator::process (Moment m) { - if (!m) + if (!m.to_bool ()) { Music_iterator *yeah = try_music (music_l ()); if (yeah) diff --git a/lily/separating-group-spanner.cc b/lily/separating-group-spanner.cc index bc5e030994..d102e35bdb 100644 --- a/lily/separating-group-spanner.cc +++ b/lily/separating-group-spanner.cc @@ -96,6 +96,10 @@ Separating_group_spanner::set_spacing_rods (SCM smob) find_rods (rb, gh_cdr (s)); } +#if 0 + /* + TODO; restore this. + */ /* We've done our job, so we get lost. */ @@ -110,6 +114,7 @@ Separating_group_spanner::set_spacing_rods (SCM smob) it->suicide (); } me->suicide (); +#endif return SCM_UNSPECIFIED ; } diff --git a/lily/separating-line-group-engraver.cc b/lily/separating-line-group-engraver.cc index 73e0f2e160..5ac8910896 100644 --- a/lily/separating-line-group-engraver.cc +++ b/lily/separating-line-group-engraver.cc @@ -18,7 +18,14 @@ class Separating_line_group_engraver : public Engraver { protected: Item * break_malt_p_; - Item * nobreak_malt_p_; + Item * musical_malt_p_; + + /* + malt_p_ : we used to have a Single_malt_grouping_item + + */ + Item * last_step_musical_malt_p_; + Spanner * sep_span_p_; virtual void acknowledge_grob (Grob_info); @@ -32,9 +39,10 @@ public: Separating_line_group_engraver::Separating_line_group_engraver () { + last_step_musical_malt_p_ = 0; sep_span_p_ = 0; break_malt_p_ = 0; - nobreak_malt_p_ =0; + musical_malt_p_ =0; } void @@ -68,7 +76,7 @@ Separating_line_group_engraver::acknowledge_grob (Grob_info i) bool ib =Item::breakable_b (it); Item *&p_ref_ (ib ? break_malt_p_ - : nobreak_malt_p_); + : musical_malt_p_); if (!p_ref_) { @@ -92,12 +100,26 @@ Separating_line_group_engraver::stop_translation_timestep () typeset_grob (break_malt_p_); break_malt_p_ =0; } - if (nobreak_malt_p_) + if (musical_malt_p_) { - Separating_group_spanner::add_spacing_unit (sep_span_p_, nobreak_malt_p_); - typeset_grob (nobreak_malt_p_); - nobreak_malt_p_ =0; + Separating_group_spanner::add_spacing_unit (sep_span_p_, musical_malt_p_); + + if (last_step_musical_malt_p_) + { + Paper_column *col = + last_step_musical_malt_p_->column_l(); + SCM newtup = gh_cons (last_step_musical_malt_p_->self_scm (), + musical_malt_p_->self_scm ()); + col->set_grob_property ("spacing-sequence", + gh_cons (newtup, + col->get_grob_property ("spacing-sequence"))); + } + + typeset_grob (musical_malt_p_); } + last_step_musical_malt_p_ = musical_malt_p_; + musical_malt_p_ =0; + } diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index 2b9bbdde83..0340596ad3 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -189,7 +189,9 @@ Simple_spacer::add_columns (Link_array cols) } else { - programming_error ("No spring between adjacent columns"); + programming_error (_f("No spring between column %d and next one", + Paper_column::rank_i (cols[i]) + )); desc.hooke_f_ = 1.0; desc.ideal_f_ = default_space_f_; } diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index edeb8ebb9e..198080648d 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -111,7 +111,7 @@ Spacing_engraver::stop_translation_timestep () for (int i=0; i < playing_durations_.size (); i++) { Moment m = (playing_durations_[i].info_.req_l_)->length_mom (); - if (m) + if (m.to_bool ()) { shortest_playing = shortest_playing length_mom (); - if (m) + if (m.to_bool ()) starter = starter get_grob_property ("arithmetic-basicspace")) - log; - - return (log_2 (d) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier")); + + Rational compdur = d.main_part_ + d.grace_part_ / Rational (3); + return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier")); } @@ -450,13 +451,13 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, if (unsmob_moment (s)) shortest_playing_len = *unsmob_moment (s); - if (! shortest_playing_len) + if (! shortest_playing_len.to_bool ()) { programming_error ("can't find a ruling note at " + Paper_column::when_mom (lc).str ()); shortest_playing_len = 1; } - if (! shortest) + if (! shortest.to_bool ()) { programming_error ("no minimum in measure at " + Paper_column::when_mom (lc).str ()); shortest = 1; diff --git a/lily/span-dynamic-performer.cc b/lily/span-dynamic-performer.cc index 7276bd6c70..f76f7a8876 100644 --- a/lily/span-dynamic-performer.cc +++ b/lily/span-dynamic-performer.cc @@ -153,8 +153,8 @@ Span_dynamic_performer::stop_translation_timestep () for (int i=0; i < finished_dynamic_tuple_arr_.size (); i++) { Audio_dynamic_tuple* a = &finished_dynamic_tuple_arr_[i]; - Real volume = start_volume + dv * (Real) (a->mom_ - start_mom) - / (Real)dt; + Real volume = start_volume + dv * (Real) (a->mom_ - start_mom).main_part_ + / (Real)dt.main_part_; a->audio_l_->volume_ = volume; } finished_dynamic_tuple_arr_.clear (); diff --git a/lily/tempo-performer.cc b/lily/tempo-performer.cc index 53ca7c056c..f24dd0f8aa 100644 --- a/lily/tempo-performer.cc +++ b/lily/tempo-performer.cc @@ -51,9 +51,9 @@ Tempo_performer::create_audio_elements () SCM met = tempo_req_l_->get_mus_property ("metronome-count"); Duration *d = unsmob_duration (tempo_req_l_->get_mus_property ("duration")); - audio_p_ = new Audio_tempo (d->length_mom () / - Moment (1, 4) - * Moment (gh_scm2int (met))); + Rational r = (d->length_mom () / Moment (1, 4) * Moment (gh_scm2int (met))).main_part_; + + audio_p_ = new Audio_tempo (int (r)); Audio_element_info info (audio_p_, tempo_req_l_); announce_element (info); diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index b666f766bd..df242b03ff 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -16,7 +16,7 @@ void Time_scaled_music_iterator::process (Moment m) { - if (!m) + if (!m.to_bool ()) { Music_iterator *yeah = try_music (music_l ()); if (yeah) diff --git a/lily/timing-translator.cc b/lily/timing-translator.cc index dbe365e11c..d90e93cec7 100644 --- a/lily/timing-translator.cc +++ b/lily/timing-translator.cc @@ -141,7 +141,7 @@ Timing_translator::start_translation_timestep () dt = 0; } - if (!dt) + if (!dt.to_bool ()) return; Moment measposp; diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index 65b38e8a48..453d958b37 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -124,7 +124,7 @@ Tuplet_engraver::start_translation_timestep () started_span_p_arr_[i] =0; } - if (tsd) + if (tsd.to_bool ()) span_stop_moments_[i] += tsd.main_part_; } diff --git a/lily/unfolded-repeat-iterator.cc b/lily/unfolded-repeat-iterator.cc index 56c6195aed..73343eee83 100644 --- a/lily/unfolded-repeat-iterator.cc +++ b/lily/unfolded-repeat-iterator.cc @@ -303,7 +303,7 @@ Unfolded_repeat_iterator::add_repeat_command (SCM what) void Unfolded_repeat_iterator::process (Moment m) { - if (!m) + if (!m.to_bool ()) { if (volta_b_) add_repeat_command (ly_symbol2scm ("start-repeat")); diff --git a/scm/grob-description.scm b/scm/grob-description.scm index 916afa7884..a66b6ddadc 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -500,8 +500,11 @@ )) (SpacingSpanner . ( - (spacing-procedure . ,Spacing_spanner::set_springs) + (spacing-procedure . ,New_spacing_spanner::set_springs) (stem-spacing-correction . 0.5) + + + ;; TODO: change naming -- unintuitive (arithmetic-basicspace . 2.0) (arithmetic-multiplier . ,(* 0.9 1.32)) ;; assume that notes at least this long are present. diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index a20fc98a6a..ae582e5b88 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -273,7 +273,7 @@ itself. Return value is ignored.") (grob-property-description 'stem-end-position number? "Where does the stem end (the end is opposite to the support-head.") (grob-property-description 'stem-length number? "length of stem.") (grob-property-description 'stem-shorten list? "shorten stems in forced directions given flag multiplicity.") -(grob-property-description 'stem-spacing-correction number? "optical correction amount.") +(grob-property-description 'stem-spacing-correction number? "optical correction amount. [TODO: doco] ") (grob-property-description 'stems list? "list of stem objects, corresponding to the notes that the arpeggio has to be before.") (grob-property-description 'stretch-distance number-pair? "pair of distances.") (grob-property-description 'style symbol? "a string determining what style of glyph is typeset. Valid choices depend on the function that is reading this property. .")