preliminary, please do not distribute. Please send your helpful comments and
patches to me,
- hanwen@stack.urc.tue.nl
+ hanwen@stack.urc.tue.nl
+
+LilyPond is updated very frequently, the latest version is always available at:
+
+ ftp://pcnov095.win.tue.nl/pub/lilypond
PREREQUISITES
You will need GNU C++ v2.7 or better and GNU make. If you actually
want to use this, you'd better use the "speedy" compilation flags in
the Makefile.
+Do:
+
+ tar zxf flower-1.11.9.tar.gz
+ mv flower-1.11.9 flower
+ cd flower; make; cd ..
+ tar zxf lilypond-1.2.13.tar.gz
+ cd lilypond-1.2.13
+ make
why G++ >= 2.7? LilyPond & flower lib uses builtin bool and typeof.
This is what the output looks like over here.
-hw:~/musix/spacer$ lilypond maartje.ly
-LilyPond version 0.0.6 compiled on Nov 2 1996 at 01:25:29
-Parsing ... [maartje.ly]
+hw:~/musix/spacer$ lilypond kortjakje.ly
+LilyPond version 0.0.9 compiled on Nov 7 1996 at 23:38:21
+Parsing ... [kortjakje.ly]
+Processing ... Calculating ...
output to lelie.uit...
+
hw:~/musix/spacer$ tex test
This is TeX, Version 3.14159 (C version 6.1)
(test.tex
Hyphenation patterns for english, dutch, loaded.
(lilyponddefs.tex) (lelie.uit) [1] )
-Output written on test.dvi (1 page, 1964 bytes).
+Output written on test.dvi (1 page, 3076 bytes).
Transcript written on test.log.
+
hw:~/musix/spacer$ xdvi test&
-[1] 3130
-hw:~/musix/spacer$
+[1] 1667
PROBLEMS
* Use The Source, Luke. If you don't know C++, you can try editing
.dstreamrc for copious debugging output.
-* see also the subdir Documentation
+* also the subdir Documentation/ it contains some in depth matter
+on LilyPond algorithms
* The source is commented in the DOC++ style.
Check out doc++ at
--- /dev/null
+#include "proto.hh"
+#include "real.hh"
+#include "string.hh"
+
+/// symbols, dimensions and constants
+struct Paperdef {
+ Lookup *lookup_;
+ String outfile;
+ Real linewidth;
+
+ /// how much space does a whole note take (ideally?)
+ Real whole_width;
+
+ /// ideal = geometric_ ^ log2(duration)
+ Real geometric_;
+
+ /****************/
+ void parse();
+ Paperdef();
+ ~Paperdef();
+ Real interline()const;
+ Real rule_thickness()const;
+ Real standard_height()const;
+ Real note_width() const;
+ void print() const;
+ Real duration_to_dist(Real);
+};
+/** This struct takes care of all kinds of symbols, dimensions and
+ constants. Most of them are related to the point-size of the fonts,
+ so therefore, the lookup table for symbols is also in here.
+
+ see TODO
+ */
--- /dev/null
+#include "beam.hh"
+#include "debug.hh"
+#include "symbol.hh"
+#include "molecule.hh"
+#include "leastsquares.hh"
+#include "pcol.hh"
+#include "stem.hh"
+#include "paper.hh"
+#include "lookup.hh"
+
+
+struct Stem_info {
+ Real x;
+ Real idealy;
+ Real miny;
+ int no_beams;
+
+ Stem_info(){}
+ Stem_info(const Stem*);
+};
+Stem_info::Stem_info(const Stem*s)
+{
+ x = s->hpos();
+ int dir = s->dir;
+ idealy = MAX(dir*s->top, dir*s->bot);
+ miny = MAX(dir*s->minnote, dir*s-> maxnote);
+ assert(miny <= idealy);
+ no_beams = s->flag;
+}
+
+/****************/
+
+Beam::Beam()
+{
+ slope = 0;
+ left_pos = 0.0;
+ dir =0;
+}
+
+void
+Beam::add(Stem*s)
+{
+ stems.bottom().add(s);
+ s->print_flag = false;
+}
+
+void
+Beam::set_default_dir()
+{
+ int dirs[2];
+ dirs[0]=0; dirs[1] =0;
+ for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
+ sc->set_default_dir();
+ dirs[(sc->dir+1)/2] ++;
+ }
+ dir = (dirs[0] > dirs[1]) ? -1 : 1;
+ for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
+ sc->dir = dir;
+ }
+}
+
+void
+Beam::solve_slope()
+{
+ svec<Stem_info> sinfo;
+ for (PCursor<Stem* >sc(stems); sc.ok(); sc++) {
+ sc->set_default_extents();
+ Stem_info i(sc);
+ sinfo.add(i);
+ }
+ Real leftx = sinfo[0].x;
+ Least_squares l;
+ for (int i=0; i < sinfo.sz(); i++) {
+ sinfo[i].x -= leftx;
+ l.input.add(Offset(sinfo[i].x, sinfo[i].idealy));
+ }
+
+ l.minimise(slope, left_pos);
+ Real dy = 0.0;
+ for (int i=0; i < sinfo.sz(); i++) {
+ Real y = sinfo[i].x * slope + left_pos;
+ Real my = sinfo[i].miny;
+
+ if (my - y > dy)
+ dy = my -y;
+ }
+ left_pos += dy;
+ left_pos *= dir;
+ slope *= dir;
+
+ {Real inter =paper()->interline()/2;
+ Real unitslope = slope*inter;
+
+ // set beamslope, for setting stems correctly
+ // ignoring return.
+ Symbol sy = paper()->lookup_->beam(unitslope, width().length());
+ slope =unitslope / inter;
+ }
+}
+
+void
+Beam::set_stemlens()
+{
+ PCursor<Stem*> s(stems);
+ Real x0 = s->hpos();
+ for (; s.ok() ; s++) {
+ Real x = s->hpos()-x0;
+ s->set_stemend(left_pos + slope * x);
+ }
+}
+
+void
+Beam::calculate()
+{
+ assert(stems.size()>1);
+ if (!dir)
+ set_default_dir();
+
+ solve_slope();
+ set_stemlens();
+}
+
+void
+Beam::process()
+{
+ calculate();
+ brew_molecule();
+}
+
+
+// todo.
+Spanner *
+Beam::broken_at(const PCol *, const PCol *) const
+{
+ return new Beam(*this);
+}
+
+void
+Beam::preprocess()
+{
+ left = (*stems.top()) ->pcol_;
+ right = (*stems.bottom())->pcol_;
+}
+
+Interval
+Beam::height() const
+{
+ return output->extent().y;
+}
+
+Interval
+Beam::width() const
+{
+ Beam * me = (Beam*) this; // ugh
+ return Interval( (*me->stems.top()) ->hpos(),
+ (*me->stems.bottom()) ->hpos() );
+}
+
+void
+Beam::brew_molecule()
+{
+ Real inter=paper()->interline()/2;
+ Real sl = slope*inter;
+ Real w = width().length() + paper()->rule_thickness();
+ Symbol s = paper()->lookup_->beam(sl,w);
+
+ Atom a(s);
+
+ Real dx = width().min -left->hpos;
+ a.translate(Offset(dx,left_pos*inter));
+ output = new Molecule(a);
+}
+
+void
+Beam::print()const
+{
+ mtor << "Beam, slope " <<slope << "left ypos " << left_pos<<'\n';
+}
+
--- /dev/null
+/*
+
+ Code to generate beams for TeX
+
+ */
+
+ #include <math.h>
+#include "symbol.hh"
+#include "molecule.hh"
+#include "tex.hh"
+#include "symtable.hh"
+#include "dimen.hh"
+#include "lookup.hh"
+
+Symbol
+Lookup::beam_element(int sidx, int widx, Real slope)
+{
+ Symbol bs=(*symtables_)("beamslopes")->lookup("slope");
+
+ svec<String> args;
+ args.add(sidx);
+ args.add(widx);
+ bs.tex = substitute_args(bs.tex,args);
+ int w = 2 << widx;
+ Real width = convert_dimen(w,"pt");
+ bs.dim.x = Interval(0,width);
+ bs.dim.y = Interval(0,width*slope);
+ return bs;
+}
+
+// ugh.. hard wired tex-code.
+static int
+slope_index(Real &s)
+{
+ assert(ABS(s) < 0.45);
+ int i = int(rint(s * 20.0));
+
+ s = i/20.0;
+ if (s>0)
+ return 6*i +122;
+ else
+ return -6 * i+ 188;
+}
+
+Symbol
+Lookup::rule_symbol(Real height, Real width)
+{
+ Symbol bs=(*symtables_)("beamslopes")->lookup("horizontal");
+ svec<String> args;
+ args.add(print_dimen(height));
+ args.add(print_dimen(width));
+ bs.tex = substitute_args(bs.tex,args);
+ bs.dim.x = Interval(0,width);
+ bs.dim.y = Interval(0,height);
+ return bs;
+}
+
+Symbol
+Lookup::beam(Real &slope, Real width)
+{
+ int sidx = slope_index(slope);
+ if (!slope)
+ return rule_symbol(convert_dimen(2,"pt"), width);
+
+ Real w = width;
+ Real elemwidth = convert_dimen(64,"pt");
+ int widx = 5;
+
+ Molecule m;
+ Real dy=0;
+ Real minwid =convert_dimen(2,"pt");
+ assert(w > minwid);
+ while (w > minwid) {
+ while (elemwidth > w) {
+ widx --;
+ elemwidth /= 2.0;
+ }
+
+ Atom a(beam_element(sidx, widx, slope));
+ a.translate(Offset(0, dy));
+ m.add_right(a);
+ dy += elemwidth*slope;
+ w -= elemwidth;
+ }
+
+ widx = 0;
+ Atom a(beam_element(sidx, widx, slope));
+ a.translate(Offset(width -minwid, (width-minwid) * slope));
+ m.add(a);
+
+ Symbol ret;
+ ret.tex = m.TeXstring();
+ ret.dim.y = Interval(0,width*slope);
+ ret.dim.x = Interval(0,width);
+
+ return ret;
+}
+
+