\grace c8
c4 c4 }
\context Staff = SB { c2 \clef bass
- \grace { [dis8 ( d8] }
+ \grace { [dis8 ( d8] \key es\major }
) c4 c4 }
\context Staff = SC { c2 c4 c4 \bar "|." }
--- /dev/null
+\header {
+texidoc = "A clef can be folded below notes in a different staff, if
+this doesn't disrupt the flow of the notes."
+}
+
+\score { \notes \relative c'' <
+\context Staff = SA { c4 [c16 c c c] c4 c4 }
+ \context Staff = SB { \clef bass c,2 \clef treble c'2 }
+ >
+
+ \paper { linewidth = -1. }
+ }
--- /dev/null
+\header {
+ texidoc = "Grace note spacing. Should be tuned? "
+}
+
+\score {
+ \notes \context Voice \relative c'' { \grace { [c16 d] } c4 }
+ \paper { linewidth =-1. }
+
+}
\version "1.3.148"
\header {
+texidoc = "
When tightly spaced, hinterfleisch -> 0.
Stems may touch the bar lines, opposite stems may touch eachother.
We need a mininum of about a note-width/interline space in these
situations, so that in tightly spaced music all vertical lines
are about equally spaced.
-}
+
+ "
+
+ }
\score {
\notes \relative c''{
r1 e4 f, e' f,
struct Column_x_positions
{
Link_array<Grob> cols_;
+ Link_array<Grob> loose_cols_;
+
Array<Real> config_;
Real force_f_;
bool satisfies_constraints_b_;
{
public:
static void set_interface (Grob*);
- static void do_measure (Grob*,Link_array<Grob> const &) ;
+ static void do_measure (Grob*,Link_array<Grob> *) ;
static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> const &);
static void breakable_column_spacing (Item* l, Item *r);
DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
struct Simple_spacer
{
Array<Spring_description> springs_;
-
+ Link_array<Grob> spaced_cols_;
+ Link_array<Grob> loose_cols_;
Real force_f_;
Real indent_f_;
Real line_len_f_;
}
}
+/*
+ Find the loose columns in POSNS, and drape them around the columns
+ specified in BETWEEN-COLS. */
+void
+set_loose_columns (Line_of_score* which, Column_x_positions const *posns)
+{
+ for (int i = 0; i<posns->loose_cols_.size (); i++)
+ {
+ int divide_over = 1;
+ Item *loose = dynamic_cast<Item*> (posns->loose_cols_[i]);
+ Paper_column* col = dynamic_cast<Paper_column*> (loose);
+
+ if (col->line_l_)
+ continue;
+
+
+ Item * left = 0;
+ Item * right = 0;
+ while (1)
+ {
+
+ SCM between = loose->get_grob_property ("between-cols");
+ if (!gh_pair_p (between))
+ break;
+
+ if (!left)
+ {
+ left = dynamic_cast<Item*> (unsmob_grob (gh_car (between)));
+ left = left->column_l ();
+ }
+ divide_over ++;
+ loose = dynamic_cast<Item*> (unsmob_grob (gh_cdr (between)));
+ loose = loose->column_l ();
+ }
+
+ right = loose;
+
+ Real rx = right->relative_coordinate (right->parent_l (X_AXIS), X_AXIS);
+ Real lx = left->relative_coordinate (left->parent_l (X_AXIS), X_AXIS);
+
+ int j = 1;
+ loose = col;
+ while (1)
+ {
+ SCM between = loose->get_grob_property ("between-cols");
+ if (!gh_pair_p (between))
+ break;
+
+ Paper_column *thiscol = dynamic_cast<Paper_column*> (loose);
+
+ thiscol->line_l_ = which;
+ thiscol->translate_axis (lx + j*(rx - lx)/divide_over, X_AXIS);
+
+ j ++;
+ loose = dynamic_cast<Item*> (unsmob_grob (gh_cdr (between)));
+ }
+
+ }
+}
+
// const?
void
Line_of_score::break_into_pieces (Array<Column_x_positions> const &breaking)
c[j]->translate_axis (breaking[i].config_[j],X_AXIS);
dynamic_cast<Paper_column*> (c[j])->line_l_ = line_l;
}
-
+ set_loose_columns (line_l, &breaking[i]);
broken_into_l_arr_.push (line_l);
}
}
*/
void
-New_spacing_spanner::do_measure (Grob*me, Link_array<Grob> const & cols)
+New_spacing_spanner::do_measure (Grob*me, Link_array<Grob> *cols)
{
Moment shortest;
Moment mean_shortest;
Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing"));
shortest.set_infinite (1);
+ for (int i = cols->size(); i--;)
+ {
+ if (gh_pair_p (cols->elem(i)->get_grob_property ("between-cols")))
+ cols->del (i);
+ }
+
int n = 0;
- for (int i =0 ; i < cols.size (); i++)
+ for (int i =0 ; i < cols->size (); i++)
{
- if (Paper_column::musical_b (cols[i]))
+ if (Paper_column::musical_b (cols->elem (i)))
{
- Moment *when = unsmob_moment (cols[i]->get_grob_property ("when"));
+ Moment *when = unsmob_moment (cols->elem (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");
+ SCM st = cols->elem (i)->get_grob_property ("shortest-starter-duration");
Moment this_shortest = *unsmob_moment (st);
shortest = shortest <? this_shortest;
if (!mean_shortest.main_part_.infty_b ())
Array<Spring> springs;
Item * first_col = 0;
- for (int i= 0; i < cols.size () - 1; i++)
+ for (int i= 0; i < cols->size () - 1; i++)
{
- Item * l = dynamic_cast<Item*> (cols[i]);
+ Item * l = dynamic_cast<Item*> (cols->elem (i));
if (!first_col && Paper_column::musical_b (l))
first_col = l;
- SCM between = cols[i]->get_grob_property ("between-cols");
- if (gh_pair_p (between)
- && i > 0
- && i < cols.size ()-1
- && (gh_cdr (between) != cols[i+1]->self_scm ()
- || gh_car (between) != cols[i-1]->self_scm ())
- )
- continue ;
-
- int j = i+1;
- for (; j < cols.size () - 1; j++)
- {
- if (Paper_column::musical_b (cols[j]))
- break;
-
- SCM between = cols[j]->get_grob_property ("between-cols");
- if (!gh_pair_p (between))
- continue;
-
- if (gh_car (between) == cols[i]->self_scm () )
- break ;
- }
-
- Item * r = dynamic_cast<Item*> (cols[j]);
+ Item * r = dynamic_cast<Item*> (cols->elem (i+1));
Paper_column * lc = dynamic_cast<Paper_column*> (l);
Paper_column *rc = dynamic_cast<Paper_column*> (r);
Real
New_spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc,
- Moment shortest)
+ Moment shortest)
{
Moment shortest_playing_len = 0;
SCM s = lc->get_grob_property ("shortest-playing-duration");
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);
+ Real dist = 0.0;
+ if (delta_t.main_part_)
+ {
+ dist = get_duration_space (me, shortest_playing_len, shortest);
+ dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_);
+ }
+ else if (delta_t.grace_part_)
+ {
+ dist = get_duration_space (me, shortest, shortest);
+ Real grace_fact = 1.0;
+ SCM gf = me->get_grob_property ("grace-space-factor");
+ if (gh_number_p (gf))
+ grace_fact = gh_scm2double (gf);
+
+ dist *= grace_fact;
+ }
+
+#if 0
/*
- ugh: 0.1 is an arbitrary distance.
+ TODO: figure out how to space grace notes.
*/
- dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_)
- + 0.1 * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_);
+ dist *=
+ + grace_fact * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_);
Moment *lm = unsmob_moment (lc->get_grob_property ("when"));
else if (!rm->grace_part_ && lm->grace_part_)
dist *= 0.7;
}
-
+#endif
return dist;
}
if (Item::breakable_b (sc))
{
Link_array<Grob> measure (all.slice (j, i+1));
- do_measure (me, measure);
+ do_measure (me, &measure);
j = i;
}
}
find_rods (rb, gh_cdr (s));
}
+ find_musical_sequences (me);
#if 0
/*
TODO; restore this.
}
+void
+Separating_group_spanner::find_musical_sequences (Grob *me)
+{
+ Item *last = 0;
+ Item *llast = 0;
+ for (SCM s = me->get_grob_property ("elements");
+ gh_pair_p (s); s = gh_cdr (s))
+ {
+ Item *it = dynamic_cast<Item*> (unsmob_grob (gh_car (s)));
+ if (last)
+ {
+ Item *lcol = last->column_l ();
+ Item *col = it->column_l ();
+
+ int lrank = Paper_column::rank_i (lcol);
+ int rank = Paper_column ::rank_i (col);
+
+ bool mus = Paper_column::musical_b (col);
+ bool lmus = Paper_column::musical_b (lcol);
+
+ if ((lrank - rank == 2) && lmus && mus)
+ {
+ SCM seq = col->get_grob_property ("spacing-sequence");
+ col->set_grob_property ("spacing-sequence",
+ gh_cons (gh_cons (it->self_scm (), last->self_scm ()), seq));
+ }
+
+ if (llast && !Paper_column::breakable_b (last))
+ {
+ Item *llcol = llast->column_l ();
+ int llrank = Paper_column::rank_i (llcol);
+ bool llmus= Paper_column::musical_b (llcol);
+ if (llrank - lrank == 1
+ && lrank - rank == 1
+ && llmus && !lmus && mus)
+ {
+ SCM seq = col->get_grob_property ("spacing-sequence");
+ col->set_grob_property ("spacing-sequence",
+ gh_cons (gh_cons (it->self_scm (), last->self_scm ()), seq));
+ }
+ else if (!lmus)
+ {
+ SCM between = lcol->get_grob_property ("between-cols");
+
+ if (!gh_pair_p (between))
+ {
+ between = gh_cons (it->self_scm (), llast->self_scm ());
+ lcol ->set_grob_property ("between-cols", between);
+ }
+
+ Item * left
+ = dynamic_cast<Item*> (unsmob_grob (gh_car (between)));
+ if(Paper_column::rank_i (left->column_l ()) < rank)
+ gh_set_car_x (between, col->self_scm());
+
+ Item * right
+ = dynamic_cast<Item*> (unsmob_grob (gh_cdr (between)));
+ if (Paper_column::rank_i (right->column_l ()) > llrank )
+ gh_set_cdr_x (between, llcol->self_scm ());
+ }
+ }
+ }
+
+ llast = last;
+ last = it;
+ }
+}
+
+#if 0
+void
+Separating_group_spanner::set_loose_rods ()
+{
+ // loose columns should also generate minimum distances.
+ // TODO
+}
+#endif
+
+
void
Separating_group_spanner::set_interface (Grob*)
{
Item * break_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);
Separating_line_group_engraver::Separating_line_group_engraver ()
{
- last_step_musical_malt_p_ = 0;
sep_span_p_ = 0;
break_malt_p_ = 0;
musical_malt_p_ =0;
}
if (musical_malt_p_)
- {
+ {
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;
-
+ }
+ musical_malt_p_ =0;
}
void
Simple_spacer::add_columns (Link_array<Grob> cols)
{
+ for (int i = cols.size (); i--;)
+ if (gh_pair_p (cols[i]->get_grob_property ("between-cols")))
+ {
+ loose_cols_.push (cols[i]);
+ cols.del (i);
+ }
+
+ spaced_cols_ = cols;
for (int i=0; i < cols.size () - 1; i++)
{
- SCM spring_params = SCM_UNDEFINED;
+ SCM spring_params = SCM_EOL;
for (SCM s = cols[i]->get_grob_property ("ideal-distances");
- spring_params == SCM_UNDEFINED && gh_pair_p (s);
+ !gh_pair_p (spring_params) && gh_pair_p (s);
s = gh_cdr (s))
{
Grob *other = unsmob_grob (gh_caar (s));
}
Spring_description desc;
- if (spring_params != SCM_UNDEFINED)
+ if (gh_pair_p (spring_params))
{
desc.ideal_f_ = gh_scm2double (gh_car (spring_params));
desc.hooke_f_ = gh_scm2double (gh_cdr (spring_params));
if (!desc.sane_b ())
{
programming_error ("Insane spring found. Setting to unit spring.");
+
+ cout << "columns " << Paper_column::rank_i (cols[i])
+ << " " << Paper_column::rank_i (cols[i+1]) << endl;
desc.hooke_f_ = 1.0;
desc.ideal_f_ = 1.0;
}
{
positions->config_.push (positions->config_.top () + springs_[i].length (force_f_));
}
-
+ positions->cols_ = spaced_cols_;
+ positions->loose_cols_ = loose_cols_;
+
positions->satisfies_constraints_b_ = (line_len_f_ < 0) || active_b ();
}
(SpacingSpanner . (
(spacing-procedure . ,Spacing_spanner::set_springs)
(stem-spacing-correction . 0.5)
-
+ (grace-space-factor . 0.8)
;; TODO: change naming -- unintuitive
(arithmetic-basicspace . 2.0)
# source file of the GNU LilyPond music typesetter
#
# download and rebuild latest lilypond or from specified url
-#
+#
+
'''
TODO: