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
+pl 19:
+ - struct Moment
+ - grouping code: LilyPond can set advanced multibeams.
+
pl 18:
- robust Staff_commands
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\
# 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
-\font\musicfnt=musix16
+\font\musicfnt=musix20
\font\slurfont=xslhu20
\def\thefont{\musicfnt}
depend: Sources.make
$(CXX) -MM $(cc) > depend
-
clean:
rm -f $(obs) $(staticlib)
tar cfz $(DNAME).tar.gz $(DDIR)/*
rm -rf $(DDIR)/
-TAGS:
+TAGS: $(ALLSOURCES)
etags -CT $(inl) $(cc) $(hh)
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\
MAJVER=1
MINVER=0
-PATCHLEVEL=18
+PATCHLEVEL=19
PACKAGENAME=flower
#PROFILEFLAG=-pg
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)
#ifndef ASSOC_HH
#define ASSOC_HH
-#include "vray.hh"
+#include "varray.hh"
#include <assert.h>
template<class K, class V>
template<class K, class V>
struct Assoc {
- svec< Assoc_ent_<K,V> > arr;
+ Array< Assoc_ent_<K,V> > 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;
}
}
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 ) {
ae.free = false;
ae.key = key;
arr.add(ae);
- return arr.sz() -1;
+ return arr.size() -1;
}
public:
bool elt_query(K key) const {
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);
Cursor( const Cursor<T>& cursor );
T& thing();
+
/// return current T
T& operator *() { return thing(); }
operator T() { return thing(); }
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;
}
#ifndef FPROTO_HH
#define FPROTO_HH
-template<class T> struct svec;
+template<class T> struct Array;
template<class T> struct sstack;
template<class T,class K> struct Assoc;
template<class T> struct List;
#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())
void concatenate(List<T> 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
/// put thing before #before_me#
void insert( const T& thing, Cursor<T> &before_me );
- virtual void remove( Cursor<T> me );
- /**
- Remove link pointed to by me.
+
+ void remove( Cursor<T> 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<T>* top_;
Link<T>* bottom_;
template<class T>
List<T>::~List()
{
- Cursor<T> next(*this);
- for ( Cursor<T> c( *this ); c.ok(); c = next ) {
- next = c;
- next++;
- remove( c );
- }
+ Cursor<T> c(*this);
+ while (c.ok())
+ c.del();
}
template<class T>
template<class T>
struct PCursor : private Cursor<void *> {
friend class IPointerList<T>;
+
+ /// delete contents
+ void junk();
public:
Cursor<void*>::ok;
- Cursor<void*>::del;
- Cursor<void*>::backspace;
+ void del() { junk(); Cursor<void*>::del(); }
+ void backspace() { junk(); Cursor<void*>::backspace(); }
+ T get() {
+ T p = ptr();
+ Cursor<void*>::del();
+ return p;
+ }
+ T get_prev() {
+ (*this)--;
+ return get();
+ }
PointerList<T> &list() { return (PointerList<T>&)Cursor<void*>::list(); }
PCursor<T> operator++(int) { return Cursor<void*>::operator++(0);}
--- /dev/null
+#include "pcursor.hh"
+
+template<class T>
+void
+PCursor<T>::junk()
+{
+#if !defined(NDEBUG) && defined(PARANOID)
+ list().OK();
+#endif
+
+ delete ptr();
+#if !defined(NDEBUG)&&defined(PARANOID)
+ thing() = 0;
+ list().OK();
+#endif
+}
struct IPointerList : public PointerList<T> {
IPointerList(const IPointerList&) { set_empty(); }
IPointerList() { }
-protected:
- virtual void remove( Cursor<void*> me ) { remove (PCursor<T>(me)); }
- virtual void remove( PCursor<T> me );
+ ~IPointerList();
};
/**
NOTE:
#include "plist.hh"
-// not inlined since it assumes knowledge of destructor.
template<class T>
-void
-IPointerList<T>::remove(PCursor<T> me )
+IPointerList<T>::~IPointerList()
{
- if ( me.ok() ) {
- delete me.ptr();
- List<void*>::remove(me);
+ PCursor<T> c( *this );
+ while (c.ok()) {
+ c.del();
}
}
+
template<class T>
PCursor<T>
PointerList<T>::find(T what ) const
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)
}
-svec<Real>
+Array<Real>
Full_storage::row(int n) const
{
- svec<Real> r;
+ Array<Real> r;
for (int j = 0; j < w; j++)
r.add(els[n][j]);
return r;
}
-svec<Real>
+Array<Real>
Full_storage::column(int n) const
{
- svec<Real> r;
+ Array<Real> r;
for (int i = 0; i<h; i++)
r.add(els[i][n]);
return r;
#ifndef SMAT_HH
#define SMAT_HH
-#include "vray.hh"
+#include "varray.hh"
#include "vsmat.hh"
#include "real.hh"
/// simplest matrix storage. refer to its baseclass for the doco.
assert(valid(i,j));
return els[i][j];
}
- virtual svec<Real> row(int i) const;
- virtual svec<Real> column(int j) const;
+ virtual Array<Real> row(int i) const;
+ virtual Array<Real> column(int j) const;
Full_storage() {
init();
#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<class T>
-struct sstack : svec<T> {
+struct sstack : Array<T> {
T top() { return last(); }
T pop() {
assert(!empty());
T l = last();
- svec<T>::pop();
+ Array<T>::pop();
return l;
}
void push(T l) { add(l); }
};
/**
- Same as for #svec# goes here.
+ Same as for #Array# goes here.
*/
{
while (1) {
String s;
- svec<String> fields;
+ Array<String> fields;
assert(!eof());
while ((s = get_word()) != "")
if (get_line() != "")
assert(false);
- assert (fields.sz());
+ assert (fields.size());
return Text_record(fields, get_name(), line());
}
}
/**: do "#" comments, read quote enclosed fields */
-/// a "const" svec. Contents can't be changed.
-class Text_record : svec<String>
+/// a "const" Array. Contents can't be changed.
+class Text_record : Array<String>
{
int line_no;
String filename;
cerr << '\n'<< filename << ": "<< line_no << s << "\n";
}
String operator[](int j) {
- return svec<String>::operator[](j);
+ return Array<String>::operator[](j);
}
- Text_record(svec<String> s, String fn, int j) : svec<String>(s) {
+ Text_record(Array<String> s, String fn, int j) : Array<String>(s) {
filename = fn; line_no = j;
}
- svec<String>::sz;
+ Array<String>::size;
};
/// abstraction for a datafile
#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.
assert(valid(i,j));
return els[i][j];
}
- virtual svec<T> row(int i) const;
- virtual svec<T> column(int j) const;
+ virtual Array<T> row(int i) const;
+ virtual Array<T> column(int j) const;
Full_storage() {
init();
#ifndef VSMAT_HH
#define VSMAT_HH
-#include "vray.hh"
+#include "varray.hh"
/// a matrix storage baseclass.
class virtual_smat {
virtual const Real& elem(int i, int j) const = 0;
#if 1
- virtual svec<Real> row(int i) const = 0;
- virtual svec<Real> column(int j) const = 0;
+ virtual Array<Real> row(int i) const = 0;
+ virtual Array<Real> column(int j) const = 0;
#endif
/// add a row
#ifndef UNIONFIND_HH
#define UNIONFIND_HH
-#include "vray.hh"
+#include "varray.hh"
/// which points of a graph are connected?
struct Union_find {
Union_find(int sz);
private:
- svec<int> classes;
+ Array<int> classes;
};
/*
--- /dev/null
+/*
+ (c) Han-Wen Nienhuys 1995,96
+
+ Distributed under GNU GPL
+*/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+#include <assert.h>
+
+/// copy a bare (C-)array from #src# to #dest# sized #count#
+template<class T>
+inline void arrcpy(T*dest, T*src, int count) {
+ for (int i=0; i < count ; i++)
+ *dest++ = *src++;
+}
+
+///scaleable array template, for T with def ctor.
+template<class T>
+class Array {
+protected:
+ /// maximum length of array.
+ int max;
+
+ /// the data itself
+ T *thearray;
+
+ /// stretch or shrink array.
+ void remax(int newmax) {
+ T* newarr = new T[newmax];
+ size_ = (newmax < size_) ? newmax : size_;
+ arrcpy(newarr, thearray, size_);
+
+ delete[] thearray;
+ thearray = newarr;
+ max = newmax;
+ }
+ int size_;
+
+public:
+ /// check invariants
+ void OK() const {
+ assert(max >= size_ && size_ >=0);
+ if (max) assert(thearray);
+ }
+ /// report the size_. See {setsize_}
+
+ int size() const { return size_; }
+
+ /// POST: size() == 0
+ void clear() { 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: size() == s.
+ Warning: contents are unspecified */
+
+ ~Array() { delete[] thearray; }
+
+ /// return a "new"ed copy of array
+ T* copy_array() const {
+ T* Tarray = new T[size_];
+ arrcpy(Tarray, thearray, size_);
+ return Tarray;
+ }
+ // depracated
+ operator T* () const {
+ return copy_array();
+ }
+ void operator=(Array const & src) {
+ set_size (src.size_);
+ arrcpy(thearray,src.thearray, size_);
+ }
+ Array(const Array & src) {
+ thearray = src.copy_array();
+ max = size_ = src.size_;
+ }
+
+ /// tighten array size_.
+ void precompute () { remax(size_); }
+
+ /// this makes Array behave like an array
+ T &operator[] (const int i) const {
+ assert(i >=0&&i<size_);
+ return ((T*)thearray)[i];
+ }
+
+ /// add to the end of array
+ void add(T x) {
+ if (size_ == max)
+ remax(2*max + 1);
+
+ // T::operator=(T &) is called here. Safe to use with automatic
+ // vars
+ thearray[size_++] = x;
+ }
+
+ /// junk last entry.
+ void pop() { size_ -- ; }
+
+ /// return last entry
+ T& last(int j=0) {
+ return (*this)[size_-j-1];
+ }
+ T last(int j=0) const {
+ return (*this)[size_-j-1];
+ }
+ void swap (int i,int j) {
+ T t((*this)[i]);
+ (*this)[i]=(*this)[j];
+ (*this)[j]=t;
+ }
+ bool empty() { return !size_; }
+ void insert(T k, int j) {
+ assert(j >=0 && j<= size_);
+ set_size(size_+1);
+ for (int i=size_-1; i > j; i--)
+ thearray[i] = thearray[i-1];
+ thearray[j] = k;
+ }
+ void del(int i) {
+ assert(i >=0&& i < size_);
+ arrcpy(thearray+i, thearray+i+1, size_-i-1);
+ size_--;
+ }
+ // quicksort.
+ void sort (int (*compare)(T& , T& ),
+ int lower = -1, int upper = -1 ) {
+ if (lower < 0) {
+ lower = 0 ;
+ upper = size()-1;
+ }
+ if (lower >= upper)
+ return;
+ swap(lower, (lower+upper)/2);
+ int last = lower;
+ for (int i= lower +1; i <= upper; i++)
+ if (compare(thearray[i], thearray[lower]) < 0 )
+ swap( ++last,i);
+ swap(lower, last);
+ sort(compare, lower, last-1);
+ sort(compare, last+1, upper);
+ }
+ void concat(Array<T> const &src) {
+ int s = size_;
+ set_size(size_ + src.size_);
+ arrcpy(thearray+s,src.thearray, src.size_);
+ }
+ Array<T> subvec(int lower, int upper) {
+ assert(lower >= 0 && lower <=upper&& upper <= size_);
+ Array<T> r;
+ int s =upper-lower;
+ r.set_size(s);
+ arrcpy(r.thearray, thearray + lower, s);
+ return r;
+ }
+};
+/**
+
+ This template implements a scaleable vector. With (or without) range
+ checking. It may be flaky for objects with complicated con- and
+ destructors. The type T should have a default constructor. It is
+ best suited for simple types, such as int, double or String
+
+ */
+
+#endif
#include <math.h>
#include "real.hh"
-#include "vray.hh"
+#include "varray.hh"
class Dstream;
class String;
/// a row of numbers
class Vector {
- svec<Real> dat;
+ Array<Real> 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) {
Real norm_sq() {
return ((*this) * (*this));
}
- operator svec<Real> () { return dat; }
+ operator Array<Real> () { 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
+++ /dev/null
-/*
- (c) Han-Wen Nienhuys 1995,96
-
- Distributed under GNU GPL
-*/
-
-#ifndef SVEC_H
-#define SVEC_H
-#include <assert.h>
-
-/// copy a bare (C-)array from #src# to #dest# sized #count#
-template<class T>
-inline void arrcpy(T*dest, T*src, int count) {
- for (int i=0; i < count ; i++)
- *dest++ = *src++;
-}
-
-///scaleable array template, for T with def ctor.
-template<class T>
-class svec {
-protected:
-
- int max;
-
- /// the data itself
- T *thearray;
-
- /// stretch or shrink array.
- void remax(int newmax) {
- T* newarr = new T[newmax];
- size_ = (newmax < size_) ? newmax : size_;
- arrcpy(newarr, thearray, size_);
-
- delete[] thearray;
- thearray = newarr;
- max = newmax;
- }
- int size_;
-
-public:
- /// check invariants
- void OK() const {
- assert(max >= size_ && size_ >=0);
- if (max) assert(thearray);
- }
- /// 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; }
-
- /// set the size_ to #s#
- void set_size(int s) {
- if (s >= max) remax(s);
- size_ = s;
- }
- /** POST: sz() == s.
- Warning: contents are unspecified */
-
- ~svec() { delete[] thearray; }
-
- /// return a "new"ed copy of array
- T* copy_array() const {
- T* Tarray = new T[size_];
- arrcpy(Tarray, thearray, size_);
- return Tarray;
- }
- // depracated
- operator T* () const {
- return copy_array();
- }
- void operator=(svec const & src) {
- set_size (src.size_);
- arrcpy(thearray,src.thearray, size_);
- }
- svec(const svec & src) {
- thearray = src.copy_array();
- max = size_ = src.size_;
- }
-
- /// tighten array size_.
- void precompute () { remax(size_); }
-
- /// this makes svec behave like an array
- T &operator[] (const int i) const {
- assert(i >=0&&i<size_);
- return ((T*)thearray)[i];
- }
-
- /// add to the end of array
- void add(T x) {
- if (size_ == max)
- remax(2*max + 1);
-
- // T::operator=(T &) is called here. Safe to use with automatic
- // vars
- thearray[size_++] = x;
- }
-
- /// junk last entry.
- void pop() { size_ -- ; }
-
- /// return last entry
- T& last(int j=0) {
- return (*this)[size_-j-1];
- }
- T last(int j=0) const {
- return (*this)[size_-j-1];
- }
- void swap (int i,int j) {
- T t((*this)[i]);
- (*this)[i]=(*this)[j];
- (*this)[j]=t;
- }
- bool empty() { return !size_; }
- void insert(T k, int j) {
- assert(j >=0 && j<= size_);
- set_size(size_+1);
- for (int i=size_-1; i > j; i--)
- thearray[i] = thearray[i-1];
- thearray[j] = k;
- }
- void del(int i) {
- assert(i >=0&& i < size_);
- arrcpy(thearray+i, thearray+i+1, size_-i-1);
- size_--;
- }
- // quicksort.
- void sort (int (*compare)(T& , T& ),
- int lower = -1, int upper = -1 ) {
- if (lower < 0) {
- lower = 0 ;
- upper = sz()-1;
- }
- if (lower >= upper)
- return;
- swap(lower, (lower+upper)/2);
- int last = lower;
- for (int i= lower +1; i <= upper; i++)
- if (compare(thearray[i], thearray[lower]) < 0 )
- swap( ++last,i);
- swap(lower, last);
- sort(compare, lower, last-1);
- sort(compare, last+1, lower);
- }
- void concat(svec<T> const &src) {
- int s = size_;
- set_size(size_ + src.size_);
- arrcpy(thearray+s,src.thearray, src.size_);
- }
- svec<T> subvec(int lower, int upper) {
- assert(lower >= 0 && lower <=upper&& upper <= size_);
- svec<T> r;
- int s =upper-lower;
- r.set_size(s);
- arrcpy(r.thearray, thearray + lower, s);
- return r;
- }
-};
-/**
-
- This template implements a scaleable vector. With (or without) range
- checking. It may be flaky for objects with complicated con- and
- destructors. The type T should have a default constructor. It is
- best suited for simple types, such as int, double or String
-
- */
-
-#endif
#ifndef VSMAT_HH
#define VSMAT_HH
-#include "vray.hh"
+#include "varray.hh"
#include "real.hh"
/// a matrix storage baseclass.
class virtual_smat {
virtual const Real& elem(int i, int j) const = 0;
#if 1
- virtual svec<Real> row(int i) const = 0;
- virtual svec<Real> column(int j) const = 0;
+ virtual Array<Real> row(int i) const = 0;
+ virtual Array<Real> column(int j) const = 0;
#endif
/// add a row
/// -1 below heads, +1 above heads.
int dir;
+ Rhythmic_grouping *group;
+
/****************/
virtual Interval width()const;
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();
#include "vray.hh"
-
+/// data structure which represents rhythmic units
struct Rhythmic_grouping {
- svec<Real> divisions;
+
svec<Rhythmic_grouping*> children;
-
+ Interval *interval_;
+
/****************/
- svec<Real> interior();
- Rhythmic_grouping partial_grouping(Interval t);
+ svec<Interval> intervals();
+ Interval interval()const;
Real length() const;
- Interval time() const;
- Rhythmic_grouping(Interval);
- Rhythmic_grouping();
- Rhythmic_grouping(svec<Real>);
- 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*>);
+ ~Rhythmic_grouping();
+
+ void add_child(Real start, Real len);
+
void split(Rhythmic_grouping r);
- void split(svec<Real>);
- void intersect(Interval);
+ void split(svec<Interval>);
void split(int n);
+
void print() const;
void OK() const;
- ~Rhythmic_grouping();
+
+ svec<int> generate_beams(svec<int>, int&);
+
+private:
+ void junk();
+ void copy(Rhythmic_grouping const&);
};
+/**
+ this is a tree. It groupes notes according to rules
+
+ */
+
#endif
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<int>);
+Input_command *get_skip_command(int,Real);
+Input_command *get_grouping_command(Real,svec<int>);
+Input_command *get_grouping_command(svec<int>);
Input_command *get_bar_command( );
+
+svec<int> get_default_grouping(int count);
#endif // INPUTCOMMAND_HH
#include "proto.hh"
#include "plist.hh"
#include "real.hh"
+#include "moment.hh"
struct Commands_at : public IPointerList<Input_command*> {
- 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*);
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)); }
--- /dev/null
+/*
+ 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
+
int staff_size;
int dots;
int balltype;
-
+ int x_dir;
+
/****************/
void preprocess();
*/
void print()const;
-
+ static int compare(Notehead*&a, Notehead*&b) ;
private:
void brew_molecole();
};
struct Notename_tab;
struct Input_file;
struct Keyword_table;
+struct Rhythmic_grouping;
+struct Staff_commands_at ;
+struct Commands_at ;
+struct Moment;
#endif // PROTO_HH
bool processed_clef;
Clef clef_;
Rhythmic_grouping default_grouping;
- Rhythmic_grouping current_grouping;
+ Rhythmic_grouping *current_grouping;
+ Real inbar;
svec<Slur_req*> pending_slur_reqs;
svec<Slur*> pending_slurs;
String TeXstring () const ;
Spanner();
Paperdef*paper() const;
-
+ virtual ~Spanner();
virtual Interval height()const=0;
/**
PRE:
*/
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.
#include "command.hh"
#include "vray.hh"
#include "plist.hh"
+#include "moment.hh"
struct Staff_commands_at : public IPointerList<Command*> {
- 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;
void insert_between(Command victim, PCursor<Command*> firstc,
PCursor<Command*> last);
void add(Command c);
-
};
/// the list of commands in Score
struct Staff_commands : public IPointerList<Staff_commands_at*>
{
Staff_commands_at*find(Real);
- void add(Command,Real);
+ void add(Staff_commands_at*);
void clean(Real last);
void OK() const;
void print() const;
svec<Voice_element *> v_elts;
/// idem
- svec<Command *> s_commands;
+ Staff_commands_at *s_commands;
+ Moment *moment_;
+
/****************/
Staff_column(Score_column*s);
virtual void process_requests()=0;
- virtual ~Staff_column() { }
+ virtual ~Staff_column();
};
#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)
*/
Real stem_xoffset;
+
+ svec<Notehead*> heads;
+
/****************/
/// ensure that this Stem also encompasses the Notehead #n#
void set_default_dir();
void set_default_stemlen();
void set_default_extents();
+ void set_noteheads();
void postprocess();
void preprocess();
Stem(int center, Real duration);
\newdimen\interlinedist
\newcount\n
\newdimen\balkhoog
+ \newdimen\notewidth
+ \newdimen\notewidthhalf
+ \newdimen\notewidthdouble
\newdimen\staffrulethickness
\newdimen\interstaffrule
\font\hslurhfont=xslhz20
\font\musicfnt=musix20
\balkhoog=20pt
+ \notewidth=6pt
\staffrulethickness=0.4pt
\musixcalc
\font\musicfnt=musix16
\balkhoog=16pt
\staffrulethickness=0.4pt
-
+ \notewidth=5pt
\musixcalc
}
\advance\interstaffrule by-\staffrulethickness
\divide\interstaffrule by 4
\advance\interstaffrule by -\staffrulethickness
+ \notewidthhalf=\notewidth
+ \notewidthdouble=\notewidth
+ \divide \notewidthhalf by 2
+ \multiply \notewidthdouble by 2
}
}}
\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
\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}
ritme = staff {rhythmic
music {$
c8
- c2 c2
+ [a8 a8. a8 a16 a16 a16] c4.
+
%[c8( )'a8 c8 c8]
c2 c2
[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
$}
}
staff { melodic
music{$
c8
- r1
+ r4 r4 r4 r4
'cis2.. r8
r4 r8 r16 r32 r32
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
}
#include "stem.hh"
#include "paper.hh"
#include "lookup.hh"
-#include "scalar.hh"
-
+#include "grouping.hh"
struct Stem_info {
Real x;
Beam::Beam()
{
+ group = 0;
slope = 0;
left_pos = 0.0;
dir =0;
solve_slope();
}
-
void
Beam::process()
{
calculate();
- /*
- quick and dirty!
- */
- for (PCursor<Stem*> 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<int> b;
+ {
+ PCursor<Stem*> s(stems);
+ svec<int> 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<Stem*> 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 *
#endif
}
+Beam::~Beam()
+{
+ delete group;
+}
#include <fstream.h>
+#include <signal.h>
#include <std/new.h>
#include <stdlib.h>
#include "debug.hh"
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;
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<Real> 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<Real>
-Rhythmic_grouping::interior()
+
+svec<Interval>
+Rhythmic_grouping::intervals()
{
- svec<Real> r(divisions);
- r.del(0);
- r.pop();
+ svec<Interval> 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<Real> 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<Real> 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<Rhythmic_grouping*> 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<Real> splitpoints)
+Rhythmic_grouping::split(svec<Interval> splitpoints)
{
- assert(!children.sz());
- svec<Real> child;
- int j = 0, i=0;
+ //check on splitpoints..
+ int j = 0, i=0, starti = 0, startj = 0;
+
+ svec<Rhythmic_grouping*> 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<Rhythmic_grouping*> r)
+ :children(r)
+{
+ interval_ =0;
}
-Rhythmic_grouping::Rhythmic_grouping(svec<Real> 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<int> v)
+{
+ int i = 1000; // ugh
+ for (int j = 0 ; j < v.sz(); j++)
+ i = i <? v[j];
+ return i;
+}
+
+svec<int>
+Rhythmic_grouping::generate_beams(svec<int> flags, int &flagidx)
+{
+
+ assert (!interval_) ;
+
+ svec< svec<int> > children_beams;
+ for (int i=0; i < children.sz(); i++) {
+ svec<int> 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<int> 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 <? m);
+ beams.concat(children_beams[i]);
+ if (add_right)
+ beams.add(m <? nextm);
+ }
+ lastm = m;
+ m = nextm;
+ }
+ assert(!(beams.sz()%2));
+ return beams;
+}
return c;
}
+Input_command*
+get_grouping_command(Real r,svec<int>a )
+{
+ Input_command*c = get_grouping_command(a);
+ c->args.insert(r,1);
+ return c;
+}
+
Input_command*
get_grouping_command(svec<int>a )
{
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]);
c->args.add(w);
return c;
}
+
+svec<int>
+get_default_grouping(int count)
+{
+ svec<int> 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;
+}
-/*
- it still sucks.
- */
-
#include "inputcommands.hh"
#include "inputcommand.hh"
#include "debug.hh"
Commands_at::print() const
{
#ifndef NPRINT
- mtor << "Commands_at { at "<<when<<'\n';
- mtor << "meter " << whole_per_measure
- << " pos "<< bars << ":" << whole_in_measure <<'\n';
+ mtor << "Commands_at {";
+ moment_.print();
for (PCursor<Input_command *> 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<Input_command*> &me(*this);
const IPointerList<Input_command*> &that(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<Input_command *> cc(*this); cc.ok(); cc++) {
+ if (cc->args.sz() && cc->args[0] !="") {
+ Command c = **cc;
+ s->add(c);
+
+ }
+ }
+}
/****************/
void
Real last = when();
while (1) {
if (! ok() ) {
- *this = PCursor<Commands_at*>(list().bottom());
+ *this = list().bottom();
Real dt = (w - when()) <? ptr()->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 )
{
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);
}
}
{
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);
+ }
}
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<Commands_at*> i(*this); i.ok(); i++) {
- for (PCursor<Commands_at*> i(*this); i.ok(); i++)
- for (PCursor<Input_command *> 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;
}
Real
Input_cursor::when()const
{
- return (*this)->when;
+ return (*this)->when();
}
Input_cursor::Input_cursor(PCursor<Commands_at *>c)
: PCursor<Commands_at*>(c)
{
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;
}
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;
}
void
-Molecule::add_bot(const Molecule &m)
+Molecule::add_bottom(const Molecule &m)
{
if (!ats.size()) {
add(m);
--- /dev/null
+#include "moment.hh"
+#include "debug.hh"
+
+void
+Moment::print() const
+{
+ mtor << " at "<<when<<'\n';
+ mtor << "meeter " << whole_per_measure << "/" << 1/one_beat
+ << "\nposition "<< bars << ":" << whole_in_measure <<'\n';
+}
+void
+Moment::OK() const
+{
+ assert(whole_in_measure < whole_per_measure && 0 <= whole_in_measure);
+ assert(one_beat);
+}
+Moment::Moment(Real dt, Moment const *prev)
+{
+ if (prev) {
+ assert(dt >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;
+}
Notehead::Notehead(int ss)
{
+ x_dir = 0;
staff_size=ss;
position = 0;
balltype = 0;
Notehead::print()const
{
#ifndef NPRINT
- mtor << "Head "<<balltype<<", position = "<< position << "dots " << dots;
+ mtor << "Head "<< balltype << ", position = "<< position
+ << "dots " << dots;
Item::print();
#endif
}
brew_molecole();
}
+int
+Notehead::compare(Notehead*&a, Notehead*&b)
+{
+ return a->position - b->position;
+}
+
void
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);
+/*
+ UGR
+ */
+
#include "request.hh"
#include "voice.hh"
#include "clef.hh"
Rhythmic_grouping
parse_grouping(svec<Scalar> a)
{
- Rhythmic_grouping ret;
Real one_beat =a[0];
a.del(0);
svec<int> r;
for (int i= 0 ; i < a.sz(); i++)
r.add(a[i]);
Real here =0.0;
+
+ svec<Rhythmic_grouping*> 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
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()) {
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) {
if (wantkey)
do_local_key(req);
}
-
+
if (rq->rest()) {
c->typeset_item( s->get_rest(rq->rest()) );
}
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");
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 = "
+ <<String(c->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]);
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_);
stem_ = 0;
beam_ =0;
oldkey_undo = 0;
-
+ current_grouping = 0;
Local_key_item * i = s->get_local_key_item();
wantkey =i;
delete i;
mtor << "}\n";
#endif
}
+Spanner::~Spanner()
+{
+ delete output;
+}
}
for (PCursor<Staff_commands_at*> cc(*staff_commands_); cc.ok(); cc++) {
- Staff_column *sc=get_col(cc->when,false);
- for (PCursor<Command*> 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<Staff_commands_at*> cc(*staff_commands_);
+ for (PCursor<Staff_column*> 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_);
+ }
}
}
}
Staff::Staff()
-{
+{
staff_commands_ = 0;
score_ =0;
pscore_=0;
#include "debug.hh"
#include "parseconstruct.hh"
+Real
+Staff_commands_at::when()
+{
+ return moment_.when;
+}
void
Staff_commands_at::print() const
{
#ifndef NPRINT
PCursor<Command*> i (*this);
- mtor << "Commands at: " << when<<"\n";
+ mtor << "Commands at: " ;
+ moment_.print();
for (; i.ok(); i++)
i->print();
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
{
#ifndef NDEBUG
for (PCursor<Staff_commands_at*> 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
}
{
PCursor<Staff_commands_at*> 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<Staff_commands_at*> 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<Staff_commands_at*> 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");*/
}
}
line_of_score_=sc;
pstaff_=st;
-
PCol *linestart = sc->cols.top();
PCol *linestop = sc->cols.bottom();
-
for (PCursor<const Spanner*> sp(pstaff_->spans); sp.ok(); sp++) {
+
PCol *brokenstart = &MAX(*linestart, *sp->left);
PCol *brokenstop = &MIN(*linestop, *sp->right);
if ( *brokenstart < *brokenstop) {
#include "stcol.hh"
#include "sccol.hh"
#include "voice.hh"
+#include "moment.hh"
bool
Staff_column::mus() const
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_;
+}
if ( p < minnote)
minnote = p;
if ( p> maxnote)
- maxnote = p;
+ maxnote = p;
+ heads.add(n);
}
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();
}
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
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<Command*> i(*ptr()->s_commands); i.ok(); i++) {
+ process_command(i);
}
process_requests();
-#include "glob.hh"
-#include "debug.hh"
-#include "string.hh"
-#include "inputstaff.hh"
-
-
-
-
#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);
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;
"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 {
}
"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 {