From eb30c110377bd94cf7647e6105b39afe234ad8e2 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sat, 21 Dec 1996 14:00:03 +0100 Subject: [PATCH] release: 0.0.19 --- .dstreamrc | 5 +- NEWS | 4 + Sources.make | 3 +- Variables.make | 5 +- dimen.tex | 2 +- flower/Makefile | 3 +- flower/Sources.make | 5 +- flower/Variables.make | 6 +- flower/assoc.hh | 10 +- flower/associter.hh | 4 +- flower/cursor.hh | 1 + flower/dstream.cc | 2 +- flower/fproto.hh | 2 +- flower/iterate.hh | 2 + flower/list.hh | 25 ++- flower/list.tcc | 9 +- flower/pcursor.hh | 16 +- flower/pcursor.tcc | 16 ++ flower/plist.hh | 4 +- flower/plist.tcc | 11 +- flower/smat.cc | 12 +- flower/smat.hh | 6 +- flower/sstack.hh | 10 +- flower/textdb.cc | 4 +- flower/textdb.hh | 10 +- flower/tsmat.hh | 6 +- flower/tvsmat.hh | 6 +- flower/unionfind.hh | 4 +- flower/{vray.hh => varray.hh} | 31 ++-- flower/vector.hh | 10 +- flower/vsmat.hh | 6 +- hdr/beam.hh | 5 +- hdr/grouping.hh | 42 +++-- hdr/inputcommand.hh | 7 +- hdr/inputcommands.hh | 16 +- hdr/molecule.hh | 2 +- hdr/moment.hh | 36 +++++ hdr/notehead.hh | 5 +- hdr/proto.hh | 4 + hdr/simplewalker.hh | 3 +- hdr/spanner.hh | 15 +- hdr/staffcommands.hh | 12 +- hdr/stcol.hh | 6 +- hdr/stem.hh | 6 + lilyponddefs.tex | 20 ++- maartje.ly | 13 +- src/beam.cc | 50 ++++-- src/debug.cc | 8 + src/grouping.cc | 295 +++++++++++++++++++++++----------- src/inputcommand.cc | 27 +++- src/inputcommands.cc | 136 ++++++++-------- src/melodicstaff.cc | 2 +- src/misc.cc | 4 + src/molecule.cc | 2 +- src/moment.cc | 58 +++++++ src/notehead.cc | 11 +- src/simplewalker.cc | 46 ++++-- src/spanner.cc | 4 + src/staff.cc | 22 ++- src/staffcommands.cc | 51 +++--- src/staffline.cc | 3 +- src/stcol.cc | 10 +- src/stem.cc | 23 ++- src/swalker.cc | 6 +- src/table.cc | 8 - src/template3.cc | 4 +- src/texbeam.cc | 41 ++--- symbol.ini | 30 ++-- 68 files changed, 855 insertions(+), 418 deletions(-) create mode 100644 flower/pcursor.tcc rename flower/{vray.hh => varray.hh} (88%) create mode 100644 hdr/moment.hh create mode 100644 src/moment.cc diff --git a/.dstreamrc b/.dstreamrc index be1953b0de..1d35c0489b 100644 --- a/.dstreamrc +++ b/.dstreamrc @@ -33,5 +33,6 @@ Score 0 Voice 0 Voice_element 1 Input_cursor 1 -Commands_at 0 -Input_command 1 \ No newline at end of file +Commands_at 1 +Input_command 1 +Moment 0 \ No newline at end of file diff --git a/NEWS b/NEWS index 34a2deafd2..ab7f8437f6 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +pl 19: + - struct Moment + - grouping code: LilyPond can set advanced multibeams. + pl 18: - robust Staff_commands diff --git a/Sources.make b/Sources.make index 4545a011b2..53977c778b 100644 --- a/Sources.make +++ b/Sources.make @@ -17,11 +17,12 @@ hdr= qlp.hh linespace.hh qlpsolve.hh\ clef.hh clefitem.hh slur.hh inputcommands.hh\ getcommand.hh inputmusic.hh \ inputscore.hh inputstaff.hh identparent.hh\ - inputcommand.hh grouping.hh + inputcommand.hh grouping.hh moment.hh mycc= qlp.cc qlpsolve.cc leastsquares.cc\ inputcommands.cc inputmusic.cc \ inputscore.cc inputstaff.cc\ + moment.cc\ break.cc linespace.cc molecule.cc staffline.cc\ pscore.cc tex.cc item.cc pcol.cc staff.cc \ rhythmstaff.cc score.cc note.cc main.cc misc.cc\ diff --git a/Variables.make b/Variables.make index 6e67b107d3..32bffdfc97 100644 --- a/Variables.make +++ b/Variables.make @@ -37,10 +37,13 @@ endif # version info MAJVER=0 MINVER=0 -PATCHLEVEL=18 +PATCHLEVEL=19 VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) CXXVER=`$(CXX) --version` +#flower version +NEEDEFLOWERVER=1.0.16 + # directories TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) OBJECTDIR=objects diff --git a/dimen.tex b/dimen.tex index 962ec5d5b7..f1c9bad686 100644 --- a/dimen.tex +++ b/dimen.tex @@ -1,4 +1,4 @@ -\font\musicfnt=musix16 +\font\musicfnt=musix20 \font\slurfont=xslhu20 \def\thefont{\musicfnt} diff --git a/flower/Makefile b/flower/Makefile index 89e3bd6f5c..ed618974eb 100644 --- a/flower/Makefile +++ b/flower/Makefile @@ -8,7 +8,6 @@ include depend depend: Sources.make $(CXX) -MM $(cc) > depend - clean: rm -f $(obs) $(staticlib) @@ -25,6 +24,6 @@ dist: tar cfz $(DNAME).tar.gz $(DDIR)/* rm -rf $(DDIR)/ -TAGS: +TAGS: $(ALLSOURCES) etags -CT $(inl) $(cc) $(hh) diff --git a/flower/Sources.make b/flower/Sources.make index 2a618814c3..eae2acaf4d 100644 --- a/flower/Sources.make +++ b/flower/Sources.make @@ -3,11 +3,12 @@ cc=lgetopt.cc string.cc dataf.cc textdb.cc unionfind.cc \ smat.cc matrix.cc choleski.cc vector.cc dstream.cc\ matdebug.cc scalar.cc -templatecc=cursor.tcc list.tcc tsmat.tcc plist.tcc interval.tcc +templatecc=cursor.tcc list.tcc tsmat.tcc plist.tcc interval.tcc\ + pcursor.tcc inl=findcurs.inl link.inl list.inl cursor.inl plist.inl hh=cursor.hh pcursor.hh lgetopt.hh link.hh list.hh dstream.hh \ - string.hh stringutil.hh vray.hh textdb.hh textstr.hh assoc.hh\ + string.hh stringutil.hh varray.hh textdb.hh textstr.hh assoc.hh\ findcurs.hh unionfind.hh compare.hh handle.hh matrix.hh\ smat.hh vsmat.hh vector.hh real.hh choleski.hh\ tsmat.hh tvsmat.hh plist.hh associter.hh fproto.hh\ diff --git a/flower/Variables.make b/flower/Variables.make index 7d6f0479a5..c1801c14c4 100644 --- a/flower/Variables.make +++ b/flower/Variables.make @@ -1,6 +1,6 @@ MAJVER=1 MINVER=0 -PATCHLEVEL=18 +PATCHLEVEL=19 PACKAGENAME=flower #PROFILEFLAG=-pg @@ -31,7 +31,7 @@ include Sources.make obs=$(cc:.cc=.o) staticlib=libflower.a - -DFILES=$(hh) $(cc) $(inl) $(templatecc) Makefile Variables.make make_version\ +ALLSOURCES=$(hh) $(cc) $(inl) $(templatecc) +DFILES=$(ALLSOURCES) Makefile Variables.make make_version\ Sources.make TODO README DDIR=$(DNAME) diff --git a/flower/assoc.hh b/flower/assoc.hh index 3a49c8a058..d17b10a70b 100644 --- a/flower/assoc.hh +++ b/flower/assoc.hh @@ -1,7 +1,7 @@ #ifndef ASSOC_HH #define ASSOC_HH -#include "vray.hh" +#include "varray.hh" #include template @@ -13,12 +13,12 @@ struct Assoc_ent_ { template struct Assoc { - svec< Assoc_ent_ > arr; + Array< Assoc_ent_ > arr; /****************/ int find(K key) const { - for (int i = 0; i < arr.sz(); i++) { + for (int i = 0; i < arr.size(); i++) { if (!arr[i].free && key == arr[i].key) return i; } @@ -26,7 +26,7 @@ struct Assoc { } int find_creat(K key) { int free = -1; - for (int i = 0; i < arr.sz(); i++) { + for (int i = 0; i < arr.size(); i++) { if (key == arr[i].key) { return i; } else if (arr[i].free ) { @@ -43,7 +43,7 @@ struct Assoc { ae.free = false; ae.key = key; arr.add(ae); - return arr.sz() -1; + return arr.size() -1; } public: bool elt_query(K key) const { diff --git a/flower/associter.hh b/flower/associter.hh index 0902c3953d..bb312b8e9e 100644 --- a/flower/associter.hh +++ b/flower/associter.hh @@ -21,12 +21,12 @@ struct Assoc_iter { i= next(0); } int next(int j) { - while (j < assoc_.arr.sz() && assoc_.arr[j].free) + while (j < assoc_.arr.size() && assoc_.arr[j].free) j++; return j; } bool ok() const { - return i < assoc_.arr.sz(); + return i < assoc_.arr.size(); } void OK()const { assert(!ok() || !assoc_.arr[i].free); diff --git a/flower/cursor.hh b/flower/cursor.hh index c6a8584335..1484770688 100644 --- a/flower/cursor.hh +++ b/flower/cursor.hh @@ -18,6 +18,7 @@ class Cursor Cursor( const Cursor& cursor ); T& thing(); + /// return current T T& operator *() { return thing(); } operator T() { return thing(); } diff --git a/flower/dstream.cc b/flower/dstream.cc index b4267f3502..fc50506195 100644 --- a/flower/dstream.cc +++ b/flower/dstream.cc @@ -114,7 +114,7 @@ Dstream::Dstream(ostream *r, const char * cfg_nm ) Text_db cfg(fn); while (! cfg.eof()){ Text_record r( cfg++); - if (r.sz() != 2) { + if (r.size() != 2) { r.message("not enough fields in Dstream init."); continue; } diff --git a/flower/fproto.hh b/flower/fproto.hh index 4452176d19..dcd17595d0 100644 --- a/flower/fproto.hh +++ b/flower/fproto.hh @@ -7,7 +7,7 @@ #ifndef FPROTO_HH #define FPROTO_HH -template struct svec; +template struct Array; template struct sstack; template struct Assoc; template struct List; diff --git a/flower/iterate.hh b/flower/iterate.hh index adff7792bb..33dbb16a4c 100644 --- a/flower/iterate.hh +++ b/flower/iterate.hh @@ -1,6 +1,8 @@ #define iterator(set) typeof((set).top()) +#define iterator_bot(set) typeof((set).bottom()) // should use top() #define iter_top(set,var) iterator(set) var(set) +#define iter_bot(set,var) iterator(set) var(set.bottom()) diff --git a/flower/list.hh b/flower/list.hh index f49b5d7850..4a4aab2f5b 100644 --- a/flower/list.hh +++ b/flower/list.hh @@ -29,11 +29,15 @@ class List void concatenate(List const &s); - /// make *this empty void set_empty(); /** - WARNING: contents lost, and not deleted. + + POST: + size == 0 + + WARNING: + contents lost, and not deleted. */ /// add after after_me @@ -41,13 +45,20 @@ class List /// put thing before #before_me# void insert( const T& thing, Cursor &before_me ); - virtual void remove( Cursor me ); - /** - Remove link pointed to by me. + + void remove( Cursor me ); + /** Remove link pointed to by me. Destructor of contents called + (nop for pointers) POST - none; WARNING: do not use #me#. - */ + none; + + + WARNING: do not use #me# after calling + */ + + /****************/ + int size_; Link* top_; Link* bottom_; diff --git a/flower/list.tcc b/flower/list.tcc index 55e1e20507..37ded81bbe 100644 --- a/flower/list.tcc +++ b/flower/list.tcc @@ -38,12 +38,9 @@ List::OK() const template List::~List() { - Cursor next(*this); - for ( Cursor c( *this ); c.ok(); c = next ) { - next = c; - next++; - remove( c ); - } + Cursor c(*this); + while (c.ok()) + c.del(); } template diff --git a/flower/pcursor.hh b/flower/pcursor.hh index eeaa866ea8..383a450a1a 100644 --- a/flower/pcursor.hh +++ b/flower/pcursor.hh @@ -13,10 +13,22 @@ template struct PCursor : private Cursor { friend class IPointerList; + + /// delete contents + void junk(); public: Cursor::ok; - Cursor::del; - Cursor::backspace; + void del() { junk(); Cursor::del(); } + void backspace() { junk(); Cursor::backspace(); } + T get() { + T p = ptr(); + Cursor::del(); + return p; + } + T get_prev() { + (*this)--; + return get(); + } PointerList &list() { return (PointerList&)Cursor::list(); } PCursor operator++(int) { return Cursor::operator++(0);} diff --git a/flower/pcursor.tcc b/flower/pcursor.tcc new file mode 100644 index 0000000000..ffb01bcfe8 --- /dev/null +++ b/flower/pcursor.tcc @@ -0,0 +1,16 @@ +#include "pcursor.hh" + +template +void +PCursor::junk() +{ +#if !defined(NDEBUG) && defined(PARANOID) + list().OK(); +#endif + + delete ptr(); +#if !defined(NDEBUG)&&defined(PARANOID) + thing() = 0; + list().OK(); +#endif +} diff --git a/flower/plist.hh b/flower/plist.hh index bac9f7bf02..0aedfba60b 100644 --- a/flower/plist.hh +++ b/flower/plist.hh @@ -34,9 +34,7 @@ template struct IPointerList : public PointerList { IPointerList(const IPointerList&) { set_empty(); } IPointerList() { } -protected: - virtual void remove( Cursor me ) { remove (PCursor(me)); } - virtual void remove( PCursor me ); + ~IPointerList(); }; /** NOTE: diff --git a/flower/plist.tcc b/flower/plist.tcc index 2581d24279..69986035d2 100644 --- a/flower/plist.tcc +++ b/flower/plist.tcc @@ -1,15 +1,14 @@ #include "plist.hh" -// not inlined since it assumes knowledge of destructor. template -void -IPointerList::remove(PCursor me ) +IPointerList::~IPointerList() { - if ( me.ok() ) { - delete me.ptr(); - List::remove(me); + PCursor c( *this ); + while (c.ok()) { + c.del(); } } + template PCursor PointerList::find(T what ) const diff --git a/flower/smat.cc b/flower/smat.cc index 93726ec08a..c2177d4c99 100644 --- a/flower/smat.cc +++ b/flower/smat.cc @@ -14,18 +14,22 @@ Full_storage::operator=(Full_storage const &fs) void Full_storage::OK() const { + #ifndef NDEBUG // static Real dummy; assert(maxh >= h && maxw >= w); assert(h >= 0 && w >= 0); assert(els||!maxh); if (maxh>0) { // access outer elts. Real *r = els[maxh -1]; + #if 0 if (maxw>0) { assert(r); Real s = r[maxw -1]; // accessing unitialised memory. s = sin(s); } + #endif } + #endif } void Full_storage::resize_cols(int newh) @@ -148,20 +152,20 @@ Full_storage::insert_row(int k) } -svec +Array Full_storage::row(int n) const { - svec r; + Array r; for (int j = 0; j < w; j++) r.add(els[n][j]); return r; } -svec +Array Full_storage::column(int n) const { - svec r; + Array r; for (int i = 0; i row(int i) const; - virtual svec column(int j) const; + virtual Array row(int i) const; + virtual Array column(int j) const; Full_storage() { init(); diff --git a/flower/sstack.hh b/flower/sstack.hh index fa21392de0..fb4d68c3a5 100644 --- a/flower/sstack.hh +++ b/flower/sstack.hh @@ -7,22 +7,22 @@ #ifndef SSTACK_HH #define SSTACK_HH -#include "vray.hh" +#include "varray.hh" -/// A simple stack based on svec. +/// A simple stack based on Array. template -struct sstack : svec { +struct sstack : Array { T top() { return last(); } T pop() { assert(!empty()); T l = last(); - svec::pop(); + Array::pop(); return l; } void push(T l) { add(l); } }; /** - Same as for #svec# goes here. + Same as for #Array# goes here. */ diff --git a/flower/textdb.cc b/flower/textdb.cc index 4c10139583..d94b64ab79 100644 --- a/flower/textdb.cc +++ b/flower/textdb.cc @@ -27,7 +27,7 @@ Text_db::get_record() { while (1) { String s; - svec fields; + Array fields; assert(!eof()); while ((s = get_word()) != "") @@ -40,7 +40,7 @@ Text_db::get_record() if (get_line() != "") assert(false); - assert (fields.sz()); + assert (fields.size()); return Text_record(fields, get_name(), line()); } } diff --git a/flower/textdb.hh b/flower/textdb.hh index bea0c4521e..afb04f0725 100644 --- a/flower/textdb.hh +++ b/flower/textdb.hh @@ -5,8 +5,8 @@ /**: do "#" comments, read quote enclosed fields */ -/// a "const" svec. Contents can't be changed. -class Text_record : svec +/// a "const" Array. Contents can't be changed. +class Text_record : Array { int line_no; String filename; @@ -19,13 +19,13 @@ public: cerr << '\n'<< filename << ": "<< line_no << s << "\n"; } String operator[](int j) { - return svec::operator[](j); + return Array::operator[](j); } - Text_record(svec s, String fn, int j) : svec(s) { + Text_record(Array s, String fn, int j) : Array(s) { filename = fn; line_no = j; } - svec::sz; + Array::size; }; /// abstraction for a datafile diff --git a/flower/tsmat.hh b/flower/tsmat.hh index 0fe3f7af79..e8dac44e6e 100644 --- a/flower/tsmat.hh +++ b/flower/tsmat.hh @@ -1,6 +1,6 @@ #ifndef SMAT_HH #define SMAT_HH -#include "vray.hh" +#include "varray.hh" #include "vsmat.hh" /// simplest matrix storage. refer to its baseclass for the doco. @@ -60,8 +60,8 @@ public: assert(valid(i,j)); return els[i][j]; } - virtual svec row(int i) const; - virtual svec column(int j) const; + virtual Array row(int i) const; + virtual Array column(int j) const; Full_storage() { init(); diff --git a/flower/tvsmat.hh b/flower/tvsmat.hh index 5e79634b55..32f981d2e9 100644 --- a/flower/tvsmat.hh +++ b/flower/tvsmat.hh @@ -1,6 +1,6 @@ #ifndef VSMAT_HH #define VSMAT_HH -#include "vray.hh" +#include "varray.hh" /// a matrix storage baseclass. class virtual_smat { @@ -62,8 +62,8 @@ public: virtual const Real& elem(int i, int j) const = 0; #if 1 - virtual svec row(int i) const = 0; - virtual svec column(int j) const = 0; + virtual Array row(int i) const = 0; + virtual Array column(int j) const = 0; #endif /// add a row diff --git a/flower/unionfind.hh b/flower/unionfind.hh index 8fcc6b438e..523321ff5f 100644 --- a/flower/unionfind.hh +++ b/flower/unionfind.hh @@ -1,6 +1,6 @@ #ifndef UNIONFIND_HH #define UNIONFIND_HH -#include "vray.hh" +#include "varray.hh" /// which points of a graph are connected? struct Union_find { @@ -10,7 +10,7 @@ struct Union_find { Union_find(int sz); private: - svec classes; + Array classes; }; /* diff --git a/flower/vray.hh b/flower/varray.hh similarity index 88% rename from flower/vray.hh rename to flower/varray.hh index 39913fc423..bfc6b984fa 100644 --- a/flower/vray.hh +++ b/flower/varray.hh @@ -4,8 +4,8 @@ Distributed under GNU GPL */ -#ifndef SVEC_H -#define SVEC_H +#ifndef ARRAY_H +#define ARRAY_H #include /// copy a bare (C-)array from #src# to #dest# sized #count# @@ -17,9 +17,9 @@ inline void arrcpy(T*dest, T*src, int count) { ///scaleable array template, for T with def ctor. template -class svec { +class Array { protected: - + /// maximum length of array. int max; /// the data itself @@ -46,22 +46,21 @@ public: /// report the size_. See {setsize_} int size() const { return size_; } - int sz() const { return size(); } /// POST: size() == 0 void clear() { size_ = 0; } - svec() { thearray = 0; max =0; size_ =0; } + Array() { thearray = 0; max =0; size_ =0; } /// set the size_ to #s# void set_size(int s) { if (s >= max) remax(s); size_ = s; } - /** POST: sz() == s. + /** POST: size() == s. Warning: contents are unspecified */ - ~svec() { delete[] thearray; } + ~Array() { delete[] thearray; } /// return a "new"ed copy of array T* copy_array() const { @@ -73,11 +72,11 @@ public: operator T* () const { return copy_array(); } - void operator=(svec const & src) { + void operator=(Array const & src) { set_size (src.size_); arrcpy(thearray,src.thearray, size_); } - svec(const svec & src) { + Array(const Array & src) { thearray = src.copy_array(); max = size_ = src.size_; } @@ -85,7 +84,7 @@ public: /// tighten array size_. void precompute () { remax(size_); } - /// this makes svec behave like an array + /// this makes Array behave like an array T &operator[] (const int i) const { assert(i >=0&&i= upper) return; @@ -145,16 +144,16 @@ public: swap( ++last,i); swap(lower, last); sort(compare, lower, last-1); - sort(compare, last+1, lower); + sort(compare, last+1, upper); } - void concat(svec const &src) { + void concat(Array const &src) { int s = size_; set_size(size_ + src.size_); arrcpy(thearray+s,src.thearray, src.size_); } - svec subvec(int lower, int upper) { + Array subvec(int lower, int upper) { assert(lower >= 0 && lower <=upper&& upper <= size_); - svec r; + Array r; int s =upper-lower; r.set_size(s); arrcpy(r.thearray, thearray + lower, s); diff --git a/flower/vector.hh b/flower/vector.hh index 1929c674a9..2fdf41482a 100644 --- a/flower/vector.hh +++ b/flower/vector.hh @@ -3,7 +3,7 @@ #include #include "real.hh" -#include "vray.hh" +#include "varray.hh" class Dstream; class String; @@ -11,10 +11,10 @@ void set_matrix_debug(Dstream&ds); /// a row of numbers class Vector { - svec dat; + Array dat; public: void OK() const { dat.OK();} - int dim() const { return dat.sz(); } + int dim() const { return dat.size(); } Vector() { } Vector(const Vector&n); Vector(int n) { @@ -69,13 +69,13 @@ public: Real norm_sq() { return ((*this) * (*this)); } - operator svec () { return dat; } + operator Array () { return dat; } void print() const; /// set to j-th element of unit-base void set_unit(int j) ; }; /** - a vector. Storage is handled in svec, Vector only does the mathematics. + a vector. Storage is handled in Array, Vector only does the mathematics. */ inline Vector diff --git a/flower/vsmat.hh b/flower/vsmat.hh index 4e1ea797b6..3112ae9b25 100644 --- a/flower/vsmat.hh +++ b/flower/vsmat.hh @@ -1,6 +1,6 @@ #ifndef VSMAT_HH #define VSMAT_HH -#include "vray.hh" +#include "varray.hh" #include "real.hh" /// a matrix storage baseclass. class virtual_smat { @@ -62,8 +62,8 @@ public: virtual const Real& elem(int i, int j) const = 0; #if 1 - virtual svec row(int i) const = 0; - virtual svec column(int j) const = 0; + virtual Array row(int i) const = 0; + virtual Array column(int j) const = 0; #endif /// add a row diff --git a/hdr/beam.hh b/hdr/beam.hh index 60b5dedd71..0032b67e17 100644 --- a/hdr/beam.hh +++ b/hdr/beam.hh @@ -18,6 +18,8 @@ struct Beam: public Spanner { /// -1 below heads, +1 above heads. int dir; + Rhythmic_grouping *group; + /****************/ virtual Interval width()const; @@ -31,8 +33,9 @@ struct Beam: public Spanner { void preprocess(); Interval height()const; void print() const; - + void set_grouping(Rhythmic_grouping def, Rhythmic_grouping current); void set_stemlens(); + ~Beam(); private: Molecule stem_beams(Stem *here, Stem *next, Stem *prev); void solve_slope(); diff --git a/hdr/grouping.hh b/hdr/grouping.hh index 21a4b4b70f..da1ddd2ce3 100644 --- a/hdr/grouping.hh +++ b/hdr/grouping.hh @@ -11,28 +11,44 @@ #include "vray.hh" - +/// data structure which represents rhythmic units struct Rhythmic_grouping { - svec divisions; + svec children; - + Interval *interval_; + /****************/ - svec interior(); - Rhythmic_grouping partial_grouping(Interval t); + svec intervals(); + Interval interval()const; Real length() const; - Interval time() const; - Rhythmic_grouping(Interval); - Rhythmic_grouping(); - Rhythmic_grouping(svec); - Rhythmic_grouping(Rhythmic_grouping const&); + void intersect(Interval); + void operator=(Rhythmic_grouping const&); + Rhythmic_grouping(Rhythmic_grouping const&); + Rhythmic_grouping(Interval, int n=1); + Rhythmic_grouping(); + Rhythmic_grouping(svec); + ~Rhythmic_grouping(); + + void add_child(Real start, Real len); + void split(Rhythmic_grouping r); - void split(svec); - void intersect(Interval); + void split(svec); void split(int n); + void print() const; void OK() const; - ~Rhythmic_grouping(); + + svec generate_beams(svec, int&); + +private: + void junk(); + void copy(Rhythmic_grouping const&); }; +/** + this is a tree. It groupes notes according to rules + + */ + #endif diff --git a/hdr/inputcommand.hh b/hdr/inputcommand.hh index 47882a2374..fff2f1a1f3 100644 --- a/hdr/inputcommand.hh +++ b/hdr/inputcommand.hh @@ -24,8 +24,11 @@ Input_command* get_key_interpret_command(svec); Input_command* get_clef_interpret_command(String w); Input_command *get_reset_command(); Input_command *get_partial_command(Real u); -Input_command* get_skip_command( int,Real); -Input_command* get_grouping_command( svec); +Input_command *get_skip_command(int,Real); +Input_command *get_grouping_command(Real,svec); +Input_command *get_grouping_command(svec); Input_command *get_bar_command( ); + +svec get_default_grouping(int count); #endif // INPUTCOMMAND_HH diff --git a/hdr/inputcommands.hh b/hdr/inputcommands.hh index c5b594359b..527986e6ea 100644 --- a/hdr/inputcommands.hh +++ b/hdr/inputcommands.hh @@ -11,21 +11,15 @@ #include "proto.hh" #include "plist.hh" #include "real.hh" +#include "moment.hh" struct Commands_at : public IPointerList { - Real when; - - /// current measure info - Real whole_per_measure; - - /// where am i - Real whole_in_measure; - - /// idem + Moment moment_; - int bars; - /****************/ + + Real when(); + void parse(Staff_commands_at*); void print() const; Real barleft(); void add(Input_command*); diff --git a/hdr/molecule.hh b/hdr/molecule.hh index 83f8ac1e2c..b5df9ee383 100644 --- a/hdr/molecule.hh +++ b/hdr/molecule.hh @@ -38,7 +38,7 @@ struct Molecule { void add_right(const Molecule &m); void add_left(const Molecule &m); void add_top(const Molecule &m); - void add_bot(const Molecule &m); + void add_bottom(const Molecule &m); void add(Molecule const &m); void translate(Offset); void add(Atom a) { ats.bottom().add(new Atom(a)); } diff --git a/hdr/moment.hh b/hdr/moment.hh new file mode 100644 index 0000000000..83910b1a31 --- /dev/null +++ b/hdr/moment.hh @@ -0,0 +1,36 @@ +/* + moment.hh -- part of LilyPond + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef MOMENT_HH +#define MOMENT_HH + +#include "real.hh" + + +struct Moment { + Real when; + /// current measure info + Real whole_per_measure; + + /// where am i + Real whole_in_measure; + + /// how long is one beat? + Real one_beat; + + /// idem + int bars; + /****************/ + void OK() const; + Moment(Real, const Moment*); + void print() const; + void setpartial(Real p); + Real barleft(); + void set_meter(int,int); +}; + +#endif // MOMENT_HH + diff --git a/hdr/notehead.hh b/hdr/notehead.hh index 3137a1e558..317d74cc3e 100644 --- a/hdr/notehead.hh +++ b/hdr/notehead.hh @@ -17,7 +17,8 @@ struct Notehead : public Item int staff_size; int dots; int balltype; - + int x_dir; + /****************/ void preprocess(); @@ -28,7 +29,7 @@ struct Notehead : public Item */ void print()const; - + static int compare(Notehead*&a, Notehead*&b) ; private: void brew_molecole(); }; diff --git a/hdr/proto.hh b/hdr/proto.hh index 09465e3e85..217b2f7f58 100644 --- a/hdr/proto.hh +++ b/hdr/proto.hh @@ -92,4 +92,8 @@ struct Input_command; struct Notename_tab; struct Input_file; struct Keyword_table; +struct Rhythmic_grouping; +struct Staff_commands_at ; +struct Commands_at ; +struct Moment; #endif // PROTO_HH diff --git a/hdr/simplewalker.hh b/hdr/simplewalker.hh index 2631f8b983..6394bc79db 100644 --- a/hdr/simplewalker.hh +++ b/hdr/simplewalker.hh @@ -24,7 +24,8 @@ struct Simple_walker: Staff_walker { bool processed_clef; Clef clef_; Rhythmic_grouping default_grouping; - Rhythmic_grouping current_grouping; + Rhythmic_grouping *current_grouping; + Real inbar; svec pending_slur_reqs; svec pending_slurs; diff --git a/hdr/spanner.hh b/hdr/spanner.hh index 8a22985819..cfaca3dec9 100644 --- a/hdr/spanner.hh +++ b/hdr/spanner.hh @@ -19,7 +19,7 @@ struct Spanner { String TeXstring () const ; Spanner(); Paperdef*paper() const; - + virtual ~Spanner(); virtual Interval height()const=0; /** PRE: @@ -39,7 +39,18 @@ struct Spanner { */ virtual void print() const; }; -/** Spanner should know about the items which it should consider: +/** + A spanner is a symbol whose appearance can only be calculated after the breaking problem is solved. + + Examples + + - (de)crescendo + - slur + - beam + - bracket + + + Spanner should know about the items which it should consider: e.g. slurs should be steep enough to "enclose" all those items. This is absolutely necessary for beams, since they have to adjust the length of stems of notes they encompass. diff --git a/hdr/staffcommands.hh b/hdr/staffcommands.hh index 7573595a37..2fb564eb62 100644 --- a/hdr/staffcommands.hh +++ b/hdr/staffcommands.hh @@ -8,16 +8,17 @@ #include "command.hh" #include "vray.hh" #include "plist.hh" +#include "moment.hh" struct Staff_commands_at : public IPointerList { - Real when; - + Moment moment_; + /****************/ bool is_breakable(); - - Staff_commands_at(Real); + Real when(); + Staff_commands_at(Moment); void set_breakable(); void add_command_to_break(Command pre, Command mid,Command post); void print() const; @@ -25,14 +26,13 @@ struct Staff_commands_at : public IPointerList { void insert_between(Command victim, PCursor firstc, PCursor last); void add(Command c); - }; /// the list of commands in Score struct Staff_commands : public IPointerList { Staff_commands_at*find(Real); - void add(Command,Real); + void add(Staff_commands_at*); void clean(Real last); void OK() const; void print() const; diff --git a/hdr/stcol.hh b/hdr/stcol.hh index a620f8795d..823e9e9126 100644 --- a/hdr/stcol.hh +++ b/hdr/stcol.hh @@ -18,8 +18,10 @@ struct Staff_column { svec v_elts; /// idem - svec s_commands; + Staff_commands_at *s_commands; + Moment *moment_; + /****************/ Staff_column(Score_column*s); @@ -33,7 +35,7 @@ struct Staff_column { virtual void process_requests()=0; - virtual ~Staff_column() { } + virtual ~Staff_column(); }; diff --git a/hdr/stem.hh b/hdr/stem.hh index 372011d1b1..ff64a3af91 100644 --- a/hdr/stem.hh +++ b/hdr/stem.hh @@ -7,9 +7,11 @@ #ifndef STEM_HH #define STEM_HH #include "item.hh" +#include "vray.hh" /// the rule attached to the ball struct Stem : public Item { + /// rhythmical length Real note_length; // heads the stem encompasses (positions) @@ -42,6 +44,9 @@ struct Stem : public Item { */ Real stem_xoffset; + + svec heads; + /****************/ /// ensure that this Stem also encompasses the Notehead #n# @@ -52,6 +57,7 @@ struct Stem : public Item { void set_default_dir(); void set_default_stemlen(); void set_default_extents(); + void set_noteheads(); void postprocess(); void preprocess(); Stem(int center, Real duration); diff --git a/lilyponddefs.tex b/lilyponddefs.tex index 5f42c07c51..0c70462bc0 100644 --- a/lilyponddefs.tex +++ b/lilyponddefs.tex @@ -8,6 +8,9 @@ \newdimen\interlinedist \newcount\n \newdimen\balkhoog + \newdimen\notewidth + \newdimen\notewidthhalf + \newdimen\notewidthdouble \newdimen\staffrulethickness \newdimen\interstaffrule @@ -21,6 +24,7 @@ \font\hslurhfont=xslhz20 \font\musicfnt=musix20 \balkhoog=20pt + \notewidth=6pt \staffrulethickness=0.4pt \musixcalc @@ -36,7 +40,7 @@ \font\musicfnt=musix16 \balkhoog=16pt \staffrulethickness=0.4pt - + \notewidth=5pt \musixcalc } @@ -45,6 +49,10 @@ \advance\interstaffrule by-\staffrulethickness \divide\interstaffrule by 4 \advance\interstaffrule by -\staffrulethickness + \notewidthhalf=\notewidth + \notewidthdouble=\notewidth + \divide \notewidthhalf by 2 + \multiply \notewidthdouble by 2 } @@ -119,9 +127,9 @@ }} \def\toplines#1{ % why space needed here? - \vbox to 0pt{\hbox{\kern-6pt\lines{#1}{12pt}}\vss}} + \vbox to 0pt{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}\vss}} \def\botlines#1{ % idem ditto - \vbox to 0pt{\vss\hbox{\kern-6pt\lines{#1}{12pt}}}} + \vbox to 0pt{\vss\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}} % % a staffsymbol with #1 lines, width #2 @@ -140,9 +148,9 @@ \def\csixteenthrest{\vcenter\sixteenthrest} \def\cthirtysecondrest{\vcenter\thirtysecondrest} -\def\lsingledot{\kern-6pt\singledot} -\def\ldoubledot{\kern-6pt\doubledot} -\def\ltripledot{\kern-6pt\tripledot} +\def\lsingledot{\kern-\notewidth\singledot} +\def\ldoubledot{\kern-\notewidth\doubledot} +\def\ltripledot{\kern-\notewidth\tripledot} diff --git a/maartje.ly b/maartje.ly index a0cffa1190..2ce1ab655a 100644 --- a/maartje.ly +++ b/maartje.ly @@ -1,7 +1,8 @@ ritme = staff {rhythmic music {$ c8 - c2 c2 + [a8 a8. a8 a16 a16 a16] c4. + %[c8( )'a8 c8 c8] c2 c2 @@ -11,9 +12,9 @@ ritme = staff {rhythmic [c16 c8.] [c16 c16 c8] [c16 c8 c16] +% [c16 r8 c16] - c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 - + c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $} } @@ -22,7 +23,7 @@ melody= staff { melodic music{$ c8 - r1 + r4 r4 r4 r4 'cis2.. r8 r4 r8 r16 r32 r32 @@ -47,10 +48,10 @@ c8 commands { % skip 0:0.125 - skip 3:0 % BUG!! + skip 3:0%BUG key $ fis cis gis $ skip 2:0 - key $ $ + key $ $%BUG skip 5:0 clef bass } diff --git a/src/beam.cc b/src/beam.cc index a2d58254af..9cb43f5731 100644 --- a/src/beam.cc +++ b/src/beam.cc @@ -9,8 +9,7 @@ #include "stem.hh" #include "paper.hh" #include "lookup.hh" -#include "scalar.hh" - +#include "grouping.hh" struct Stem_info { Real x; @@ -38,6 +37,7 @@ Stem_info::Stem_info(const Stem*s) Beam::Beam() { + group = 0; slope = 0; left_pos = 0.0; dir =0; @@ -120,25 +120,47 @@ Beam::calculate() solve_slope(); } - void Beam::process() { calculate(); - /* - quick and dirty! - */ - for (PCursor i(stems); i.ok(); i++) - i->beams_left = i->beams_right = intlog2(ABS(i->flag)) - 2; - - stems.top()->beams_left = 0; - stems.bottom()->beams_right = 0; - brew_molecule(); set_stemlens(); } +void +Beam::set_grouping(Rhythmic_grouping def, Rhythmic_grouping cur) +{ + def.OK(); + cur.OK(); + assert(cur.children.sz() == stems.size()); + + cur.split(def); + group = new Rhythmic_grouping(cur); + svec b; + { + PCursor s(stems); + svec flags; + for (; s.ok(); s++) { + int f = intlog2(ABS(s->flag))-2; + assert(f>0); + flags.add(f); + } + int fi =0; + b= group->generate_beams(flags, fi); + b.insert(0,0); + b.add(0); + assert(stems.size() == b.sz()/2); + } + + PCursor s(stems); + for (int i=0; i < b.sz() && s.ok(); i+=2, s++) { + s->beams_left = b[i]; + s->beams_right = b[i+1]; + } +} + // todo. Spanner * @@ -258,3 +280,7 @@ Beam::print()const #endif } +Beam::~Beam() +{ + delete group; +} diff --git a/src/debug.cc b/src/debug.cc index eaed33f080..1d27e81359 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include "debug.hh" @@ -19,12 +20,19 @@ mynewhandler() assert(false); } +void +float_handler(int) +{ + cerr << "Floating point exception .. \n"<< flush; + assert(false); +} void debug_init() { set_new_handler(&mynewhandler); set_matrix_debug(monitor); + signal(SIGFPE, float_handler); } bool check_debug=false; diff --git a/src/grouping.cc b/src/grouping.cc index 1d70808fc7..4c77034bd1 100644 --- a/src/grouping.cc +++ b/src/grouping.cc @@ -5,160 +5,275 @@ void Rhythmic_grouping::OK()const { - for (int i= 1; i < divisions.sz(); i++) { - Real dt = divisions[i] - divisions[i-1]; - assert(dt>0); - } - Interval u; - for (int i= 1; i < children.sz(); i++) { - children[i]->OK(); - u.unite(children[i]->time()); - } - + assert(bool(children.sz()) != bool(interval_)); + + for (int i= 0; i < children.sz(); i++) { + children[i]->OK(); + if (i>0) + assert(children[i-1]->interval().max == + children[i]->interval().min); + } } Real Rhythmic_grouping::length() const { - return divisions.last() - divisions[0]; + return interval().length(); +} + +Interval +Rhythmic_grouping::interval()const +{ + if (interval_) + return *interval_; + else + return + Interval(children[0]->interval().min, + children.last()->interval().max); } void Rhythmic_grouping::split(Rhythmic_grouping r) { - svec ir = r.interior(); - split(ir); + if (interval_) + return ; + + r.intersect(interval()); + split(r.intervals()); for (int i= 0; i < children.sz(); i++) { - Rhythmic_grouping here(r.partial_grouping(children[i]->time())); - if (here.divisions.sz() == 2) - here.split(2); - children[i]->split(here); + if (!children[i]->interval_) { + Rhythmic_grouping here(r); + children[i]->split(here); + } } } -svec -Rhythmic_grouping::interior() + +svec +Rhythmic_grouping::intervals() { - svec r(divisions); - r.del(0); - r.pop(); + svec r; + if (interval_ || children.sz() == 1) { + Interval i(interval()); + Interval r1(i), r2(i); + r1.max = r2.min = i.center(); + r.add(r1); r.add(r2); + } else { + for (int i=0; i < children.sz(); i++) + r.add(children[i]->interval()); + } return r; } -void -Rhythmic_grouping::split(int n) +Rhythmic_grouping::Rhythmic_grouping(Interval t, int n) { - assert(divisions.sz() == 2 && children.sz() == 0); - Real dt =(divisions.last()-divisions[0] )/n; - svec r; - for (int i= 0; i <= n; i++) - r.add(divisions[0] +dt *i); - divisions = r; + if (n == 1 || !n) { + interval_ = new Interval(t); + return; + } + Real dt = t.length()/n; + Interval basic = Interval(t.min, t.min+dt); + for (int i= 0; i < n; i++) + children.add(new Rhythmic_grouping( dt*i + basic )); } void Rhythmic_grouping::intersect(Interval t) { - svec r; - for (int i=0; i < divisions.sz(); i++) - if (t.elt_q(divisions[i])) - r.add(divisions[i]); - if (r[0] > t.min ) // todo - r.insert( t.min,0); - if (r.last() < t.max) - r.add(t.max); + if (interval_) { + interval_->intersect(t); + return; + } - divisions = r; - svec nc; for (int i=0; i < children.sz(); i++) { - Interval inter = intersection(t, children[i]->time()); - if (!inter.empty()) { - Rhythmic_grouping*p =new Rhythmic_grouping(*children[i]); - nc.add(p); - p->intersect(inter); + Interval inter = intersection(t, children[i]->interval()); + if (inter.empty() || inter.length() < 1e-8) { + delete children[i]; + children[i] =0; + } else { + children[i]->intersect(t); } - delete children[i]; } - children = nc; -} + for (int i=0; i < children.sz(); ) { + if (!children[i]) + children.del(i); + else + i++; + } -Rhythmic_grouping -Rhythmic_grouping::partial_grouping(Interval t) -{ - Rhythmic_grouping r(*this); - r.intersect(t); - return r; } void -Rhythmic_grouping::split(svec splitpoints) +Rhythmic_grouping::split(svec splitpoints) { - assert(!children.sz()); - svec child; - int j = 0, i=0; + //check on splitpoints.. + int j = 0, i=0, starti = 0, startj = 0; + + svec ch; while (1) { - if ( i >= divisions.sz() || j >= splitpoints.sz()) + if ( i >= children.sz() || j >= splitpoints.sz()) break; - child.add(divisions[i]); - if (divisions[i] < splitpoints[j]) { - i++; - } else if (divisions[i] > splitpoints[j]) { - j ++; + assert( distance( + children[starti]->interval().min, splitpoints[startj].min)<1e-8); + if (children[i]->interval().max < splitpoints[j].max - 1e-8) { + i ++; + } else if (children[i]->interval().max > splitpoints[j].max + 1e-8) { + j ++; } else { - children.add(new Rhythmic_grouping(child)); - child.set_size(1); - child[0] = divisions[i]; + + if (i == starti) { + ch.add(children[i]); + } else { + Rhythmic_grouping *newchild=new Rhythmic_grouping( + children.subvec(starti, i+1)); + + ch.add(newchild); + } + i ++; + j++; + starti = i; + startj = j; + + } } + if (ch.size() != 1) + children = ch; + } + +Rhythmic_grouping::Rhythmic_grouping(svec r) + :children(r) +{ + interval_ =0; } -Rhythmic_grouping::Rhythmic_grouping(svec d) - :divisions(d) +Rhythmic_grouping::~Rhythmic_grouping() { + junk(); } -Rhythmic_grouping::Rhythmic_grouping() + +void +Rhythmic_grouping::copy(Rhythmic_grouping const&s) { + interval_ = (s.interval_)? new Interval(*s.interval_) : 0; + for (int i=0; i < s.children.sz(); i++) + children.add(new Rhythmic_grouping(*s.children[i])); } -Interval -Rhythmic_grouping::time()const + +void +Rhythmic_grouping::operator=(Rhythmic_grouping const &s) { - return Interval(divisions[0], divisions.last()); + junk(); + copy(s); } -Rhythmic_grouping::Rhythmic_grouping(Interval h) + +Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s) { - divisions.add(h.min); - divisions.add(h.max); + copy(s); } -Rhythmic_grouping::~Rhythmic_grouping() +void +Rhythmic_grouping::junk() { + delete interval_; + interval_ = 0; for (int i=0; i < children.sz(); i++) delete children[i]; + children.set_size(0); } - -Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s) -{ - divisions = s.divisions; - for (int i=0; i < s.children.sz(); i++) - children.add(new Rhythmic_grouping(*s.children[i])); -} - void Rhythmic_grouping::print()const { #ifndef NPRINT - mtor << "{ "; - for (int i=0; i < divisions.sz(); i++) { - mtor << divisions[i] << ','; - } + mtor << "{ \n"; + if (interval_) + mtor<<" Interval "<< interval_->str(); for (int i=0; i < children.sz(); i++) { children[i]->print(); } - mtor << "}"; + mtor << "}\n"; #endif } +void +Rhythmic_grouping::add_child(Real start, Real len) +{ + Real stop = start+len; + for (int i=0; i < children.sz(); i ++) { + Interval j=children[i]->interval(); + if (distance (j.min, start)<1e-8 && distance (j.max, stop)<1e-8) { + return; + } + } + + if (children.sz()) + assert ( distance(children.last()->interval().max , start) < 1e-8); + + children.add(new Rhythmic_grouping(Interval(start, stop))); +} + +Rhythmic_grouping::Rhythmic_grouping() +{ + interval_ =0; +} + +int +min_elt(svec v) +{ + int i = 1000; // ugh + for (int j = 0 ; j < v.sz(); j++) + i = i +Rhythmic_grouping::generate_beams(svec flags, int &flagidx) +{ + + assert (!interval_) ; + + svec< svec > children_beams; + for (int i=0; i < children.sz(); i++) { + svec child_beams; + if (children[i]->interval_) { + int f = flags[flagidx++]; + child_beams.add(f); + } else { + child_beams = children[i]-> + generate_beams(flags, flagidx); + } + children_beams.add(child_beams); + } + svec beams; + int lastm, m, nextm; + for (int i=0; i < children_beams.sz(); i++) { + bool add_left = (i >0); + bool add_right = (i < children_beams.sz() -1); + + if (!i) + m = min_elt(children_beams[i]); + if (add_right) + nextm = min_elt(children_beams[i+1]); + + if (children_beams[i].sz() == 1) { + if (add_right) + beams.add(m); + if (add_left) + beams.add(m); + } else { + if (add_left) + beams.add(lastm a ) +{ + Input_command*c = get_grouping_command(a); + c->args.insert(r,1); + return c; +} + Input_command* get_grouping_command(sveca ) { Input_command*c = new Input_command; - c->args.add("GROUPING"); + c->args.add("GROUPING"); for (int i=0; i < a.sz(); i ++) c->args.add(a[i]); @@ -133,3 +141,20 @@ get_clef_interpret_command(String w) c->args.add(w); return c; } + +svec +get_default_grouping(int count) +{ + svec s; + if (!(count % 3 )) { + for (int i=0; i < count/3; i++) + s.add(3); + } else if (!(count %2)) { + for (int i=0; i < count/2; i++) + s.add(2); + }else { + s.add(2); + s.concat(get_default_grouping(count-2)); + } + return s; +} diff --git a/src/inputcommands.cc b/src/inputcommands.cc index 3a27b3801f..59d8eeaae7 100644 --- a/src/inputcommands.cc +++ b/src/inputcommands.cc @@ -1,7 +1,3 @@ -/* - it still sucks. - */ - #include "inputcommands.hh" #include "inputcommand.hh" #include "debug.hh" @@ -13,57 +9,45 @@ void Commands_at::print() const { #ifndef NPRINT - mtor << "Commands_at { at "< cc(*this); cc.ok(); cc++) cc->print(); mtor << "}\n"; #endif } - +Real +Commands_at::when() +{ + return moment_.when; +} Commands_at::Commands_at(Real dt, Commands_at* prev) + : moment_(dt, (prev)? &prev->moment_ : 0) { - if (prev) { - assert(dt >0); - when = prev->when + dt; - whole_per_measure = prev->whole_per_measure; - whole_in_measure = prev->whole_in_measure + dt; - bars = prev->bars; - - while ( whole_in_measure >= whole_per_measure ) { - whole_in_measure -= whole_per_measure; - bars ++; - } - if (!whole_in_measure) { - bottom().add(get_bar_command()); - } - } else { - whole_per_measure = 1; - whole_in_measure =0; - when = 0.0; - bars = 0; + if (prev&& !moment_.whole_in_measure) { + bottom().add(get_bar_command()); } } void Commands_at::add(Input_command *i) { - bottom().add(i); - if (i->args[0] == "METER") { // should check for other meterchanges here. - Real l = i->args[1]; - Real o = i->args[2]; - whole_per_measure = l/o; + bottom().add(i); + + // should check for other meterchanges here. + if (i->args[0] == "METER") { + int l = i->args[1]; + int o = i->args[2]; + moment_.set_meter(l,o); + bottom().add(get_grouping_command( moment_.one_beat, + get_default_grouping(l))); + } } -Commands_at::Commands_at(Commands_at const&src) +Commands_at::Commands_at(Commands_at const&src) : + moment_(src.moment_) { - when = src.when; - whole_in_measure = whole_in_measure; - whole_per_measure = whole_per_measure; - bars = src.bars; - IPointerList &me(*this); const IPointerList &that(src); @@ -73,18 +57,27 @@ Commands_at::Commands_at(Commands_at const&src) void Commands_at::setpartial(Real p) { - if (when) - error_t ("Partial measure only allowed at beginning.", when); - if (p<0||p > whole_per_measure) - error_t ("Partial measure has incorrect size", when); - whole_in_measure = whole_per_measure - p; + moment_.setpartial(p); } + Real Commands_at::barleft() { - return whole_per_measure-whole_in_measure; + return moment_.barleft(); } +void +Commands_at::parse(Staff_commands_at*s) +{ + s->moment_ = moment_; + for (PCursor cc(*this); cc.ok(); cc++) { + if (cc->args.sz() && cc->args[0] !="") { + Command c = **cc; + s->add(c); + + } + } +} /****************/ void @@ -93,11 +86,12 @@ Input_cursor::find_moment(Real w) Real last = when(); while (1) { if (! ok() ) { - *this = PCursor(list().bottom()); + *this = list().bottom(); Real dt = (w - when()) barleft(); - assert(dt >= 0); + Commands_at * c = new Commands_at(dt, *this); - add(c); + assert(c->when() <= w); + add(c); } else if (when() == w ) { return ; } else if (when() > w ) @@ -140,11 +134,11 @@ Input_commands::do_skip(int bars, Real wholes) { while (bars > 0) { Real b = ptr->barleft(); - ptr.find_moment(ptr->when + b); + ptr.find_moment(ptr->when() + b); bars --; } if (wholes) { - ptr.find_moment(ptr->when + wholes); + ptr.find_moment(ptr->when() + wholes); } } @@ -154,21 +148,25 @@ Input_commands::add(Input_command c) { if (c.args[0] == "PARTIAL") { ptr->setpartial(c.args[1]); + } else if (c.args[0] == "GROUPING") { + Input_command *ic = new Input_command(c); + ic->args.insert(ptr->moment_.one_beat, 1); + ptr->add(ic); } else if (c.args[0] == "METER") { int beats_per_meas = c.args[1]; int one_beat = c.args[2]; Input_command *ch = get_meterchange_command(beats_per_meas, one_beat); ptr->add(ch); - } else if (c.args[0] == "KEY" || c.args[0] == "CLEF") { - Input_command *ic = new Input_command(c); - ptr->add(ic); } else if (c.args[0] == "SKIP") { int bars = c.args[1] ; Real wholes= c.args[2]; do_skip(bars, wholes); } else if (c.args[0] == "RESET") { ptr= top(); - } + } else { + Input_command *ic = new Input_command(c); + ptr->add(ic); + } } @@ -178,23 +176,23 @@ Input_commands::parse() const print(); Staff_commands*nc = new Staff_commands; - { /* all pieces should start with a breakable. */ - Command c;//(0.0); - c.code = INTERPRET; - c.args.add("BAR"); - c.args.add("empty"); - nc->add(c,0.0); - } + for (PCursor i(*this); i.ok(); i++) { - for (PCursor i(*this); i.ok(); i++) - for (PCursor cc(**i); cc.ok(); cc++) { - if (cc->args.sz() && cc->args[0] !="") { - Command c = **cc; -// c.when = i->when; - nc->add(c, i->when); - } + Staff_commands_at* s= nc->find(i->when()); + if (!s){ + s = new Staff_commands_at(i->moment_); + nc->add(s); } - + if (!i->when()) { /* all pieces should start with a breakable. */ + Command c;//(0.0); + c.code = INTERPRET; + c.args.add("BAR"); + c.args.add("empty"); + s->add(c); + } + + i->parse(s); + } return nc; } @@ -213,7 +211,7 @@ Input_commands::print() const Real Input_cursor::when()const { - return (*this)->when; + return (*this)->when(); } Input_cursor::Input_cursor(PCursorc) : PCursor(c) diff --git a/src/melodicstaff.cc b/src/melodicstaff.cc index ed4383fced..493e67f05e 100644 --- a/src/melodicstaff.cc +++ b/src/melodicstaff.cc @@ -66,7 +66,7 @@ Melodic_staff::get_rest(Rest_req*rq) { Rest*r = Simple_staff::get_rest(rq); if (rq->balltype <= 2) - r->translate(Offset(0, (NO_LINES-1) * paper()->internote())); + r->translate(Offset(0, NO_LINES * paper()->internote())); return r; } diff --git a/src/misc.cc b/src/misc.cc index 30116303fc..ff99029ec7 100644 --- a/src/misc.cc +++ b/src/misc.cc @@ -6,6 +6,10 @@ Real wholes(int dur, int dots) { + if (!dur) + return 0.0; + + // stupid Intel: doesn't crash if !dur Real f = 1.0/Real(dur); Real delta = f; diff --git a/src/molecule.cc b/src/molecule.cc index a664eeb74a..fb72eb6bf0 100644 --- a/src/molecule.cc +++ b/src/molecule.cc @@ -116,7 +116,7 @@ Molecule::add_top(const Molecule &m) } void -Molecule::add_bot(const Molecule &m) +Molecule::add_bottom(const Molecule &m) { if (!ats.size()) { add(m); diff --git a/src/moment.cc b/src/moment.cc new file mode 100644 index 0000000000..19f8571335 --- /dev/null +++ b/src/moment.cc @@ -0,0 +1,58 @@ +#include "moment.hh" +#include "debug.hh" + +void +Moment::print() const +{ + mtor << " at "<0); + *this = *prev; + when += + dt; + whole_in_measure += dt; + while ( whole_in_measure >= whole_per_measure ) { + whole_in_measure -= whole_per_measure; + bars ++; + } + } else { // default 4/4 + whole_per_measure = 1; + whole_in_measure =0; + one_beat = 0.25; + when = 0.0; + bars = 0; + } +} + +void +Moment::set_meter(int l, int o) +{ + assert(o); + one_beat = 1/Real(o); + whole_per_measure = Real(l) * one_beat; +} + +void +Moment::setpartial(Real p) +{ + if (when) + error_t ("Partial measure only allowed at beginning.", when); + if (p<0||p > whole_per_measure) + error_t ("Partial measure has incorrect size", when); + whole_in_measure = whole_per_measure - p; +} +Real +Moment::barleft() +{ +return whole_per_measure-whole_in_measure; +} diff --git a/src/notehead.cc b/src/notehead.cc index fcbd6745eb..88cb621181 100644 --- a/src/notehead.cc +++ b/src/notehead.cc @@ -8,6 +8,7 @@ Notehead::Notehead(int ss) { + x_dir = 0; staff_size=ss; position = 0; balltype = 0; @@ -18,7 +19,8 @@ void Notehead::print()const { #ifndef NPRINT - mtor << "Head "<position - b->position; +} + void Notehead::brew_molecole() { @@ -49,6 +57,7 @@ Notehead::brew_molecole() dm.translate(Offset(0,dy)); output->add_right(dm); } + output->translate(Offset(x_dir * p->note_width(),0)); bool streepjes = (position<-1)||(position > staff_size+1); if (streepjes) { int dir = sgn(position); diff --git a/src/simplewalker.cc b/src/simplewalker.cc index fcf2558aac..9f5f0033f2 100644 --- a/src/simplewalker.cc +++ b/src/simplewalker.cc @@ -1,3 +1,7 @@ +/* + UGR + */ + #include "request.hh" #include "voice.hh" #include "clef.hh" @@ -19,22 +23,23 @@ Rhythmic_grouping parse_grouping(svec a) { - Rhythmic_grouping ret; Real one_beat =a[0]; a.del(0); svec r; for (int i= 0 ; i < a.sz(); i++) r.add(a[i]); Real here =0.0; + + svec children; for (int i=0; i < r.sz(); i++) { - ret.divisions.add(here); + Real last = here; here += one_beat * r[i]; - Rhythmic_grouping *child =new Rhythmic_grouping(Interval(last, here)); - child->split(r[i]); - ret.children.add(child); + children.add( + new Rhythmic_grouping(Interval(last, here), r[i] ) + ); } - ret.divisions.add(here); + return Rhythmic_grouping(children); } void @@ -46,7 +51,7 @@ Simple_walker::do_INTERPRET_command(Command*com) default_grouping = parse_grouping(args); }else if (com->args[0] == "BAR") { local_key_.reset(key_); - current_grouping = default_grouping; + } else if (com->args[0] == "KEY") { if (col()->when()) { @@ -129,6 +134,10 @@ Simple_walker::do_note(Rhythmic_req*rq) Notehead*n = s->get_notehead(req, clef_.c0_pos); stem_->add(n); + if (current_grouping) { + current_grouping->add_child( + c->moment_->whole_in_measure, rq->duration()); + } noteheads.add(n); int sidx =find_slur(v); if (sidx >= 0) { @@ -138,7 +147,7 @@ Simple_walker::do_note(Rhythmic_req*rq) if (wantkey) do_local_key(req); } - + if (rq->rest()) { c->typeset_item( s->get_rest(rq->rest()) ); } @@ -154,10 +163,11 @@ Simple_walker::process_requests() error("Too many beams (t = " +String(c->when())+")"); beam_ = new Beam; + current_grouping = new Rhythmic_grouping; } for (int i=0; i < c->slurs.sz(); i++) { Slur_req*sl = c->slurs[i]; - + if (sl->spantype == Span_req::START) { if (find_slur(sl->elt->voice_ )>=0) error("Too many slurs in voice"); @@ -176,20 +186,24 @@ Simple_walker::process_requests() if (beam_) { if (!stem_) - error("beamed note should have a stem (t = " - +String(c->when())+")"); - beam_->add(stem_); + WARN <<"beamed note should have a stem (t = " + <when())<<"\n"; + else + beam_->add(stem_); + + } if (stem_) { c->typeset_item(stem_); /* needed, otherwise placement of local_key fucks up */ -// stem_->set_default_extents(); - // can somebody explain myself? } if (c->beam_&& c->beam_->spantype == Span_req::STOP) { + beam_->set_grouping(default_grouping, *current_grouping); pscore_->typeset_spanner(beam_, s->theline); beam_ = 0; + delete current_grouping; + current_grouping =0; } for (int i = 0; i < noteheads.sz(); i++) { c->typeset_item(noteheads[i]); @@ -204,7 +218,7 @@ Simple_walker::process_requests() stem_ = 0; } for (int i=0; i < c->slurs.sz(); i++) { - Slur_req*sl = c->slurs[i]; + Slur_req *sl = c->slurs[i]; if (sl->spantype == Span_req::STOP) { int idx = find_slur(sl->elt->voice_); @@ -226,7 +240,7 @@ Simple_walker::Simple_walker(Simple_staff*s) stem_ = 0; beam_ =0; oldkey_undo = 0; - + current_grouping = 0; Local_key_item * i = s->get_local_key_item(); wantkey =i; delete i; diff --git a/src/spanner.cc b/src/spanner.cc index 2d34f9e477..a550227ea6 100644 --- a/src/spanner.cc +++ b/src/spanner.cc @@ -59,3 +59,7 @@ Spanner::print()const mtor << "}\n"; #endif } +Spanner::~Spanner() +{ + delete output; +} diff --git a/src/staff.cc b/src/staff.cc index f3d6a063be..03e22a0398 100644 --- a/src/staff.cc +++ b/src/staff.cc @@ -99,9 +99,23 @@ Staff::setup_staffcols() } for (PCursor cc(*staff_commands_); cc.ok(); cc++) { - Staff_column *sc=get_col(cc->when,false); - for (PCursor i(**cc); i.ok(); i++) - sc->s_commands.add(i); + Staff_column *sc=get_col(cc->moment_.when,false); + sc->s_commands = cc; + sc->moment_ = new Moment(cc->moment_); + } + + PCursor cc(*staff_commands_); + for (PCursor i(cols); i.ok(); i++) { + while ((cc+1).ok() && (cc+1)->when() < i->when()) + cc++; + + if(!i->moment_) { + if (cc->moment_.when == i->when()) + i->moment_ = new Moment(cc->moment_); + else + i->moment_ = new Moment( + i->when() - cc->when() ,&cc->moment_); + } } } @@ -150,7 +164,7 @@ Staff::print() const } Staff::Staff() -{ +{ staff_commands_ = 0; score_ =0; pscore_=0; diff --git a/src/staffcommands.cc b/src/staffcommands.cc index 2837de161c..a0bb71f84c 100644 --- a/src/staffcommands.cc +++ b/src/staffcommands.cc @@ -2,12 +2,18 @@ #include "debug.hh" #include "parseconstruct.hh" +Real +Staff_commands_at::when() +{ + return moment_.when; +} void Staff_commands_at::print() const { #ifndef NPRINT PCursor i (*this); - mtor << "Commands at: " << when<<"\n"; + mtor << "Commands at: " ; + moment_.print(); for (; i.ok(); i++) i->print(); @@ -22,9 +28,10 @@ Staff_commands_at::OK()const assert(i->priority >= (i+1)->priority); } -Staff_commands_at::Staff_commands_at(Real r) +Staff_commands_at::Staff_commands_at(Moment m) + :moment_(m) { - when = r; + } bool @@ -200,9 +207,8 @@ Staff_commands::OK() const { #ifndef NDEBUG for (PCursor i(*this); i.ok() && (i+1).ok(); i++) { - assert(i->when <= (i+1)->when); + assert(i->moment_.when <= (i+1)->moment_.when); i->OK(); - } #endif } @@ -222,41 +228,44 @@ Staff_commands::find(Real w) { PCursor i(bottom()); for (; i.ok() ; i--) { - if (i->when == w) + if (i->moment_.when == w) return i; - if (i->when < w) + if (i->moment_.when < w) + break; + } + return 0; +} + +void +Staff_commands::add(Staff_commands_at*p) +{ + PCursor i(bottom()); + for (; i.ok() ; i--) { + if (i->moment_.when < p->moment_.when) break; } - Staff_commands_at*p =new Staff_commands_at(w); if (!i.ok()) i.insert(p); else { i.add(p); i++; } - return i; -} - -void -Staff_commands::add(Command c, Real when) -{ - Staff_commands_at* p = find(when); - p->add(c); } void Staff_commands::clean(Real l) { PCursor i(bottom()); - for (; i->when > l ; i=bottom()) { + for (; i->moment_.when > l; i=bottom()) { remove(i); } - Staff_commands_at*p = find(l); + Staff_commands_at*p = find(l); + if (!p) { + p = new Staff_commands_at(Moment(l - i->when(), &i->moment_)); + add(p); + } if (!p->is_breakable()) { p->set_breakable(); -/* Command b; - b.code = INTERPRET; - b.args.add("BAR");*/ } } diff --git a/src/staffline.cc b/src/staffline.cc index 9fd5b1d5bf..afb8085b1a 100644 --- a/src/staffline.cc +++ b/src/staffline.cc @@ -63,12 +63,11 @@ Line_of_staff::Line_of_staff(Line_of_score * sc, PStaff*st) line_of_score_=sc; pstaff_=st; - PCol *linestart = sc->cols.top(); PCol *linestop = sc->cols.bottom(); - for (PCursor sp(pstaff_->spans); sp.ok(); sp++) { + PCol *brokenstart = &MAX(*linestart, *sp->left); PCol *brokenstop = &MIN(*linestop, *sp->right); if ( *brokenstart < *brokenstop) { diff --git a/src/stcol.cc b/src/stcol.cc index abb27d17da..d4ba8cec33 100644 --- a/src/stcol.cc +++ b/src/stcol.cc @@ -1,6 +1,7 @@ #include "stcol.hh" #include "sccol.hh" #include "voice.hh" +#include "moment.hh" bool Staff_column::mus() const @@ -25,7 +26,14 @@ Staff_column::add(Voice_element*ve) v_elts.add(ve); } -Staff_column::Staff_column(Score_column*s) { +Staff_column::Staff_column(Score_column*s) +{ score_column = s; + s_commands = 0; + moment_ = 0; } +Staff_column::~Staff_column() +{ + delete moment_; +} diff --git a/src/stem.cc b/src/stem.cc index 84e24c5986..03b91b9316 100644 --- a/src/stem.cc +++ b/src/stem.cc @@ -60,7 +60,8 @@ Stem::add(Notehead *n) if ( p < minnote) minnote = p; if ( p> maxnote) - maxnote = p; + maxnote = p; + heads.add(n); } @@ -108,11 +109,29 @@ Stem::set_default_extents() stem_xoffset = 0; } +void +Stem::set_noteheads() +{ + heads.sort(Notehead::compare); + int parity=0; + int lastpos = heads[0]->position; + for (int i=1; i < heads.sz(); i ++) { + if (ABS(lastpos- heads[i]->position) == 1) { + if (parity) + heads[i]->x_dir = (stem_xoffset>0) ? 1:-1; + parity = !parity; + } else + parity = 0; + lastpos = heads[i]->position; + } +} + void Stem::postprocess() { if (bot == top) set_default_extents(); + set_noteheads(); brew_molecole(); } @@ -146,7 +165,7 @@ Stem::brew_molecole() Symbol fl = p->lookup_->flag(flag); Molecule m(fl); if (flag < -4){ - output->add_bot(m); + output->add_bottom(m); } else if (flag > 4) { output->add_top(m); } else diff --git a/src/swalker.cc b/src/swalker.cc index 54872ec83b..98d58324c3 100644 --- a/src/swalker.cc +++ b/src/swalker.cc @@ -23,9 +23,9 @@ void Staff_walker::process() { break_status = BREAK_END - BREAK_PRE; - - for (int i = 0 ; i < (*this)->s_commands.sz(); i++) { - process_command((*this)->s_commands[i]); + if (ptr()->s_commands) + for (PCursor i(*ptr()->s_commands); i.ok(); i++) { + process_command(i); } process_requests(); diff --git a/src/table.cc b/src/table.cc index 119475cc54..e69de29bb2 100644 --- a/src/table.cc +++ b/src/table.cc @@ -1,8 +0,0 @@ -#include "glob.hh" -#include "debug.hh" -#include "string.hh" -#include "inputstaff.hh" - - - - diff --git a/src/template3.cc b/src/template3.cc index 3e06cfdb23..2852ebda21 100644 --- a/src/template3.cc +++ b/src/template3.cc @@ -7,13 +7,13 @@ #include "inputcommands.hh" #include "molecule.hh" #include "plist.cc" - +#include "staffcommands.hh" IPL_instantiate(Atom); IPL_instantiate(Command); IPL_instantiate(Atom); -IPL_instantiate(Command); IPL_instantiate(Input_command); IPL_instantiate(Commands_at); +IPL_instantiate(Staff_commands_at); IPL_instantiate(Input_staff); IPL_instantiate(Input_music); diff --git a/src/texbeam.cc b/src/texbeam.cc index 87967119b1..5c082be669 100644 --- a/src/texbeam.cc +++ b/src/texbeam.cc @@ -66,31 +66,32 @@ Lookup::beam(Real &slope, Real width) int sidx = slope_index(slope); if (!slope) return rule_symbol(convert_dimen(2,"pt"), width); - - Real w = width; + if (width < convert_dimen(2,"pt")) + error("Beam too narrow. " ); + 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; + + while (elemwidth > width) { + widx --; + elemwidth /= 2.0; } - - widx = 0; - Atom a(beam_element(sidx, widx, slope)); - a.translate(Offset(width -minwid, (width-minwid) * slope)); + Real overlap = elemwidth/4; + Real last_x = width - elemwidth; + Real x = overlap; + Atom elem(beam_element(sidx, widx, slope)); + Atom a(elem); + m.add(a); + while (x < last_x) { + a=elem; + a.translate(Offset(x-overlap, (x-overlap)*slope)); + m.add(a); + x += elemwidth - overlap; + } + a=elem; + a.translate(Offset(last_x, (last_x) * slope)); m.add(a); Symbol ret; diff --git a/symbol.ini b/symbol.ini index d0dd12453d..ed7b4f23be 100644 --- a/symbol.ini +++ b/symbol.ini @@ -11,12 +11,12 @@ table_sixteen = symboltables { "clefs" = table { - "violin" "\violinclef" 0pt 16pt -12.5pt 22.5pt - "bass" "\bassclef" 0pt 16pt 0pt 20pt - "viola" "\violaclef" 0pt 16pt 0pt 20pt - "violin_change" "\cviolinclef" 0pt 16pt -12.5pt 22.5pt - "bass_change" "\cbassclef" 0pt 16pt 0pt 20pt - "viola_change" "\cviolaclef" 0pt 16pt 0pt 20pt + "violin" "\violinclef" 0pt 12.8pt -10pt 18pt + "bass" "\bassclef" 0pt 11.2pt 0pt 16pt + "viola" "\violaclef" 0pt 12.8pt 0pt 16pt + "violin_change" "\cviolinclef" 0pt 11.2pt -12pt 12pt + "bass_change" "\cbassclef" 0pt 12.8pt 0pt 16pt + "viola_change" "\cviolaclef" 0pt 11.2pt 0pt 16pt } "balls" = table { @@ -71,18 +71,18 @@ table_sixteen = symboltables { } "dots" = table { - "1" "\lsingledot" 0pt 8pt -1pt 1pt - "2" "\ldoubledot" 0pt 12pt -1pt 1pt - "3" "\ltripledot" 0pt 16pt -1pt 1pt + "1" "\lsingledot" 0pt 2pt -1pt 1pt + "2" "\ldoubledot" 0pt 5pt -1pt 1pt + "3" "\ltripledot" 0pt 8pt -1pt 1pt } "flags" = table { - "8" "\eigthflag" 0pt 5pt 0pt 0pt - "16" "\sixteenthflag" 0pt 5pt 0pt 0pt - "32" "\thirtysecondflag" 0pt 5pt 0pt 0pt - "-8" "\deigthflag" 0pt 5pt 0pt 0pt - "-16" "\dsixteenthflag" 0pt 5pt 0pt 0pt - "-32" "\dthirtysecondflag" 0pt 5pt 0pt 0pt + "8" "\eigthflag" 0pt 4pt 0pt 0pt + "16" "\sixteenthflag" 0pt 4pt 0pt 0pt + "32" "\thirtysecondflag" 0pt 4pt 0pt 0pt + "-8" "\deigthflag" 0pt 4pt 0pt 0pt + "-16" "\dsixteenthflag" 0pt 4pt 0pt 0pt + "-32" "\dthirtysecondflag" 0pt 4pt 0pt 0pt } "beamslopes" = table { -- 2.39.5