+pl 14.hwn1
+ - specialize duration.cc for lily, move out of lib/
+ - stem cleanup
+ - more SCM typechecking
+ - stafflineleading -> staff_space
+ - bf: rod distances.
+ - junk some unused code.
+
pl 13.hwn2
- paper/score column cleanups. Junk Score_column type
The website is the most convenient form to use for reading the
documentation on-line documentation. It is made by entering @example
- make website
+ make htmldoc
@end example
This does require a functioning LilyPond. The binary doesn't have to
#include "string.hh"
#include "proto.hh"
#include "warn.hh"
-#include "thank-you-cygnus.hh"
#include "source-file.hh"
#include "simple-file-storage.hh"
#include "string-storage.hh"
-#include "warn.hh"
#include <stream.h>
+#include "warn.hh"
+
void
error (String s)
cerr << _("programming error: ") << s << _(" (Continuing; cross thumbs)") << '\n';
}
-void
-programming_warning (String m)
-{
- cerr << _ ("programming warning: ") << m <<endl;
-
-}
{
if (!elts_[i]->parent_l (Y_AXIS))
staffline_p_->add_element (elts_[i]);
- else if (elts_[i]->get_elt_property ("Axis_group_element::add_extra_element") == SCM_UNDEFINED
- && ! dynamic_cast<Axis_group_element*> (elts_[i]->parent_l (Y_AXIS)))
+ else
+ if (
+ // elts_[i]->get_elt_property ("Axis_group_element::add_extra_element") == SCM_UNDEFINED &&
+ ! dynamic_cast<Axis_group_element*> (elts_[i]->parent_l (Y_AXIS)))
{
staffline_p_->add_element (elts_[i]);
{
Stem *s = stem (i);
SCM force = s->remove_elt_property ("dir-forced");
- if (force == SCM_UNDEFINED)
+ if (!gh_boolean_p (force) || !gh_scm2bool (force))
s->set_direction (d);
}
}
bool knee_b = false;
int knee_y = 0;
SCM gap = get_elt_property (gap_str);
- if (gap != SCM_UNDEFINED)
+ if (gh_number_p (gap))
{
int auto_gap_i = gh_scm2int (gap);
for (int i=1; i < stem_count (); i++)
gh_int2scm (multiplicity),
SCM_UNDEFINED));
Real shorten_f = gh_scm2double (shorten)
- * Staff_symbol_referencer_interface (this).staff_line_leading_f ();
+ * Staff_symbol_referencer_interface (this).staff_space ();
/* cute, but who invented this -- how to customise ? */
if (forced_fraction < 1)
Stem* s = stem (i);
if (s->invisible_b ())
continue;
- if (s->get_elt_property ("shorten") == SCM_UNDEFINED)
+ if (gh_number_p (s->get_elt_property ("shorten")))
s->set_elt_property ("shorten", gh_double2scm (shorten_f));
}
}
/* set or read dy as necessary */
SCM s = get_elt_property ("height");
- if (s != SCM_UNDEFINED)
+ if (gh_number_p (s))
dy = gh_scm2double (s);
else
set_elt_property ("height", gh_double2scm (dy));
/* set or read y as necessary */
s = get_elt_property ("y-position");
- if (s != SCM_UNDEFINED)
+ if (gh_number_p (s))
{
y = gh_scm2double (s);
set_stem_length (y, dy);
{
SCM damp = get_elt_property ("damping"); // remove?
int damping = 1; // ugh.
- if (damp != SCM_UNDEFINED)
+ if (gh_number_p (damp))
damping = gh_scm2int (damp);
if (damping)
return dy;
Staff_symbol_referencer_interface st (this);
- Real interline_f = st.staff_line_leading_f ();
+ Real interline_f = st.staff_space ();
Real staffline_f = paper_l ()->get_var ("stafflinethickness");
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
*/
Staff_symbol_referencer_interface sinf (this);
- Real space = sinf.staff_line_leading_f ();
+ Real space = sinf.staff_space ();
Real staffline_f = paper_l ()->get_var ("stafflinethickness");
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
Real gap_f = 0;
SCM gap = get_elt_property ("beam-gap");
- if (gap != SCM_UNDEFINED)
+ if (gh_number_p (gap))
{
int gap_i = gh_scm2int ( (gap));
int nogap = rwholebeams - gap_i;
Molecule a;
SCM d = get_elt_property ("dashed");
- if (d == SCM_UNDEFINED)
- a = lookup_l ()->slur (one, get_direction () * thick, thick);
- else
+ if (gh_number_p (d))
a = lookup_l ()->dashed_slur (one, thick, gh_scm2int (d));
+ else
+ a = lookup_l ()->slur (one, get_direction () * thick, thick);
return new Molecule (a);
}
Bezier
Bow::get_curve () const
{
-
-
-
Bezier_bow b (paper_l (),
get_encompass_offset_arr (), get_direction ());
// urg
SCM first_pair = elems[0]->get_elt_property ("minimum-space");
- if (first_pair == SCM_UNDEFINED)
- first_pair = gh_cons (gh_double2scm (0.0), gh_double2scm (0.0));
- else
+ if (gh_pair_p (first_pair))
first_pair = first_pair;
+ else
+ first_pair = gh_cons (gh_double2scm (0.0), gh_double2scm (0.0));
scm_set_car_x (first_pair, gh_double2scm (-dists[0]));
elems[0]->set_elt_property ("minimum-space", first_pair);
{
Staff_symbol_referencer_interface si (this);
- Real dl = si.staff_line_leading_f();
+ Real dl = si.staff_space();
Interval i1(0, dl / 6), i2(-dl / 2, dl / 2);
Box b(i1, i2);
void
Breathing_sign::do_post_processing()
{
- Real dl = Staff_symbol_referencer_interface (this).staff_line_leading_f();
+ Real dl = Staff_symbol_referencer_interface (this).staff_space();
translate_axis(2.0 * dl * get_direction (), Y_AXIS);
}
Jan Nieuwenhuizen <janneke@gnu.org>
*/
-#include "duration-convert.hh"
#include "timing-translator.hh"
#include "chord-tremolo-engraver.hh"
#include "stem.hh"
add_dependency (g); // just to be sure.
SCM my_vis = get_elt_property ("visibility-lambda");
- if (my_vis != SCM_UNDEFINED)
+ if (gh_procedure_p (my_vis))
g->set_elt_property ("visibility-lambda", my_vis);
}
Score_element * se = unsmob_element ( gh_car (s));
SCM force = se->remove_elt_property ("force-hshift");
- if (force != SCM_UNDEFINED)
+ if (gh_number_p (force))
{
tups. push (Shift_tup (se, gh_scm2double (force)));
}
if (pc->original_l_)
{
SCM pen = pc->get_elt_property ("penalty");
- if (pen != SCM_UNDEFINED)
+ if (gh_number_p (pen))
{
break_penalties += gh_scm2double (pen);
}
Hara_kiri_group_spanner::do_post_processing ()
{
SCM worth = get_elt_property ("items-worth-living");
- if (worth != SCM_EOL && worth != SCM_UNDEFINED)
+ if (gh_pair_p (worth))
return;
Link_array<Score_element> childs = get_children ();
void banter (Array<Musical_pitch> pitch_arr, Chord_mol* name_p) const;
Chord_name (Chord const& c);
+
+ /*
+ ugh. Junkme, I must be elt property.
+ */
+
Chord chord_;
protected:
--- /dev/null
+/*
+ duration.hh -- declare Duration
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+*/
+
+#ifndef DURATION_HH
+#define DURATION_HH
+
+#include "fproto.hh"
+#include "rational.hh"
+
+
+/**
+ A musical duration.
+ */
+struct Duration {
+ Duration ();
+ /// is the "plet factor" of this note != 1 ?
+ bool plet_b ();
+ String str () const;
+ void set_plet (int,int );
+ void compress (Rational);
+ Rational length_mom () const ;
+
+ /// Logarithm of the base duration.
+ int durlog_i_;
+ int dots_i_;
+ int tuplet_iso_i_; // 2/3; 2 is not duration, maar of count!
+ int tuplet_type_i_;
+
+};
+#endif // DURATION_HH
+
typeface. ie. leading is vertical space.
*/
- Real staff_line_leading_f () const;
+ Real staff_space () const;
Staff_symbol * staff_symbol_l () const;
int lines_i () const;
Real position_f () const;
public:
/// this many lines.
int no_lines_i_;
- Real staff_line_leading_f_;
- Real staff_line_leading_f ();
+ Real staff_space_;
+ Real staff_space ();
Staff_symbol ();
class Stem : public Item,
public Directional_element
{
-
- /**extent of the stem (positions).
- fractional, since Beam has to adapt them.
- */
- Interval yextent_;
-
public:
/// log of the duration. Eg. 4 -> 16th note -> 2 flags
int flag_i () const;
Note_head * first_head () const;
Score_element * support_head () const;
Stem ();
+
/// ensure that this Stem also encompasses the Notehead #n#
void add_head (Rhythmic_head*n);
int type_i () const;
void set_stemend (Real);
Direction get_default_dir() const;
-
int get_center_distance(Direction) const;
+ Real get_default_stemlen() const;
+
+ void position_noteheads();
- void set_default_stemlen();
- void set_default_extents();
- void set_noteheads();
+ Real stem_end_position () const;
- Real stem_end_f() const;
- Real stem_begin_f() const;
+ // todo: cleanup, naming
Real note_delta_f () const;
bool invisible_b() const;
Item::try_visibility_lambda ()
{
SCM vis = remove_elt_property ("visibility-lambda");
- if (vis != SCM_UNDEFINED)
+ if (gh_procedure_p (vis))
{
SCM args = scm_listify (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
SCM result = gh_apply (vis, args);
Molecule*output = new Molecule;
Staff_symbol_referencer_interface si (this);
- Real inter = si.staff_line_leading_f ()/2.0;
+ Real inter = si.staff_space ()/2.0;
int j;
if ((break_status_dir () == LEFT || break_status_dir () == CENTER)
{
Molecule*output = new Molecule;
Staff_symbol_referencer_interface si (this);
- Real note_distance = si.staff_line_leading_f ()/2;
+ Real note_distance = si.staff_space ()/2;
Molecule *octave_mol_p = 0;
int lastoct = -100;
String
Midi_event::str () const
{
- int delta_i = delta_mom_ * Moment (Duration::division_1_i_s);
+ int delta_i = delta_mom_ * Moment (384 * 4); // ugh.
+
String delta_str = Midi_item::i2varint_str (delta_i);
String midi_str = midi_p_->str ();
assert (midi_str.length_i ());
Molecule s;
bool rest_symbol=true;
SCM alt_symbol_sym =get_elt_property ("alt-symbol");
- if (alt_symbol_sym != SCM_UNDEFINED)
+ if (gh_string_p (alt_symbol_sym))
{
s = lookup_l () -> afm_find (ly_scm2string (alt_symbol_sym));
rest_symbol = false;
mol_p->add_molecule (s);
Real interline_f
- = staff_symbol_referencer_interface (this).staff_line_leading_f ();
+ = staff_symbol_referencer_interface (this).staff_space ();
if (measures_i_ == 1 && rest_symbol)
{
mol_p->translate_axis (interline_f, Y_AXIS);
SCM s1 = p1->get_elt_property ("horizontal-shift");
SCM s2 = p2->get_elt_property ("horizontal-shift");
- int h1 = (s1 == SCM_UNDEFINED) ? 0 : gh_scm2int (s1);
- int h2 = (s2 == SCM_UNDEFINED) ? 0 : gh_scm2int (s2);
+ int h1 = (gh_number_p (s1))? gh_scm2int (s1) :0;
+ int h2 = (gh_number_p (s2)) ? gh_scm2int (s2):0;
return h1 - h2;
}
Score_element * se = unsmob_element (gh_car (s));
Staff_symbol_referencer_interface si (se);
- se->translate_axis (dy_i * si.staff_line_leading_f ()/2.0, Y_AXIS);
+ se->translate_axis (dy_i * si.staff_space ()/2.0, Y_AXIS);
}
}
Real beam_y = 0;
SCM s = b->get_elt_property ("height");
- if (s != SCM_UNDEFINED)
+ if (gh_number_p (s))
beam_dy = gh_scm2double (s);
s = b->get_elt_property ("y-position");
- if (s != SCM_UNDEFINED)
+ if (gh_number_p (s))
beam_y = gh_scm2double (s);
Real x0 = b->first_visible_stem ()->hpos_f ();
Score_element * se = unsmob_element (gh_car (s));
Staff_symbol_referencer_interface si (se);
- Real staff_space = si.staff_line_leading_f ();
+ Real staff_space = si.staff_space ();
Real rest_dim = extent (Y_AXIS)[d]*2.0 /staff_space ;
Real minimum_dist
{
Staff_symbol_referencer_interface si (this);
- Real inter_f = si.staff_line_leading_f ()/2;
+ Real inter_f = si.staff_space ()/2;
int sz = si.lines_i ()-1;
Real p = si.position_f ();
int streepjes_i = abs (p) < sz
String type;
SCM style = get_elt_property ("style");
- if (style != SCM_UNDEFINED)
+ if (gh_string_p (style))
{
type = ly_scm2string (style);
}
Real staff_space = paper_l()->get_var ("interline");
/* FIXME
- staff_space = rcol->rest_l_arr[0]->staff_line_leading_f ();
+ staff_space = rcol->rest_l_arr[0]->staff_space ();
*/
Real internote_f = staff_space/2;
Real minimum_dist = paper_l ()->get_var ("restcollision_minimum_dist")
String style;
SCM style_sym =get_elt_property ("style");
- if (balltype_i () >= 2 && style_sym != SCM_UNDEFINED)
+ if (balltype_i () >= 2 &&gh_string_p ( style_sym))
{
style = ly_scm2string (style_sym);
}
for (SCM s = get_elt_property ("elements"); gh_pair_p (s) && gh_pair_p (gh_cdr (s)); s = gh_cdr (s))
{
- SCM elt = gh_car (s);
- SCM next_elt = gh_cadr (s);
+ /*
+ Order of elements is reversed!
+ */
+ SCM elt = gh_cadr (s);
+ SCM next_elt = gh_car (s);
Single_malt_grouping_item *l = dynamic_cast<Single_malt_grouping_item*> (unsmob_element (elt));
Single_malt_grouping_item *r = dynamic_cast<Single_malt_grouping_item*> (unsmob_element ( next_elt));
Direction dir = Side_position_interface (me).get_direction ();
SCM pad = me->remove_elt_property ("padding");
- if (pad != SCM_UNDEFINED)
+ if (gh_number_p (pad))
{
off += gh_scm2double (pad) * dir;
}
rp += d;
}
- return (rp - p) * si.staff_line_leading_f () / 2.0;
+ return (rp - p) * si.staff_space () / 2.0;
}
return 0.0;
}
SCM next_stretch_hint = rc->get_elt_property ("stretch-distance");
Real left_distance;
- if (hint != SCM_UNDEFINED)
+ if (gh_pair_p (hint))
{
left_distance = gh_scm2double (gh_cdr (hint));
}
Real right_dist = 0.0;
- if (next_hint != SCM_UNDEFINED)
+ if (gh_pair_p (next_hint))
{
right_dist += - gh_scm2double (gh_car (next_hint));
}
else
stretch_dist += left_distance;
- if (next_stretch_hint != SCM_UNDEFINED)
+ if (gh_pair_p (next_stretch_hint))
// see regtest spacing-tight
stretch_dist += - gh_scm2double (gh_car (next_stretch_hint));
else
else
{
Staff_symbol_referencer_interface si (this);
- return (si.lines_i () -1) * si.staff_line_leading_f ();
+ return (si.lines_i () -1) * si.staff_space ();
}
}
SCM sz (get_property ("staffLineLeading", 0));
if (gh_number_p(sz))
{
- span_p_->staff_line_leading_f_ = gh_scm2double (sz);
+ span_p_->staff_space_ = gh_scm2double (sz);
}
else
{
- span_p_->staff_line_leading_f_ = paper_l ()->get_var ("interline");
+ span_p_->staff_space_ = paper_l ()->get_var ("interline");
}
span_p_->set_bounds(RIGHT,get_staff_info().command_pcol_l ());
typeset_element (span_p_);
}
Real
-Staff_symbol_referencer_interface::staff_line_leading_f () const
+Staff_symbol_referencer_interface::staff_space () const
{
Staff_symbol * st = staff_symbol_l ();
if (st)
- return st->staff_line_leading_f_;
+ return st->staff_space_;
else if (elt_l_->pscore_l_ && elt_l_->paper_l ())
elt_l_->paper_l ()->get_var ("interline");
Real y = elt_l_->relative_coordinate (c, Y_AXIS)
- st->relative_coordinate (c, Y_AXIS);
- p += 2.0 * y / st->staff_line_leading_f ();
+ p += 2.0 * y / st->staff_space ();
}
else
{
Real off =0.0;
if (gh_number_p (pos))
{
- Real space = staff_symbol_referencer_interface (sc).staff_line_leading_f ();
+ Real space = staff_symbol_referencer_interface (sc).staff_space ();
off = gh_scm2double (pos) * space/2.0;
}
sc->set_elt_property ("staff-position", gh_double2scm (0.0));
Staff_symbol::Staff_symbol ()
{
no_lines_i_ = 5;
- staff_line_leading_f_ = 5.0 PT;
+ staff_space_ = 5.0 PT;
}
void
Molecule rule = lookup_l ()->filledbox (Box (Interval (0,width),
Interval (-t/2, t/2)));
- Real height = (no_lines_i_-1) * staff_line_leading_f_ /2;
+ Real height = (no_lines_i_-1) * staff_space_ /2;
Molecule * m = new Molecule;
for (int i=0; i < no_lines_i_; i++)
{
Molecule a (rule);
- a.translate_axis (height - i * staff_line_leading_f_, Y_AXIS);
+ a.translate_axis (height - i * staff_space_, Y_AXIS);
m->add_molecule (a);
}
return no_lines_i_*2;
}
Real
-Staff_symbol::staff_line_leading_f ()
+Staff_symbol::staff_space ()
{
- return staff_line_leading_f_;
+ return staff_space_;
}
#include "note-head.hh"
#include "stem.hh"
#include "musical-request.hh"
-#include "duration-convert.hh"
#include "misc.hh"
#include "stem-tremolo.hh"
#include "staff-info.hh"
{
Stem_tremolo * s = dynamic_cast<Stem_tremolo*> (c->element_l ());
Real space = Staff_symbol_referencer_interface (s->stem_l ())
- .staff_line_leading_f ();
+ .staff_space ();
return Interval (-space, space);
}
Real interbeam_f = paper_l ()->interbeam_f (mult);
Real w = gh_scm2double (get_elt_property ("beam-width"));
- Real space = Staff_symbol_referencer_interface (st).staff_line_leading_f ();
+ Real space = Staff_symbol_referencer_interface (st).staff_space ();
Real internote_f = space / 2;
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
{
Real dy = 0;
SCM s = st->beam_l ()->get_elt_property ("height");
- if (s != SCM_UNDEFINED)
+ if (gh_number_p (s))
dy = gh_scm2double (s);
Real dx = st->beam_l ()->last_visible_stem ()->hpos_f ()
- st->beam_l ()->first_visible_stem ()->hpos_f ();
if (st->beam_l ())
{
beams->translate (Offset(st->hpos_f () - hpos_f (),
- st->stem_end_f () * internote_f -
+ st->stem_end_position () * internote_f -
st->beam_l ()->get_direction () * beams_i * interbeam_f));
}
else
? -st->get_direction () * st->note_delta_f ()/2
: 0.0;
- dy += st->stem_end_f ();
+ dy += st->stem_end_position ();
beams->translate (Offset(st->hpos_f () - hpos_f ()+
whole_note_correction, dy));
}
Text_item::do_brew_molecule_p () const
{
SCM style = get_elt_property ("style");
- String st = (style == SCM_UNDEFINED) ? "" : ly_scm2string (style);
+ String st = gh_string_p (style) ? ly_scm2string (style) : "";
Molecule a= paper_l ()->lookup_l(0)->text (st, text_str_, paper_l ());
{
SCM st = get_elt_property ("style");
- if (st != SCM_UNDEFINED)
+ if (gh_string_p (st))
{
String style (ly_scm2string (st));
if (style[0]=='1')
if (is_alias_b (n) && (id_str_ == id || id.empty_b ()))
return this;
-
Translator_group* r = 0;
- for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+ for (Cons<Translator> *p = trans_p_list_.head_; !r && p; p = p->next_)
{
if (Translator_group *trg = dynamic_cast <Translator_group *> (p->car_))
r = trg->find_existing_translator_l (n, id);
{
Direction d = UP;
SCM dir_sym =get_elt_property ("dir-forced");
- if (dir_sym != SCM_UNDEFINED) {
- d= (Direction) gh_scm2int (dir_sym);
- if (d != CENTER)
- return d;
- }
+ if (gh_number_p (dir_sym))
+ {
+ d= (Direction) gh_scm2int (dir_sym);
+ if (d != CENTER)
+ return d;
+ }
for (SCM s = get_elt_property ("columns"); gh_pair_p (s); s = gh_cdr (s))
{
--- /dev/null
+/*
+ duration-convert.cc -- implement Duration_convert
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+#include <assert.h>
+#include "duration-convert.hh"
+#include "duration-iter.hh"
+#include "warn.hh"
+
+// statics Duration_convert
+bool const Duration_convert::midi_as_plet_b_s = true;
+bool Duration_convert::no_quantify_b_s = false;
+bool Duration_convert::no_double_dots_b_s = false;
+bool Duration_convert::no_triplets_b_s = false;
+int Duration_convert::no_smaller_than_i_s = 0;
+Array<Duration> Duration_convert::dur_array_s;
+
+String
+Duration_convert::dur2_str (Duration dur)
+{
+ if (dur.ticks_i_)
+ return String ("[") + to_str (dur.ticks_i_) + "]";
+
+ String str;
+ if (dur.durlog_i_ >= 0)
+ str = to_str ( type2_i (dur.durlog_i_) );
+ else if (dur.durlog_i_ == -1)
+ str = "\\breve";
+ else if (dur.durlog_i_ == -2)
+ str = "\\longa";
+ str += to_str ('.', dur.dots_i_);
+ if (dur.plet_b ())
+ str += String ("*") + to_str (dur.plet_.iso_i_)
+ + String ("/") + to_str (dur.plet_.type_i_);
+ return str;
+}
+
+int
+Duration_convert::dur2ticks_i (Duration dur)
+{
+ if (dur.ticks_i_)
+ return dur.ticks_i_;
+ return dur2_mom (dur) * Rational (Duration::division_1_i_s);
+}
+
+int
+Duration_convert::i2_type (int i)
+{
+ int t=0;
+ while (i && !(i & 1)) {
+ i >>= 1;
+ t++;
+ }
+ return t;
+}
+
+int
+Duration_convert::type2_i (int type)
+{
+ if (type<0)
+ return 0;
+ else
+ return 1 << type;
+}
+
+Rational
+Duration_convert::dur2_mom (Duration dur)
+{
+ if (dur.ticks_i_)
+ return Rational (dur.ticks_i_, Duration::division_1_i_s);
+
+ // or simply assert?
+ if (dur.durlog_i_<-10)
+ return Rational (0);
+ Rational mom;
+ if (dur.durlog_i_<0)
+ mom = Rational (type2_i (-dur.durlog_i_), 1);
+ else
+ mom = Rational (1 , type2_i (dur.durlog_i_));
+
+ Rational delta = mom;
+ while (dur.dots_i_--)
+ {
+ delta /= 2.0;
+ mom += delta;
+ }
+
+ return mom * plet_factor_mom (dur);
+}
+
+Duration
+Duration_convert::mom2_dur (Rational mom)
+{
+ if (!mom)
+ {
+ Duration dur;
+ dur.set_plet (0,1);
+ return dur;
+ }
+
+
+ Duration dur = mom2standardised_dur (mom);
+ // if (!dur.mom () || (dur.mom () == mom))
+ if (!dur.length_mom () || (dur.length_mom () == mom))
+ return dur;
+ assert (midi_as_plet_b_s);
+
+ // dur.set_plet (type_mom, Duration::division_1_i_s / 4);
+
+ // Rational as_plet_mom = mom / dur.mom ();
+ Rational as_plet_mom = mom / dur.length_mom ();
+ as_plet_mom *= dur.plet_.mom ();
+ long num = as_plet_mom.num ();
+ long den = as_plet_mom.den ();
+ dur.set_plet (num, den);
+ return dur;
+}
+
+Duration
+Duration_convert::mom2standardised_dur (Rational mom)
+{
+ // if (!dur_array_s.length_i ())
+ if (!dur_array_s.size ())
+ set_array ();
+ assert (dur_array_s.size ());
+ for (int i = 0; i < dur_array_s.size () - 1; i++)
+ {
+ Rational lower_mom = dur2_mom (dur_array_s[ i ]);
+ if (mom <= lower_mom)
+ {
+ // all arbitrary, but 3/4 will get rid of the noise...
+ // kinda ok
+ if (i || (mom / lower_mom > Rational (3, 4)))
+ return dur_array_s[ i ];
+ else
+ {
+ Duration d;
+ d.durlog_i_ = -100;
+ return d;
+ }
+ }
+ Rational upper_mom = dur2_mom (dur_array_s[ i + 1 ]);
+ if ((mom < upper_mom)
+ && ((mom - lower_mom) / lower_mom
+ < (upper_mom - mom) / upper_mom))
+ return dur_array_s[ i ];
+ }
+ return dur_array_s[ dur_array_s.size () - 1 ];
+}
+
+void
+Duration_convert::set_array ()
+{
+ dur_array_s.clear ();
+
+ Duration_iterator iter_dur;
+ assert (iter_dur);
+ while (iter_dur)
+ dur_array_s.push (iter_dur++);
+}
+
+
+Rational
+Duration_convert::plet_factor_mom (Duration dur)
+{
+ return dur.plet_.mom ();
+}
+
+Real
+Duration_convert::sync_f (Duration dur, Rational mom)
+{
+ return mom / dur2_mom (dur);
+}
+
+Duration
+Duration_convert::ticks2_dur (int ticks_i)
+{
+ Rational mom (ticks_i, Duration::division_1_i_s);
+ if (midi_as_plet_b_s)
+ return mom2_dur (mom);
+
+ Duration dur = mom2standardised_dur (mom);
+
+ if (dur.length_mom () == mom)
+ return dur;
+
+ return mom2_dur (mom);
+}
+
+Duration
+Duration_convert::ticks2standardised_dur (int ticks_i)
+{
+ Rational mom (ticks_i, Duration::division_1_i_s);
+ Duration dur = mom2standardised_dur (mom);
+ return dur;
+}
--- /dev/null
+/*
+ duration-convert.cc -- implement Duration_convert
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+#include <assert.h>
+#include "duration-convert.hh"
+#include "warn.hh"
+#include "duration-iter.hh"
+
+Duration_iterator::Duration_iterator ()
+{
+ cursor_dur_.durlog_i_ = 7;
+ if (Duration_convert::no_smaller_than_i_s)
+ cursor_dur_.durlog_i_ = Duration_convert::no_smaller_than_i_s;
+}
+
+Duration
+Duration_iterator::operator ++(int)
+{
+ return forward_dur ();
+}
+
+Duration
+Duration_iterator::operator ()()
+{
+ return dur ();
+}
+
+Duration_iterator::operator bool ()
+{
+ return ok ();
+}
+
+Duration
+Duration_iterator::dur ()
+{
+ return cursor_dur_;
+}
+
+Duration
+Duration_iterator::forward_dur ()
+{
+ /* should do smart table? guessing:
+ duration wholes
+ 16 0.0625
+ 32.. 0.0703
+ 8:2/3 0.0833
+ 16. 0.0938
+ 8 0.1250
+ 16.. 0.1406
+ 4:2/3 0.1667
+ 8. 0.1875
+
+ */
+ assert (ok ());
+
+ Duration dur = cursor_dur_;
+
+ if (!cursor_dur_.dots_i_ && !cursor_dur_.plet_b ())
+ {
+ cursor_dur_.durlog_i_ += 1;
+ cursor_dur_.dots_i_ = 2;
+ }
+ else if (cursor_dur_.dots_i_ == 2)
+ {
+ assert (!cursor_dur_.plet_b ());
+ cursor_dur_.dots_i_ = 0;
+ cursor_dur_.durlog_i_ -=2;
+ cursor_dur_.set_plet (2, 3);
+ }
+ else if (cursor_dur_.plet_b ()
+ && (cursor_dur_.plet_.iso_i_ == 2)
+ && (cursor_dur_.plet_.type_i_ == 3))
+ {
+ assert (!cursor_dur_.dots_i_);
+ cursor_dur_.set_plet (1, 1);
+ cursor_dur_.durlog_i_ += 1;
+ cursor_dur_.dots_i_ = 1;
+ }
+ else if (cursor_dur_.dots_i_ == 1)
+ {
+ assert (!cursor_dur_.plet_b ());
+ cursor_dur_.dots_i_ = 0;
+ cursor_dur_.durlog_i_ -= 1;
+ }
+
+ if (Duration_convert::no_triplets_b_s
+ && cursor_dur_.plet_b () && ok ())
+ forward_dur ();
+ if (Duration_convert::no_double_dots_b_s
+ && (cursor_dur_.dots_i_ == 2) && ok ())
+ forward_dur ();
+ if (Duration_convert::no_smaller_than_i_s
+ && (cursor_dur_.durlog_i_ > Duration_convert::no_smaller_than_i_s) && ok ())
+ forward_dur ();
+ if (Duration_convert::no_smaller_than_i_s
+ && cursor_dur_.dots_i_
+ && (cursor_dur_.durlog_i_ >= Duration_convert::no_smaller_than_i_s)
+ && ok ())
+ forward_dur ();
+ if (Duration_convert::no_smaller_than_i_s
+ && (cursor_dur_.dots_i_ == 2)
+ && (cursor_dur_.durlog_i_ >= Duration_convert::no_smaller_than_i_s / 2)
+ && ok ())
+ forward_dur ();
+
+ return dur;
+}
+
+bool
+Duration_iterator::ok ()
+{
+ return cursor_dur_.length_mom () <= Rational (4);
+}
--- /dev/null
+/*
+ duration.cc -- implement Duration, Plet,
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
+ Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+
+ UGH. Duration is broken.
+*/
+
+#include <assert.h>
+
+#include "proto.hh"
+#include "string.hh"
+#include "source-file.hh"
+#include "source.hh"
+#include "rational.hh"
+#include "duration.hh"
+#include "duration-convert.hh"
+#include "duration-iter.hh"
+
+// statics Duration
+int Duration::division_1_i_s = 384 * 4;
+
+
+Duration::Duration ()
+{
+ durlog_i_ = 0;
+ dots_i_ = 0;
+ ticks_i_ = 0;
+}
+
+bool
+Duration::duration_type_b (int t)
+{
+ /*
+ ugh. Assuming behavior of conversion funcs on broken input.
+ */
+ return t == Duration_convert::type2_i (Duration_convert::i2_type (t));
+}
+
+void
+Duration::compress (Rational m)
+{
+ plet_.iso_i_ *= m.num_i ();
+ plet_.type_i_ *= m.den_i ();
+}
+
+Rational
+Duration::length_mom () const
+{
+ return Duration_convert::dur2_mom (*this);
+}
+
+void
+Duration::set_plet (int i, int t)
+{
+ plet_.iso_i_ = i;
+ plet_.type_i_ = t;
+}
+
+/*
+void
+Duration::set_plet (Duration d)
+{
+ plet_.iso_i_ = d.plet_.iso_i_;
+ plet_.type_i_ = d.plet_.type_i_;
+}
+*/
+
+void
+Duration::set_ticks (int ticks_i)
+{
+ assert (durlog_i_ <10);
+ assert (!dots_i_);
+ ticks_i_ = ticks_i;
+}
+
+String
+Duration::str () const
+{
+ return Duration_convert::dur2_str (*this);
+}
+
+
+bool
+Duration::plet_b ()
+{
+ return !plet_.unit_b ();
+}
+
--- /dev/null
+/*
+ duration-convert.hh -- declare Duration_convert
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+
+#ifndef DURATION_CONVERT_HH
+#define DURATION_CONVERT_HH
+#include "duration.hh"
+#include "string.hh"
+#include "array.hh"
+
+/**
+ Duration_convert handles all conversions to -n fro Duration (dur).
+ That is including (integer + division) representation for MIDI,
+ and conversion from unexact time representation (best guess :-).
+
+ A Rational (mom) is a Rational that holds the time fraction
+ compared to a whole note (before also called wholes).
+
+ [todo]
+ move all statics to real members, instantiate Duration_convert
+ object (s).
+*/
+struct Duration_convert {
+
+ /* Urgh. statics.
+ */
+ static bool const midi_as_plet_b_s;
+ static bool no_quantify_b_s;
+ static bool no_double_dots_b_s;
+ static bool no_triplets_b_s;
+ static int no_smaller_than_i_s;
+ static Array<Duration> dur_array_s;
+
+ /// Return number of ticks in (ticks, division_1) representation
+ static int dur2ticks_i (Duration dur );
+
+ /// Return the type_i representation of note length i
+ static int i2_type (int i);
+
+ /// Return the note length corresponding to the type_i representation
+ /// Return 0 if longer than whole note.
+ static int type2_i (int type);
+
+ /// Return Rational representation (fraction of whole note).
+ static Rational dur2_mom (Duration dur );
+
+ /// Return Mudela string representation.
+ static String dur2_str (Duration dur );
+
+ /// Return duration from Rational (fraction of whole) representation.
+ static Duration mom2_dur (Rational mom );
+
+ /// Return standardised duration, best guess if not exact.
+ static Duration mom2standardised_dur (Rational mom );
+
+ /// Return plet factor (not a Rational: should use Rational?).
+ static Rational plet_factor_mom (Duration dur );
+
+ static void set_array ();
+
+ /** Return synchronisation factor for mom, so that
+ mom2_dur (mom / sync_f ) will return the duration dur.
+ */
+ static Real sync_f (Duration dur, Rational mom );
+
+ /// Return exact duration, in midi-ticks if not-exact.
+ static Duration ticks2_dur (int ticks_i );
+
+ /// Return standardised duration, best guess if not exact.
+ static Duration ticks2standardised_dur (int ticks_i );
+};
+
+
+#endif // DURATION_CONVERT_HH
--- /dev/null
+/*
+ duration-iter.hh -- declare Duration_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.ruu.nl>
+
+ */
+
+#ifndef DURATION_ITER_HH
+#define DURATION_ITER_HH
+
+/// (iter_dur)
+struct Duration_iterator {
+
+ /// start at shortest: 128:2/3
+ Duration_iterator ();
+
+ // **** what about these three here ?
+ /// return forward_dur ();
+ Duration operator ++(int);
+
+ /// return ok ()
+ operator bool ();
+
+ /// return dur ()
+ Duration operator ()();
+
+
+ /// return current dur
+ Duration dur ();
+
+ /// return dur (), step to next
+ Duration forward_dur ();
+
+ /// durations left?
+ bool ok ();
+
+private:
+
+ Duration cursor_dur_;
+};
+
+
+
+#endif /* DURATION_ITER_HH */
+
--- /dev/null
+/*
+ duration.hh -- declare Duration
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+*/
+
+// split into 4?
+
+#ifndef DURATION_HH
+#define DURATION_HH
+
+#include "fproto.hh"
+#include "rational.hh"
+#include "plet.hh"
+
+/**
+ Handle "musical" durations. This means: balltype 1,2,4,etc. and dots.
+
+ (dur)
+ */
+struct Duration {
+ Duration ();
+ /// is the "plet factor" of this note != 1 ?
+ bool plet_b ();
+ String str () const;
+ void set_plet (int,int );
+ void compress (Rational);
+
+ static bool duration_type_b (int t);
+ void set_ticks (int ticks_i );
+ Rational length_mom () const ;
+ static int division_1_i_s;
+
+ /// Logarithm of the base duration.
+ int durlog_i_;
+ int dots_i_;
+ Plet plet_;
+ int ticks_i_;
+};
+#endif // DURATION_HH
+
--- /dev/null
+/*
+ plet.hh -- declare Plet
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+
+#ifndef PLET_HH
+#define PLET_HH
+#include "rational.hh"
+
+/**
+ The type and replacement value of a plet (triplet, quintuplet.) Conceptually the same as a rational, but 4/6 != 2/3.
+
+ (plet)
+ */
+struct Plet {
+ Plet ();
+ Rational mom () const;
+ bool unit_b () const;
+ int iso_i_; // 2/3; 2 is not duration, maar of count!
+ int type_i_;
+};
+
+#endif // PLET_HH
--- /dev/null
+/*
+ plet.cc -- implement Plet
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#include "plet.hh"
+
+
+Plet::Plet ()
+{
+ type_i_ = 1;
+ iso_i_ = 1;
+}
+
+Rational
+Plet::mom () const
+{
+ return Rational (iso_i_, type_i_);
+}
+
+bool
+Plet::unit_b () const
+{
+ return type_i_ == 1 && iso_i_ == 1;
+}
+