Lexer 1
parse_duration 1
parse_pitch 1
-
+Col_configuration 1
+Command 1
+Score_commands 1
\ No newline at end of file
MAJVER=0
MINVER=0
-PATCHLEVEL=4
+PATCHLEVEL=5
#
#
#compiling
LOADLIBES=-L$(FLOWERDIR) -lflower
FLOWERDIR=../flower
-#DEFINES=-DNDEBUG -DNPRINT -O2
-CXXFLAGS=$(DEFINES) -I$(FLOWERDIR) -pipe -Wall -W -pedantic -g
+#DEFINES=-DNDEBUG -DNPRINT -O2 # speedy
+DEFINES=-g # lots of debugging info
+
+CXXFLAGS=$(DEFINES) -I$(FLOWERDIR) -pipe -Wall -W -pedantic
FLEX=flex
BISON=bison
exe=$(PACKAGENAME)
hanwen@stack.urc.tue.nl
+If you actually want to use this, you'd better use the "speed"
+compilation flags in the Makefile
pcol.hh proto.hh pstaff.hh line.hh\
const.hh glob.hh molecule.hh boxes.hh pscore.hh item.hh tex.hh\
request.hh voice.hh command.hh staff.hh linestaff.hh \
- tstream.hh mtime.hh rhythmstaf.hh\
+ tstream.hh rhythmstaf.hh\
parseconstruct.hh debug.hh globvars.hh keyword.hh\
misc.hh score.hh notename.hh lexer.hh symtable.hh\
symbol.hh main.hh dimen.hh paper.hh lookupsyms.hh\
pstaff.cc tstream.cc version.cc\
calcideal.cc scores.cc identifier.cc \
dimen.cc paper.cc lookupsyms.cc scommands.cc\
- sccol.cc stcol.cc\
+ sccol.cc stcol.cc getcommands.cc\
template1.cc template2.cc template3.cc
-bug in BAR.
-dot spacing
-typeset direction.
-beam
-stem
+melodie staff.
+beam + stem
#include "const.hh"
void
-Interval:: set_empty() {
- min = INFTY;
- max = -INFTY;
+Interval::set_empty() {
+ min = INFTY;
+ max = -INFTY;
+}
+Real
+Interval::length() const {
+ return max-min;
}
-
Box::Box(svec<Real> s)
{
assert(s.sz() == 4);
Box::Box(Interval ix, Interval iy)
{
- x=ix;
+ x = ix;
y = iy;
}
+
if (h.max>max)
max = h.max;
}
-
+ Real length() const;
void set_empty() ;
bool empty() { return min > max; }
Interval() {
PScore::solve_line(svec<const PCol *> curline) const
{
Spacing_problem sp;
- mtor << "line of " << curline.sz() << " cols\n";
+
sp.add_column(curline[0], true, 0.0);
for (int i=1; i< curline.sz()-1; i++)
sp.add_column(curline[i]);
PCursor<PCol *> start(cols);
PCursor<PCol *> end (((PScore*)this)->cols.bottom());
- assert(start->breakable);
- assert(end->breakable);
+ assert(start->breakable());
+ assert(end->breakable());
}
struct Col_configuration {
energy = config.last();
config.pop();
}
+ void print() const {
+#ifndef NPRINT
+ mtor << "energy : " << energy << '\n';
+ mtor << "line of " << config.sz() << " cols\n";
+#endif
+ }
};
/// wordwrap type algorithm
-/* el stupido. This should be optimised:
+/* el stupido. This should be done more accurately:
It would be nice to have a Dynamic Programming type of algorithm
similar to TeX's
Col_configuration minimum;
Col_configuration current;
- // do another line
- current.add(breakpoints[i]->postbreak );
+ // do another line
+ PCol *post = breakpoints[i]->postbreak;
+ current.add( post);
curcol++; // skip the breakable.
i++;
}
current.add(breakpoints[i]->prebreak );
current.setsol(solve_line(current.line));
- mtor << "energy : " << current.energy << '\n';
+ current.print();
if (current.energy < minimum.energy) {
minimum = current;
- } else {
+ } else { // we're one col too far.
+ i--;
+ while (curcol != breakpoints[i])
+ curcol --;
+
break;
}
do_connect(c1,c2,d);
// alert! this is broken!
- if (c1->breakable) {
+ if (c1->breakable()) {
do_connect(c1->postbreak, c2,d);
}
- if (c2->breakable) {
+ if (c2->breakable()) {
do_connect(c1, c2->prebreak,d);
}
- if (c1->breakable &&c2->breakable) {
+ if (c1->breakable() &&c2->breakable()) {
do_connect(c1->postbreak, c2->prebreak,d);
}
}
for (; sc.ok(); sc++) {
if (sc->musical)
for (int i=0; i < sc->durations.sz(); i++) {
- Mtime d = sc->durations[i];
- Real dist = duration_to_idealspace(d, paper->whole_width);
+ Real d = sc->durations[i];
+ Real dist = duration_to_idealspace(d, paper_->whole_width);
PCol * c2 = find_col(sc->when + d,true)->pcol;
connect_nonmus(sc->pcol, c2, dist);
c2 = find_col(sc->when + d,false)->pcol;
bool
Command::isbreak()const
{
- return (code >= BREAK_PRE&&code <= BREAK_END);
+ return (code >= BREAK_PRE && code <= BREAK_END);
}
-Command*
-get_bar_command(Real w)
-{
- Command*c = new Command;
- c->when = w;
- c->code = TYPESET;
- c->args.add( "BAR");
- c->args.add( "|");
- return c;
-}
-
-Command *
-get_meter_command(Real w, int n, int m)
-{
- Command*c = new Command;
-
- c->when = w;
- c->code = TYPESET;
- c->args.add( "METER");
- c->args.add( n );
- c->args.add( m );
- return c;
-}
-
-
-
Command::Command()
{
code = NOP;
when = -1;
+ priority=0;
}
{
code = NOP;
when = w;
+ priority=0;
}
+
void
Command::print() const
{
- mtor << "command code: " << code << " args: ";
- for (int i = 0; i<args.sz(); i++)
- mtor << args[i];
+#ifndef NPRINT
+ mtor << "command at " << when << ", code " << code << " prio " << priority;
+ if (args.sz()) {
+ mtor<< " args: ";
+ for (int i = 0; i<args.sz(); i++)
+ mtor << "`"<<args[i] <<"',";
+ }
mtor << "\n";
+#endif
}
#ifndef COMMAND_HH
#define COMMAND_HH
#include "glob.hh"
-#include "mtime.hh"
+
#include "vray.hh"
#include "string.hh"
struct Command {
Commandcode code;
- Mtime when;
+ Real when;
/// analogous to argv[]
svec<String> args;
+ int priority;
+
+ /****************/
+
Command();
Command(Real w);
bool isbreak()const;
+#include <fstream.h>
#include "debug.hh"
#include "dstream.hh"
#include "vector.hh"
Dstream monitor(&cout,".dstreamrc");
-
+ostream * nulldev = new ofstream("/dev/null");
void
debug_init()
{
#define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
extern ostream &warnout ;
extern ostream *mlog;
+extern ostream *nulldev;
extern Dstream monitor; // monitor
+#ifdef NPRINT
+#define mtor *nulldev
+#else
#define mtor monitor.identify_as(__PRETTY_FUNCTION__)
-
+#endif
void error(String s);
void warning(String s);
MAJVER=1
MINVER=0
-PATCHLEVEL=4
+PATCHLEVEL=5
PACKAGENAME=flower
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
string.hh stringutil.hh vray.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\
+ tsmat.hh tvsmat.hh plist.hh associter.hh\
+
+ * PointerList<T>:List<T> -> PointerList<T>:List<T*>
* efficient copy cons for List
#define ASSOC_HH
#include "vray.hh"
+#include <assert.h>
template<class K,class V>
struct Assoc_ent_ {
};
/** mindblowingly stupid Associative array implementation
*/
+
#endif
--- /dev/null
+/*
+ associter.hh -- part of flowerlib
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef ASSOCITER_HH
+#define ASSOCITER_HH
+
+#include "assoc.hh"
+
+/// an iterator for the #Assoc# class
+template<class K, class V>
+struct Assoc_iter {
+ int i;
+ Assoc<K,V> &assoc_;
+
+ Assoc_iter(Assoc<K,V> &a) :
+ assoc_(a)
+ {
+ i= next(0);
+ }
+ int next(int j) {
+ while (j < assoc_.arr.sz() && assoc_.arr[j].free)
+ j++;
+ return j;
+ }
+ bool ok() const {
+ return i < assoc_.arr.sz();
+ }
+ void OK()const {
+ assert(!ok() || !assoc_.arr[i].free);
+ }
+ void operator++(int) { i++; i = next(i); }
+ K key() { return assoc_.arr[i].key; }
+ V &val() { return assoc_.arr[i].val; }
+};
+/*
+ Iterator
+ */
+
+#endif
#include <fstream.h>
-
+#include "assoc.hh"
#include "dstream.hh"
#include "string.hh"
#include "textdb.hh"
String cl(strip_member(mem));
String idx = cl;
- if (silent.elt_query(mem))
+ if (silent->elt_query(mem))
idx = mem;
- else if (silent.elt_query(cl))
+ else if (silent->elt_query(cl))
idx = cl;
else {
- silent[idx] = false;
+ (*silent)[idx] = false;
}
- local_silence = silent[idx];
+ local_silence = (*silent)[idx];
if (classname != idx && !local_silence) {
classname=idx;
*os << "[" << classname << ":]";
bool
Dstream::silence(String s)
{
- if (!silent.elt_query(s))
+ if (!silent->elt_query(s))
return false;
- return silent[s];
+ return (*silent)[s];
}
///
Dstream &
Dstream::Dstream(ostream *r, const char * cfg_nm )
{
os = r;
+ silent = new Assoc<String,bool>;
if (!os)
return;
indentlvl = 0;
if (!ifs)
return;
}
- // cerr << "(" << fn;
+
Text_db cfg(fn);
while (! cfg.eof()){
Text_record r( cfg++);
assert(r.sz() == 2);
- silent[r[0]] = r[1].to_bool();
+ (*silent)[r[0]] = r[1].to_bool();
}
- // cerr <<")";
-}
+}
+Dstream::~Dstream()
+{
+ delete silent;
+}
#define DSTREAM_HH
#include "string.hh"
-#include "assoc.hh"
const char eol= '\n';
+template<class K,class V>
+struct Assoc;
+
/// debug stream
class Dstream
{
bool local_silence;
String classname;
- Assoc<String, bool> silent;
+ Assoc<String, bool> *silent;
public:
bool silence(String);
template<class T>
-void PL_copy(PointerList<T> &dst,PointerList<T> const&src);
+void PL_copy(PointerList<T*> &dst,PointerList<T*> const&src);
#define PL_instantiate(a) L_instantiate(a *); template class PointerList<a*>
inline void
PointerList_print( PointerList<T> const & l )
{
- List<T>& promises_to_be_const = (List<T>&) l;
- for ( Cursor<T> c( promises_to_be_const ); c.ok(); c++ )
- (*c)->print();
+ for (PCursor<T> c(l ); c.ok(); c++ )
+ c->print();
}
template<class T>
inline void
-PL_copy(PointerList<T> &to,PointerList<T> const&src)
+PL_copy(PointerList<T*> &to,PointerList<T*> const&src)
{
- for (PCursor<T> pc(src); pc.ok(); pc++) {
- T q = pc;
- T p=new typeof(*q) (*q) ; // argh, how do i do this in ANSI-C++
+ for (PCursor<T*> pc(src); pc.ok(); pc++) {
+ T *q = pc;
+ T *p=new T(*q) ; // argh, how do i do this in ANSI-C++
to.bottom().add(p);
}
}
--- /dev/null
+#include "string.hh"
+#include "parseconstruct.hh"
+#include "command.hh"
+
+Command*
+get_bar_command(Real w)
+{
+ Command*c = new Command;
+ c->when = w;
+ c->code = TYPESET;
+ c->args.add( "BAR");
+ c->args.add( "|");
+ c->priority = 100;
+ return c;
+}
+
+Command *
+get_meter_command(Real w, int n, int m)
+{
+ Command*c = new Command;
+
+ c->when = w;
+ c->code = TYPESET;
+ c->args.add( "METER");
+ c->args.add( n );
+ c->args.add( m );
+ c->priority = 50; // less than bar
+ return c;
+}
+
+Command *
+get_meterchange_command(int n, int m)
+{
+ Command*c = new Command;
+
+ c->code = INTERPRET;
+ c->args.add( "METER");
+ c->args.add( n );
+ c->args.add( m );
+ c->priority = 0; // more than bar
+ return c;
+}
+
+
+Command *
+get_skip_command(int n, Real m)
+{
+ Command*c = new Command;
+
+ c->code = INTERPRET;
+ c->args.add( "SKIP");
+ c->args.add( n );
+ c->args.add( m );
+ c->priority = 0; // more than bar
+ return c;
+}
+
+
output = 0;
pstaff_ = 0;
}
+void
+Item::print() const
+{
+ output->print();
+}
*/
String TeXstring () const ;
Item();
+ void print()const;
};
/** An item must be part of a Column
*/
mtor << "parens\n";
return YYText()[0];
}
+[:] {
+ char c = YYText()[0];
+ mtor << "misc char" <<c<<"\n";
+ return c;
+}
[ \t\n]+ {
}
+
%.* {
//ignore
}
\mdef\singledot{'00}
\mdef\doubledot{'01}
\mdef\tripledot{'02}
+
+
+
\def\maatstreep{\vrule height8pt depth8pt }
\def\finishbar{\vrule height8pt width 1pt depth8pt}
\parindent0pt
\newcount\n
\def\linestafsym#1#2{\hbox to 0pt{\vbox to 0pt{\n=0%
- \loop\ifnum\n<#1\advance\n by1
+ \loop\ifnum\n<#1\advance\n by1%
\ifnum\n>1\vskip2pt\fi \hrule width#2\repeat\vss}\hss}}
\def\vcenter#1{\vbox to 0pt{\vss #1\vss}}
\def\cquartrest{\vcenter\quartrest}
\def\ceighthrest{\vcenter\eighthrest}
\def\csixteenthrest{\vcenter\sixteenthrest}
-\def\cthirtysecondrest{\vcenter\thirtysecondrest}
\ No newline at end of file
+\def\cthirtysecondrest{\vcenter\thirtysecondrest}
+
+\def\lsingledot{\kern-6pt\singledot}
+\def\ldoubledot{\kern-6pt\doubledot}
+\def\ltripledot{\kern-6pt\tripledot}
\ No newline at end of file
Symbol eval(svec<String> a) const{
Symbol s;
- s.dim.x = Interval(0, convert_dimen(10,"pt"));
- s.dim.y = Interval(0, convert_dimen(10,"pt") );
+ s.dim.x = Interval( convert_dimen(-5,"pt"), convert_dimen(10,"pt"));
+ s.dim.y = Interval(0, convert_dimen(10,"pt") ); // todo
String src = the_sym_tables("param")->lookup("meter").tex;
s.tex = substitute_args(src,a);
return s;
score {
-% output "maartje.uit"
+ paper {
+ unitspace 3 cm
+ }
rhythmstaff {
voice { $ c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
}
r2 r4 r1
$ }
}
-
- bar 2 bar 3
- bar 4.5 bar 5 bar 5.5
- bar 6 bar 7 bar 8
-
- meter 2 4 4 % after bars.
-
+ commands {
+ meter 4 4
+ skip 3:0
+ meter 2 4
+ skip 8:0
+ }
}
#(cd $nm$old; touch depend; make clean)
#(cd $nm$new; touch depend; make clean)
(cd $nm$new; diff -P -c ../$nm$old . > ../patch-$new)
-rm -rf $nm$old
+rm -rf $nm$old $nm$new
#include "misc.hh"
#include "glob.hh"
-#include "mtime.hh"
+
#include <math.h>
int intlog2(int d) {
Real
-duration_to_idealspace(Mtime d, Real w)
+duration_to_idealspace(Real d, Real w)
{
// see Roelofs, p. 57
return w * pow(ENGRAVERS_SPACE, log2(d));
#ifndef MISC_HH
#define MISC_HH
-#include "mtime.hh"
+#include "real.hh"
int intlog2(int d);
-Real duration_to_idealspace(Mtime d,Real w);
+Real duration_to_idealspace(Real d,Real w);
#endif
#include "string.hh"
#include "molecule.hh"
#include "symbol.hh"
+#include "debug.hh"
+
+void
+Atom::print() const
+{
+ mtor << "texstring: " <<sym.tex<<"\n";
+}
Box
Atom::extent() const
return s;
}
-/****************************************************************/
String
Molecule::TeXstring() const
{
add(s);
}
+
+void
+Molecule::print() const
+{
+ for (PCursor<Atom*> c(ats); c.ok(); c++)
+ c->print();
+}
Box extent() const;
Atom(Symbol s);
+ void print() const;
String TeXstring() const;
};
String TeXstring() const;
Molecule(const Molecule&s);
+ void print() const;
private:
void operator=(const Molecule&);
};
+++ /dev/null
-#ifndef MTIME_HH
-#define MTIME_HH
-
-#include "real.hh"
-
-typedef Real Mtime;
-
-#endif
Voice_element * get_note_element(String,String);
Voice_element* get_rest_element(String,String);
Command * get_bar_command(Real);
-Command* get_meter_command(Real, int,int);
+
+Command* get_meterchange_command( int,int);
+Command* get_meter_command( Real,int,int);
+Command* get_skip_command( int,Real);
+
#include "score.hh"
#include "main.hh"
#include "keyword.hh"
+#include "scommands.hh"
#include "debug.hh"
#include "parseconstruct.hh"
#include "dimen.hh"
Real real;
Command *command;
Identifier *id;
-
+ Score_commands *scommands;
Voice *voice;
Voice_element *el;
Staff *staff;
}
%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
-%token CM IN PT MM PAPER WIDTH METER
+%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
%type <consstr> unit
%token <id> IDENTIFIER
%type <score> score_block score_body
%type <staff> staff_block rhythmstaff_block rhythmstaff_body
%type <i> int
-
+%type <scommands> score_commands_block score_commands_body
%%
score_body: { $$ = new Score; }
| score_body staff_block { $$->add($2); }
- | score_body score_command { $$->add($2); }
- | score_body paper_block { delete $$->paper;
- $$->paper = $2;
+ | score_body score_commands_block { $$->set($2); }
+ | score_body paper_block { $$->set($2); }
+ ;
+score_commands_block:
+ COMMANDS '{' score_commands_body '}' { $$ =$3;}
+ ;
+
+score_commands_body: { $$ = new Score_commands; }
+ | score_commands_body score_command {
+ $$->parser_add($2);
}
;
| paper_body OUTPUT STRING { $$->outfile = *$3;
delete $3;
}
+ | paper_body UNITSPACE dim { $$->whole_width = $3; }
;
dim:
;
score_command:
- BAR REAL {
- $$ = get_bar_command($2);
+ SKIP int ':' REAL {
+ $$ = get_skip_command($2, $4);
}
- | METER REAL int int {
- $$ = get_meter_command($2, $3, $4);
+ | METER int int {
+ $$ = get_meterchange_command($2, $3);
}
+/* | PARTIALMEASURE REAL {
+ $$ = get_partial_command($2);
+ }*/
;
+
int:
REAL {
void
Idealspacing::print() const
{
- #ifndef NPRINT
+#ifndef NPRINT
mtor << "idealspacing {" ;
mtor << "distance "<<space<< " strength " << hooke << "}\n";
- #endif
+#endif
}
Idealspacing::Idealspacing(const PCol * l,const PCol * r)
left = l;
right = r;
}
+
void
Idealspacing::OK() const
{
#ifndef NPRINT
mtor << "PCol {";
mtor << "# symbols: " << its.size() ;
- mtor << "breakable: " << breakable<<"\n";
+ if (breakable()){
+ mtor << "pre,post: ";
+ prebreak->print();
+ postbreak->print();
+ }
mtor << "extent: " << width().min << ", " << width().max << "\n";
mtor << "}\n";
#endif
PCol::OK () const
{
if (prebreak || postbreak ) {
- assert(breakable);
+ assert(prebreak&&postbreak);
+ assert(prebreak->daddy == this);
+ assert(postbreak->daddy == this);
}
}
void
PCol::set_breakable()
{
- if (breakable)
+ if (breakable())
return;
prebreak = new PCol(this);
postbreak = new PCol(this);
- breakable = true;
used = true;
}
+bool
+PCol::breakable() const
+{
+ return prebreak||postbreak;
+}
+
PCol::PCol(PCol *parent) {
daddy = parent;
prebreak=0;
postbreak=0;
- breakable=false;
line=0;
used = false;
}
PCol::~PCol()
{
- if (prebreak)
- delete prebreak; // no recursion!
- if (postbreak)
+
+ delete prebreak;
+
delete postbreak;
}
List<const Spanner*> stoppers, starters;
/// Can this be broken? true eg. for bars.
- bool breakable;
+ bool breakable()const;
/// does this column have items, does it have spacings attached?
bool used;
+/*
+ proto.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef PROTO_HH
+#define PROTO_HH
#include "real.hh"
-class Parametric_symbol;
class Line_of_score;
class Line_of_staff;
class PCol;
struct Keyword;
class Mixed_qp;
class Paperdef;
+class Score_commands;
+class Parametric_symbol;
+
+
+
+#endif // PROTO_HH
+
// utility functions for PScore
#include "debug.hh"
+#include "molecule.hh"
#include "dimen.hh"
#include "line.hh"
#include "pscore.hh"
for (PCursor<PCol *> c(cols); c.ok(); )
if (!c->used) {
c.del();
- mtor << "removing pcol\n";
} else
c++;
}
PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
{
assert(c && i && s);
- if (breakstat == 1 ) {
- typeset_item(i, c->prebreak, s, 0);
- } if (breakstat == 3)
- typeset_item(i, c->prebreak, s, 0 );
- else{
- its.bottom().add(i);
- s->add(i);
- c->add(i);
+// assert(!breakstat != 4 || c->breakable() );
+ if (breakstat == 0) {
+ typeset_item(i, c->prebreak, s);
+ return;
}
+
+ if (breakstat == 2) {
+ typeset_item(i, c->postbreak, s);
+ return;
+ }
+ if (c->daddy && c == c->daddy->prebreak) { // makeshift.
+ Interval iv (i->width());
+ if (!iv.empty()) {
+ svec<Item*> col_its (select_items(s, c));
+ for (int j =0; j < col_its.sz(); j++)
+ col_its[j]->output->translate(Offset(-iv.length(),0));
+ i->output->translate (Offset(-iv.max, 0));
+ }
+ }
+ its.bottom().add(i);
+ s->add(i);
+ c->add(i);
}
void
{
svec<const PCol *> retval;
for (PCursor<PCol *> c(cols); c.ok(); c++)
- if (c->breakable)
+ if (c->breakable())
retval.add(c);
return retval;
PScore::PScore()
{
- linewidth = convert_dimen(15,"cm");
+ linewidth = convert_dimen(15,"cm"); // default
}
void
void
PScore::OK()const
{
+#ifdef NDEBUG
for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
cc->OK();
for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
ic->OK();
-
+#endif
}
void
PScore::print() const
-{
-
- #ifndef NPRINT
- mtor << "PScore { width "<<print_dimen(linewidth);
+{
+#ifndef NPRINT
+ mtor << "PScore { width "<<print_dimen(linewidth);
mtor << "\ncolumns: ";
for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
cc->print();
for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
ic->print();
mtor << "}\n";
- #endif
+#endif
}
void add(PStaff *);
/// add item
- void typeset_item(Item *, PCol *,PStaff*,int);
+ void typeset_item(Item *, PCol *,PStaff*,int=1);
/// add to bottom of pcols
void add(PCol*);
/**
#include "glob.hh"
#include "string.hh"
-#include "mtime.hh"
+
struct Request {
Voice_element*elt;
#if 0
/// helper in the hierarchy
struct Dynamic {
- Mtime subtime;
+ Real subtime;
};
/** Each dynamic is bound to one note ( a crescendo spanning multiple
notes is thought to be made of two "dynamics": a start and a stop).
staff_ = rs;
}
-
+Rhythmic_staff::Rhythmic_staff()
+{
+ theline = new Linestaff(1);
+}
void
Rhythmic_staff::set_output(PScore* ps )
{
- theline = new Linestaff(1);
pscore_ = ps;
pscore_->add(theline);
}
void
Rhythmic_column::process_commands( )
{
- int breakstat = BREAK_END;
+ int breakstat = BREAK_END - BREAK_PRE;
for (int i = 0 ; i < s_commands.sz(); i++) {
Command *com = s_commands[i];
switch (com->code){
case BREAK_POST:
case BREAK_END:
score_column->set_breakable();
- breakstat = com->code;
+ breakstat = com->code- BREAK_PRE;
break;
case TYPESET:
the_note = rq;
}
break;
-
}
}
m->add_right(dm);
}
i->output=m;
- staff_->pscore_->typeset_item(i, score_column->pcol, staff_->theline,0 );
+ staff_->pscore_->typeset_item(i, score_column->pcol, staff_->theline );
}
void
struct Rhythmic_staff : Staff {
/// indirection to the PStaff.
PStaff *theline;
+
+ /****************/
void set_output(PScore *);
void process_commands( PCursor<Command*> &where);
void grant_requests();
Staff_column * create_col(Score_column*);
+ Rhythmic_staff();
};
#include "sccol.hh"
#include "debug.hh"
-Score_column::Score_column(Mtime w)
+Score_column::Score_column(Real w)
{
when = w;
pcol = new PCol(0);
#ifndef SCCOL_HH
#define SCCOL_HH
#include "pcol.hh"
-#include "mtime.hh"
struct Score_column {
PCol * pcol;
- svec<Mtime> durations;
- Mtime when;
+ svec<Real> durations;
+ Real when;
///
bool musical;
- Score_column(Mtime when);
+ Score_column(Real when);
static int compare(Score_column & c1, Score_column &c2) {
return sgn(c1.when - c2.when);
#include "scommands.hh"
#include "debug.hh"
+#include "parseconstruct.hh"
/*
maybe it's time for a "narrowing" cursor?
}
return false;
}
+
+void
+Score_commands::insert_between(Command victim, PCursor<Command*> firstc,
+ PCursor<Command*> last)
+{
+ assert(last->when==firstc->when);
+ PCursor<Command*> c(firstc+1);
+ while (c != last) { // hmm what if !last.ok()?
+ if (victim.priority > c->priority) {
+ c.insert(new Command(victim));
+ return;
+ }
+ c++;
+ }
+ last.insert(new Command(victim));
+
+}
void
Score_commands::add_command_to_break(Command pre, Command mid,Command post)
{
Real w = pre.when;
-
- Command k(w);
-
- PCursor<Command*> c ( first(w));
+ PCursor<Command*> c ( first(w)), f(c), l(c);
+
while (!c->isbreak())
c++;
- c.add(new Command(pre));
-
+ f = c++;
while (!c->isbreak())
c++;
- c.add(new Command(mid));
-
+ l = c++;
+
+ insert_between(pre, f, l);
+ f = l;
while (!c->isbreak())
c++;
- c.add(new Command(post));
+ l = c++;
+ insert_between(mid, f, l);
+ f = l;
+ while (!c->isbreak())
+ c++;
+ l = c++;
+ insert_between(post, f, l);
+ assert(l.ok() && l->when ==w && l->code == BREAK_END);
}
void
-Score_commands::add(Command c)
+Score_commands::parser_add(Command *c)
{
- bool encapsulate =false;
+ bottom().add(c);
+}
- Command pre(c.when);
- Command mid(c.when);
- Command post(c.when);
+void
+Score_commands::process_add(Command c)
+{
+ bool encapsulate =false;
+ Real w = c.when;
+ Command pre(w);
+ Command mid(w);
+ Command post(w);
if (c.code == TYPESET) {
if (c.args[0] == "BAR") {
- set_breakable(c.when);
+ set_breakable(w);
encapsulate = true;
mid = c;
pre = c;
}
- if (c.args[0] == "METER" && is_breakable(c.when)) {
+ if (c.args[0] == "METER" && is_breakable(w)) {
encapsulate = true;
mid = c;
pre = c;
c.code = TYPESET;
c.args.add("BAR");
c.args.add("empty");
- add(c);
+ process_add(c);
}
PCursor<Command*> bot(bottom());
while (bot.ok() && bot->when > l) {
-
- mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
+ mtor <<"removing ";
+ bot->print();
bot.del();
bot = bottom();
}
c.code = TYPESET;
c.args.add("BAR");
c.args.add("||");
- add(c);
+ process_add(c);
}
OK();
}
{
for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
assert(cc->when <= (cc+1)->when);
+ if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak())
+ assert(cc->priority >= (cc+1)->priority);
}
}
cc->print();
}
}
+
+Score_commands*
+Score_commands::parse(Real l) const
+{
+ Score_commands*nc = new Score_commands;
+ int beats_per_meas=4;
+ Real measlen = 1.0; // 4/4 by default
+
+ Real inbar=0.0;
+ int barcount=0;
+ Real wholes=0.0;
+ Real stoppos=0.0;
+
+ {
+ Command c(0.0);
+ c.code = TYPESET;
+ c.args.add("BAR");
+ c.args.add("empty");
+ nc->process_add(c);
+ }
+ for (PCursor<Command*> cc(*this); cc.ok() && cc->when <= l; cc++) {
+ assert (cc->code==INTERPRET);
+ if (cc->args[0] == "METER") {
+ beats_per_meas=cc->args[1].value();
+ int one_beat =cc->args[2].value ();
+ measlen = beats_per_meas/Real(one_beat);
+ nc->process_add(*get_meter_command(wholes,beats_per_meas, one_beat));
+ }
+ if (cc->args[0] == "SKIP") {
+ stoppos = wholes + cc->args[1].value() * measlen + cc->args[2].fvalue();
+ wholes += (measlen-inbar); // skip at least 1 measure
+ barcount++;
+ while (wholes <= stoppos) {
+ nc->process_add(*get_bar_command(wholes)); // liek
+ wholes += measlen;
+ barcount ++;
+ }
+ wholes = stoppos;
+ //something
+ }
+ }
+
+ return nc;
+}
#include "vray.hh"
#include "list.hh"
-struct Score_commands : public PointerList<Command*> {
- void add(Command);
+struct Score_commands : public PointerList<Command*> {
+ void process_add(Command);
+ Score_commands*parse(Real last)const;
+ void parser_add(Command*);
void add_seq(svec<Command>);
void clean(Real last);
void set_breakable(Real when);
void add_command_to_break(Command pre, Command mid,Command post);
void OK() const;
void print() const;
+ Real last() const;
+ void insert_between(Command victim, PCursor<Command*> firstc,
+ PCursor<Command*> last);
};
/** the list of commands in Score. Put in a separate class, since it
otherwise clutters the methods of Score. */
+#include "scommands.hh"
#include "tstream.hh"
#include "score.hh"
#include "sccol.hh"
#include "debug.hh"
#include "paper.hh"
+void
+Score::set(Paperdef*p)
+{
+ delete paper_;
+ paper_ = p;
+}
void
Score::output(String s)
{
OK();
- if (paper->outfile=="")
- paper->outfile = s;
+ if (paper_->outfile=="")
+ paper_->outfile = s;
- *mlog << "output to " << paper->outfile << "...\n";
- Tex_stream the_output(paper->outfile);
+ *mlog << "output to " << paper_->outfile << "...\n";
+ Tex_stream the_output(paper_->outfile);
pscore_->output(the_output);
}
void
Score::process()
{
- if (!paper)
- paper = new Paperdef;
-
- commands_.clean(last());
+ set(commands_->parse(last()));
+ commands_->print();
+
+ if (!paper_)
+ paper_ = new Paperdef;
+
+ commands_->clean(last());
/// distribute commands to disciples
distribute_commands();
*/
// todo
PCursor<Score_column*>
-Score::create_cols(Mtime w)
+Score::create_cols(Real w)
{
Score_column* c1 = new Score_column(w);
Score_column* c2 = new Score_column(w);
}
Score_column*
-Score::find_col(Mtime w,bool mus)
+Score::find_col(Real w,bool mus)
{
PCursor<Score_column*> scc(cols_);
for (; scc.ok(); scc++) {
Score::distribute_commands(void)
{
for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->add_commands(commands_);
+ sc->add_commands(*commands_);
}
}
void
pscore_->add(sc->pcol);
}
}
-Mtime
+Real
Score::last() const
{
- Mtime l = 0;
+ Real l = 0;
for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
l = MAX(l, stc->last());
}
for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
assert(cc->when <= (cc+1)->when);
}
- commands_.OK();
+ commands_->OK();
#endif
}
for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
sc->print();
}
- commands_.print();
+ commands_->print();
mtor << "}\n";
#endif
}
Score::Score()
{
pscore_=0;
- paper = 0;
+ paper_ = 0;
+ commands_ = new Score_commands;
}
+
+Score::~Score()
+{
+ delete pscore_;
+ delete commands_;
+ delete paper_;
+}
+
void
-Score::add(Command*c)
+Score::set(Score_commands*c)
{
- commands_.add(*c);
+ delete commands_;
+ commands_ = c;
}
#ifndef SCORE_HH
#define SCORE_HH
-
#include "vray.hh"
-#include "mtime.hh"
-#include "scommands.hh"
+#include "proto.hh"
+#include "list.hh"
+
/// the total music def of one movement
struct Score {
- Paperdef *paper;
- /// staffs_ and commands_ form the problem definition.
+ /// paper_, staffs_ and commands_ form the problem definition.
+ Paperdef *paper_;
PointerList<Staff *> staffs_;
- Score_commands commands_;
+ Score_commands *commands_;
/// "runtime" fields for setting up spacing
PointerList<Score_column*> cols_;
/****************************************************************/
- Score();
- void process();
-
/// construction
void add_staff(Staff *st);
+ void set(Paperdef*);
+ Score();
+ ~Score();
+ void add(Staff*);
+ void set(Score_commands*);
- void OK() const;
- Score_column *find_col(Mtime,bool);
- void do_pcols();
- void add(Staff*);
+ void OK() const;
+ Score_column *find_col(Real,bool);
+ void process();
void output(String fn);
- PCursor<Score_column*> create_cols(Mtime);
+ PCursor<Score_column*> create_cols(Real);
void print() const;
-
- Mtime last() const;
-
- void add(Command*);
+ Real last() const;
private:
-
+ void do_pcols();
void clean_cols();
void distribute_commands();
void do_connect(PCol *c1, PCol *c2, Real d);
#include "main.hh"
#include "score.hh"
+#include "string.hh"
static svec<Score*> sv;
for (int i=0; i < sv.sz(); i++) {
sv[i]->process();
sv[i]->output(outfn);
+ delete sv[i];
+ sv[i] =0;
}
}
}
Staff_column *
-Staff::get_col(Mtime w, bool mus)
+Staff::get_col(Real w, bool mus)
{
Score_column* sc = score_->find_col(w,mus);
assert(sc->when == w);
for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
- Mtime now = vc->start;
+ Real now = vc->start;
for (PCursor<Voice_element *> ve(vc->elts); ve.ok(); ve++) {
Staff_column *sc=get_col(now,true);
}
-Mtime
+Real
Staff::last() const {
- Mtime l = 0.0;
+ Real l = 0.0;
for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
l = MAX(l, vc->last());
}
#endif
}
+Staff::Staff()
+{
+ score_ =0;
+ pscore_=0;
+
+}
Score *score_;
PScore *pscore_;
+ /****************************************************************/
+
void add_voice(Voice *v);
void add_staff_column(Staff_column *sp);
/**
This routines calls virtual functions from Staff, to delegate the
interpretation of requests to a derived class of Staff */
-
-
- /****************************************************************
- VIRTUALS
- ****************************************************************/
-
void setup_staffcols();
- virtual void set_output(PScore * destination)=0;
- virtual void grant_requests()=0;
-
- Staff_column * get_col(Mtime,bool);
+ void OK() const;
+ void print() const;
+ Real last() const;
+ void clean_cols() ;
+ Staff_column * get_col(Real,bool);
void add_commands(PointerList<Command* >const & sv);
/**
PRE
sv is time-ordered.
*/
+
+ Staff();
+ /**
+ Should construct with Score as arg, but this isn't known during parsing.
+ */
+ /****************************************************************
+ VIRTUALS
+ ****************************************************************/
+
+ virtual void set_output(PScore * destination)=0;
+ virtual void grant_requests()=0;
virtual Staff_column * create_col(Score_column * )=0;
+ virtual ~Staff() { }
- void OK() const;
- void print() const;
- Mtime last() const;
- void clean_cols() ;
- virtual ~Staff() { }
};
#endif
+
+
return score_column->musical;
}
-Mtime
+Real
Staff_column::when() const
{
return score_column->when;
void
Staff_column::add(Voice_element*ve)
{
- Mtime d= ve->duration;
+ Real d= ve->duration;
if (d){
score_column->durations.add(d);
}
svec<Command *> s_commands;
Staff_column(Score_column*s);
- bool mus() const ;
+ bool mus() const;
Real when() const;
void add(Voice_element*ve);
/****************************************************************
score{
rhythmstaff {
- voice { $c2 c2 c2 c2$ }
+ voice { $ c2 c2 c4. c8 c4 c4 c4 c4 c4 c4 c2 c2$ }
}
+ commands { meter 2 4 skip 2:0 meter 4 4 skip 2:0}
}
end
table dots
- 1 \singledot 0pt 4pt -1pt 1pt
- 2 \doubledot 0pt 8pt -1pt 1pt
- 3 \tripledot 0pt 12pt -1pt 1pt
+ 1 \lsingledot 0pt 8pt -1pt 1pt
+ 2 \ldoubledot 0pt 12pt -1pt 1pt
+ 3 \ltripledot 0pt 16pt -1pt 1pt
end
"paper", PAPER,
"width", WIDTH,
"meter", METER,
+ "unitspace", UNITSPACE,
+ "skip", SKIP,
+ "commands", COMMANDS,
0,0
} ;
#endif
}
-Mtime
+Real
Voice::last() const
{
- Mtime l =start;
+ Real l =start;
for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
l += vec->duration;
return l;
#ifndef VOICE_HH
#define VOICE_HH
-#include "mtime.hh"
+
#include "list.hh"
#include "request.hh"
/// class for horizontal stuff.
struct Voice {
PointerList<Voice_element *> elts;
- Mtime start;
+ Real start;
/****************/
- Mtime when(const Voice_element*)const;
- Mtime last() const;
+ Real when(const Voice_element*)const;
+ Real last() const;
Voice();
void add(Voice_element*);
void print() const;
///
struct Voice_element {
- Mtime duration;
+ Real duration;
const Voicegroup *group;
const Voice *voice;
PointerList<Request*> reqs;