+++ /dev/null
-#include "boxes.hh"
-#include "const.hh"
-
-void
-Interval::set_empty() {
- min = INFTY;
- max = -INFTY;
-}
-Real
-Interval::length() const {
- return max-min;
-}
-Box::Box(svec<Real> s)
-{
- assert(s.sz() == 4);
- x.min = s[0];
- x.max = s[1];
- y.min = s[2];
- y.max = s[3];
-}
-
-Box::Box()
-{
-}
-
-Box::Box(Interval ix, Interval iy)
-{
- x = ix;
- y = iy;
-}
-
+++ /dev/null
-/*
- some 2D geometrical concepts
-*/
-
-#ifndef BOXES_HH
-#define BOXES_HH
-
-#include "textdb.hh"
-#include "real.hh"
-#include "vray.hh"
-
-/// 2d vector
-struct Offset {
- Real x,y;
-
- Offset operator+(Offset o)const {
- Offset r(*this);
- r+=o;
- return r;
- }
-
- Offset operator+=(Offset o) {
- x+=o.x;
- y+=o.y;
- return *this;
- }
- Offset(Real ix , Real iy) {
- x=ix;
- y=iy;
- }
- Offset() {
- x=0.0;
- y=0.0;
- }
-};
-
-/// a Real interval
-struct Interval {
- Real min, max;
-
- void translate(Real t) {
- min += t;
- max += t;
- }
-
- void unite(Interval h) {
- if (h.min<min)
- min = h.min;
- if (h.max>max)
- max = h.max;
- }
- Real length() const;
- void set_empty() ;
- bool empty() { return min > max; }
- Interval() {
- set_empty();
- }
- Interval(Real m, Real M) {
- min =m;
- max = M;
- }
-};
-
-
-/// a 4-tuple of #Real#s
-struct Box {
- Interval x, y;
-
- void translate(Offset o) {
- x.translate(o.x);
- y.translate(o.y);
- }
- void unite(Box b) {
- x.unite(b.x);
- y.unite(b.y);
- }
- Box(svec<Real> );
- Box();
- Box(Interval ix, Interval iy);
-};
-
-
-#endif
+++ /dev/null
-/*
- do calculations for breaking problem
-
- */
-#include "paper.hh"
-#include "linespace.hh"
-#include "debug.hh"
-#include "line.hh"
-#include "pscore.hh"
-
-// construct an appropriate Spacing_problem and solve it.
-svec<Real>
-PScore::solve_line(svec<const PCol *> curline) const
-{
- Spacing_problem sp;
-
- sp.add_column(curline[0], true, 0.0);
- for (int i=1; i< curline.sz()-1; i++)
- sp.add_column(curline[i]);
- sp.add_column(curline.last(), true, paper_->linewidth);
-
- // misschien moeven uit Spacing_problem?
- for (PCursor<Idealspacing *> i(suz); i.ok(); i++) {
- sp.add_ideal(i);
- }
- svec<Real> the_sol=sp.solve();
- return the_sol;
-}
-
-
-void
-PScore::problem_OK() const
-{
- if (!cols.size())
- error("PScore::problem_OK(): Score does not have any columns");
- PCursor<PCol *> start(cols);
- PCursor<PCol *> end (((PScore*)this)->cols.bottom());
-
- assert(start->breakable());
- assert(end->breakable());
-}
-
-struct Col_configuration {
- svec<const PCol*> line;
- svec<Real> config;
- Real energy;
-
- Col_configuration() {
- energy = INFTY;
- }
- void add(const PCol*c) { line.add(c);}
- void setsol(svec<Real> sol) {
- config = sol;
- 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 done more accurately:
-
- It would be nice to have a Dynamic Programming type of algorithm
- similar to TeX's
-
- */
-
-void
-PScore::calc_breaking()
-{
- OK();
- problem_OK();
- PCursor<PCol *> curcol(cols);
-
- svec<const PCol *> breakpoints(find_breaks());
- assert(breakpoints.sz()>=2);
- for (int i=0 ; i < breakpoints.sz() -1; ) {
- Col_configuration minimum;
- Col_configuration current;
-
- // do another line
- PCol *post = breakpoints[i]->postbreak;
- current.add( post);
- curcol++; // skip the breakable.
- i++;
-
- while (i < breakpoints.sz()) {
-
- // add another measure.
- while(breakpoints[i] !=curcol){
-
- current.add(curcol);
- curcol++;
- }
- current.add(breakpoints[i]->prebreak );
- current.setsol(solve_line(current.line));
- current.print();
-
- if (current.energy < minimum.energy) {
- minimum = current;
- } else { // we're one col too far.
- i--;
- while (curcol != breakpoints[i])
- curcol --;
-
- break;
- }
-
- current.line.last()=breakpoints[i];
- curcol ++;
- i++;
- }
- mtor << "Adding line, next breakpoint " << i << '\n';
- add_line(minimum.line, minimum.config);
- }
-}
-
+++ /dev/null
-#include "tstream.hh"
-#include "score.hh"
-#include "pscore.hh"
-#include "staff.hh"
-#include "paper.hh"
-#include "sccol.hh"
-#include "debug.hh"
-
-
-void
-Score::do_connect(PCol *c1, PCol *c2, Real d)
-{
- Idealspacing*sp=pscore_->get_spacing(c1,c2);
-
- if (!sp->hooke){
- sp->hooke = 1.0;
- sp->space =d;
- }
-}
-
-void
-Score::connect_nonmus(PCol* c1, PCol *c2, Real d)
-{
- if (c2->used && c1->used) {
- do_connect(c1,c2,d);
-
- // alert! this is broken!
- if (c1->breakable()) {
- do_connect(c1->postbreak, c2,d);
- }
- if (c2->breakable()) {
- do_connect(c1, c2->prebreak,d);
- }
- if (c1->breakable() &&c2->breakable()) {
- do_connect(c1->postbreak, c2->prebreak,d);
- }
- }
-}
-/* this needs A LOT of rethinking.
-
- generate springs between columns.
- */
-void
-Score::calc_idealspacing()
-{
- PCursor<Score_column*> sc(cols_);
-
- for (; sc.ok(); sc++) {
- if (sc->musical)
- for (int i=0; i < sc->durations.sz(); i++) {
- Real d = sc->durations[i];
- Real dist = paper_->duration_to_dist(d);
- PCol * c2 = find_col(sc->when + d,true)->pcol;
- connect_nonmus(sc->pcol, c2, dist);
- c2 = find_col(sc->when + d,false)->pcol;
- connect_nonmus(sc->pcol, c2, dist);
- }
- else if (sc->used()) { // ignore empty columns
- PCol * c2 = find_col(sc->when,true)->pcol;
- connect_nonmus(sc->pcol,c2,0.0);
- }
- }
-}
-
-
+++ /dev/null
-#include "string.hh"
-#include "debug.hh"
-#include "command.hh"
-
-bool
-Command::isbreak()const
-{
- return (code >= BREAK_PRE && code <= BREAK_END);
-}
-
-Command::Command()
-{
- code = NOP;
- when = -1;
- priority=0;
-}
-
-
-
-Command::Command(Real w)
-{
- code = NOP;
- when = w;
- priority=0;
-}
-
-void
-Command::print() const
-{
-#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
-}
+++ /dev/null
-#ifndef COMMAND_HH
-#define COMMAND_HH
-#include "glob.hh"
-
-#include "vray.hh"
-#include "string.hh"
-
-enum Commandcode {
- NOP,
- INTERPRET,
- TYPESET,
- BREAK_PRE,BREAK_MIDDLE, BREAK_POST, BREAK_END
-};
-/// set a nonrythmical symbol
-struct Command {
- Commandcode code;
-
- Real when;
- /// analogous to argv[]
- svec<String> args;
- int priority;
-
- /****************/
-
- Command();
- Command(Real w);
- bool isbreak()const;
- void print() const;
-};
-
-/**
- A nonrhythmical "thing" in a staff is called a "command".
- Commands have these properties:
-
- \begin{itemize}
- \item They are \bf{not} rhythmical, i.e. they do not have a duration
- \item They have a staff-wide impact, i.e. a command cannot be targeted at
- only one voice in the staff: two voices sharing a staff can't have
- different clefs
- \item Commands are ordered, that is, when from musical point of view the
- commands happen simultaneously, the order in which Staff receives the
- commands can still make a difference in the output
- \item Some commands are actually score wide, so Score has to issue these
- commands to the Staff, eg. BREAK commands
- \end{itemize}
-
- At this moment we have three classes of commands:
- \begin{description}
- INTERPRET commands are not grouped.
- \item[TYPESET] These commands instruct the Staff to
- typeset symbols on the output, eg meter/clef/key changes
- \item[INTERPRET] These commands do not produce output, instead,
- they change the interpretation of other commands or requests.
- example: shift output vertically, set the key.
- \item[BREAK_XXX] These commands group TYPESET commands in
- prebreak and postbreak commands. \See{Col}.
- Staff can insert additional commands in a sequence of BREAK_XXX
- commands, eg. key change commands
-
- \end{description}
-
- These commands are generated by Score, since they have to be the
- same for the whole score.
-
-
- \begin{description}
- \item[BREAK_PRE]
- \item[BREAK_MIDDLE]
- \item[BREAK_POST]
- \item[BREAK_END]
- \item[TYPESET] METER,BAR
- \end{description}
-
-
- Commands can be freely copied, they do not have virtual methods.
- */
-
-
-#endif
+++ /dev/null
-/*
- global constants
- */
-#ifndef CONST_HH
-#define CONST_HH
-#include <math.h>
-#include "real.hh"
-
-const Real EPS=1e-7; // qlpsolve.hh
-const int MAXITER=100; // qlpsolve.hh
-const Real INFTY=HUGE;
-#endif
+++ /dev/null
-#include <fstream.h>
-#include <std/new.h>
-#include "debug.hh"
-#include "dstream.hh"
-#include "vector.hh"
-
-Dstream monitor(&cout,".dstreamrc");
-ostream * nulldev = new ofstream("/dev/null");
-
-
-/*
- want to do a stacktrace .
- */
-void
-mynewhandler()
-{
- cerr << "Out of free store memory. Aborting.. "<< flush;
- assert(false);
-}
-
-
-void
-debug_init()
-{
- set_new_handler(&mynewhandler);
- set_matrix_debug(monitor);
-}
+++ /dev/null
-#ifndef DEBUG_HH
-#define DEBUG_HH
-#include <assert.h>
-#include <iostream.h>
-#include "dstream.hh"
-
-void error(String s); // errors
-
-// warnings
-void warning(String s);
-#define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
-extern ostream &warnout ;
-
-// progress
-extern ostream *mlog;
-
-// debugging
-extern Dstream monitor; // monitor
-
-#ifdef NPRINT
-#define mtor if (0) monitor // clever hack
-#else
-#define mtor monitor.identify_as(__PRETTY_FUNCTION__)
-#endif
-
-
-
-#endif
+++ /dev/null
-#include <ctype.h>
-#include "dimen.hh"
-#include "debug.hh"
-#include "string.hh"
-
-Real
-parse_dimen(String dim)
-{
- int i=dim.len()-1;
- const char *s = dim;
- while (i > 0 && (isspace(s[i]) || isalpha(s[i])) ){
- i--;
- }
- String unit(s + i+1);
- return convert_dimen(dim.fvalue(), unit);
-}
-
-const Real CM_TO_PT=72/2.54;
-
-Real
-convert_dimen(Real quant, String unit)
-{
- if (unit == "cm")
- return quant * CM_TO_PT;
- if (unit == "pt")
- return quant;
- if (unit == "mm")
- return quant*CM_TO_PT/10;
- if (unit == "in")
- return quant * 72;
- error ("unknown length unit: `" + unit+"'");
-}
-
-String
-print_dimen(Real r)
-{
- String s(r);
- s += "pt ";
- return s;
-}
+++ /dev/null
-#ifndef DIMEN_HH
-#define DIMEN_HH
-
-#include "real.hh"
-#include "string.hh"
-
-Real parse_dimen(String);
-Real convert_dimen(Real, String);
-String print_dimen(Real);
-
-#endif
-
+++ /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;
-}
-
-
+++ /dev/null
-#ifndef GLOB_HH
-#define GLOB_HH
-#include <assert.h>
-#include <math.h>
-#include "real.hh"
-
-#include "proto.hh"
-#include "const.hh"
-#endif
+++ /dev/null
-#include <assert.h>
-#include "identifier.hh"
-#include "staff.hh"
-#include "lexer.hh"
-#include "parser.hh"
-
-Identifier::Identifier(String n)
- :name (n)
-{
- data = 0;
-}
-
-
-Identifier::~Identifier()
-{
-}
-
-Staff_id::~Staff_id()
-{
- delete staff();
-}
-
-Voice_id::~Voice_id()
-{
- delete voice();
-}
+++ /dev/null
-
-/*
- identifier.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef IDENTIFIER_HH
-#define IDENTIFIER_HH
-#include "proto.hh"
-#include "string.hh"
-
-struct Identifier
-{
- void *data;
- String name;
-
- Identifier(String n) ;
- virtual ~Identifier();
- virtual Staff * staff() { assert(false); }
- virtual Voice * voice() { assert(false); }
-};
-
-struct Staff_id : Identifier {
- Staff_id(String s, Staff*st):Identifier(s) { data = st; }
- virtual Staff* staff() { return (Staff*) data; }
- ~Staff_id();
-};
-
-struct Voice_id : Identifier {
- Voice_id(String s, Voice*st):Identifier(s) { data = st; }
- virtual Voice * voice() { return (Voice*)data; }
- ~Voice_id();
-};
-#endif // IDENTIFIER_HH
-
+++ /dev/null
-#include "line.hh"
-#include "symbol.hh"
-#include "molecule.hh"
-#include "pcol.hh"
-
-void
-Item::postprocess()
-{
- // default: do nothing
-}
-
-
-void
-Item::preprocess()
-{
- // default: do nothing
-}
-
-String
-Item::TeXstring() const
-{
- return output->TeXstring();
-}
-
-Interval
-Item::width() const
-{
- return output->extent().x;
-}
-
-Interval
-Item::height() const
-{
- return output->extent().y;
-}
-
-Item::~Item()
-{
- delete output;
-}
-
-Item::Item()
-{
- col = 0;
- output = 0;
- pstaff_ = 0;
-}
-void
-Item::print() const
-{
- output->print();
-}
+++ /dev/null
-#ifndef ITEM_HH
-#define ITEM_HH
-
-#include "glob.hh"
-#include "boxes.hh"
-#include "string.hh"
-
-/// a horizontally fixed size element of the score
-struct Item {
- const PCol * col;
- Molecule *output;
-
- PStaff *pstaff_;
- /** needed for knowing at which staff to output this item
- */
-
- /****************/
-
- /// do calculations after determining horizontal spacing
- virtual void postprocess();
-
- /// do calculations before determining horizontal spacing
- virtual void preprocess();
- /**
- This is executed directly after the item is added to the
- PScore
- */
-
- virtual Interval width() const;
- virtual Interval height() const;
- String TeXstring () const ;
- Item();
- void print()const;
- virtual ~Item();
-};
-/** Item is the datastructure for printables whose width is known
- before the spacing is calculated
-
- NB. This doesn't mean an Item has to initialize the output field before
- spacing calculation.
-
-*/
-
-
-#endif
+++ /dev/null
-/*
- keyword.cc -- keywords and identifiers
- */
-
-#include <stdlib.h>
-
-#include "glob.hh"
-#include "lexer.hh"
-//#include "mudobs.hh"
-//#include "gram.hh"
-
-/* for the keyword table */
-struct Keyword_ent
-{
- const char *name;
- int tokcode;
-};
-
-struct Keyword_table
-{
- Keyword_ent *table;
- int maxkey;
- Keyword_table(Keyword_ent *);
- int lookup(const char *s) const;
-};
-
-
-/* for qsort */
-int
- tabcmp(const void * p1, const void * p2)
-{
- return strcmp(((const Keyword_ent *) p1)->name,
- ((const Keyword_ent *) p2)->name);
-}
-
-Keyword_table::Keyword_table(Keyword_ent *tab)
-{
- table = tab;
-
- /* count keywords */
- for (maxkey = 0; table[maxkey].name; maxkey++);
-
- /* sort them */
- qsort(table, maxkey, sizeof(Keyword_ent), tabcmp);
-}
-
-/*
- lookup with binsearch, return tokencode.
-*/
-int
-Keyword_table::lookup(const char *s)const
-{
- int lo,
- hi,
- cmp,
- result;
- lo = 0;
- hi = maxkey;
-
- /* binary search */
- do
- {
- cmp = (lo + hi) / 2;
-
- result = strcmp(s, table[cmp].name);
-
- if (result < 0)
- hi = cmp;
- else
- lo = cmp;
- }
- while (hi - lo > 1);
- if (!strcmp(s, table[lo].name))
- {
- return table[lo].tokcode;
- } else
- return -1; /* not found */
-}
-
+++ /dev/null
-/* for the keyword table */
-struct Keyword_ent
-{
- const char *name;
- int tokcode;
-};
-
-struct Keyword_table
-{
- Keyword_ent *table;
- int maxkey;
- Keyword_table(Keyword_ent *);
- int lookup(const char *s) const;
-};
+++ /dev/null
-#ifndef LEXER_HH
-#define LEXER_HH
-
-#include "proto.hh"
-
-void new_input(String s);
-bool close_input();
-int yylex();
-void yyerror(char *s);
-
-int lookup_keyword(String s);
-
-Identifier* lookup_identifier(String s);
-void add_identifier(Identifier*i);
-void delete_identifiers();
-#endif
+++ /dev/null
-%{ // -*-Fundamental-*-
-
-#include <fstream.h>
-#include <stdio.h>
-#include "glob.hh"
-#include "string.hh"
-
-#include "lexer.hh"
-#include "keyword.hh"
-#include "vray.hh"
-#include "parser.hh"
-#include "debug.hh"
-
-sstack<istream *> include_stack;
-static int last_print;
-const int DOTPRINT=50; // every 50 lines dots
-%}
-
-%option c++
-%option noyywrap
-%option nodefault
-%option yylineno
-%option debug
-%x notes
-%x incl
-%x quote
-
-OPTSIGN !?
-NOTENAMEI A|B|C|D|E|F|G|As|Bes|Ces|Des|Es|Fes|Ges|Ais|Bis|Cis|Dis|Eis|Fis|Gis
-NOTENAMEII a|b|c|d|e|f|g|as|bes|ces|des|es|fes|ges|ais|bis|cis|dis|eis|fis|gis
-NOTENAMEIII Ases|Beses|Ceses|Deses|Eses|Feses|Geses|Aisis|Bisis|Cisis|Disis|Eisis|Fisis|Gisis
-NOTENAMEIIII ases|beses|ceses|deses|eses|feses|geses|aisis|bisis|cisis|disis|eisis|fisis|gisis
-RESTNAME r|s
-NOTENAME {NOTENAMEI}|{NOTENAMEII}|{NOTENAMEIII}|{NOTENAMEIIII}
-PITCH ['`]*{OPTSIGN}{NOTENAME}
-DURNAME 1|2|4|8|16|32
-DURATION {DURNAME}\.*
-FULLNOTE {PITCH}{DURATION}?
-WORD [a-zA-Z][a-zA-Z0-9_]+
-REAL [0-9]+(\.[0-9]*)?
-
-%%
-
-\$ {
- BEGIN(notes); return '$';
-}
-
-<notes>{RESTNAME} {
- const char *s = YYText();
- yylval.string = new String (s);
- mtor << "rest:"<< yylval.string;
- return RESTNAME;
-}
-<notes>{PITCH} {
- const char *s = YYText();
- yylval.string = new String (s);
- mtor << "pitch:"<< *yylval.string;
- return PITCH;
-}
-<notes>{DURATION} {
- yylval.string = new String (YYText());
- return DURATION;
-}
-<notes>[:space:]+ {
-}
-<notes>[ \t\n]+ {
-}
-<notes>%.* {
-
-}
-<notes>\$ {
- BEGIN(INITIAL); return '$';
-}
-<notes>. {
- error("lexer error: illegal character found: " + String(YYText()));
-}
-
-\" {
- BEGIN(quote);
-}
-<quote>[^\"]* {
- yylval.string = new String (YYText());
-}
-<quote>\" {
- BEGIN(INITIAL);
- return STRING;
-}
-
-<<EOF>> {
- if(!close_input())
- yyterminate();
-}
-{WORD} {
- int l = lookup_keyword(YYText());
- if (l != -1)
- return l;
- Identifier * id = lookup_identifier(YYText());
- if (id) {
- yylval.id = id;
- return IDENTIFIER;
- }
- String *sp = new String( YYText());
- mtor << "new id: " << *sp;
- yylval.string=sp;
- return NEWIDENTIFIER;
-}
-
-{REAL} {
- Real r;
- int cnv=sscanf (YYText(), "%lf", &r);
- assert(cnv == 1);
- mtor << "token (REAL)" << r;
- yylval.real = r;
- return REAL;
-}
-
-[\{\}\[\]\(\)] {
-
- mtor << "parens\n";
- return YYText()[0];
-}
-[:=] {
- char c = YYText()[0];
- mtor << "misc char" <<c<<"\n";
- return c;
-}
-[ \t\n]+ {
-
-}
-
-%.* {
- //ignore
-}
-. {
- error("lexer error: illegal character '"+String(YYText()[0])+
- "' encountered");
- return YYText()[0];
-}
-
-%%
-
-yyFlexLexer *lexer=0;
-
-// set the new input to s, remember old file.
-void
-new_input(String s)
-{
- istream *newin ;
-
- if (s=="")
- newin = &cin;
- else
- newin = new ifstream( s ); //
-
- if ( ! *newin)
- error("cant open " + s);
- cout << "["<<s<<flush;
-
- include_stack.push(newin);
-
- if (!lexer) {
- lexer = new yyFlexLexer;
- lexer->set_debug( !monitor.silence("Lexer"));
- }
-
- lexer->switch_streams(newin);
-}
-
-
-// pop the inputstack.
-bool
-close_input()
-{
-
- istream *closing= include_stack.pop();
- if (closing != &cin)
- delete closing;
-
- cout << "]" << flush;
-
- if (include_stack.empty())
- return false ;
- else
- lexer->switch_streams(include_stack.top());
- return true;
-}
-
-int
-yylex() {
- return lexer->yylex();
-}
-
-void
-yyerror(char *s)
-{
- *mlog << "error in line " << lexer->lineno() << ": " << s << '\n';
- exit(1);
-}
-
-
-#if 0
-
-<notes>{NOTENAME} {
- yylval.string = new String (YYText());
- return NOTENAME;
-}
-
-#endif
+++ /dev/null
-#include "line.hh"
-#include "dimen.hh"
-#include "spanner.hh"
-#include "symbol.hh"
-#include "paper.hh"
-#include "pcol.hh"
-#include "pscore.hh"
-
-static String
-make_vbox(Interval i)
-{
-
- String s("\\vbox to ");
- s += print_dimen(i.length());
- s += "{\\vskip "+print_dimen(i.max)+" ";
- return s;
-}
-
-
-String
-Line_of_staff::TeXstring() const
-{
- String s("%line_of_staff\n");
- s+=make_vbox(height());
- // the staff itself: eg lines, accolades
- s += "\\hbox{";
- {
- Symbol sym = pstaff_->get_stafsym(scor->score->paper_->linewidth);
- s+=sym.tex;
- PCursor<const PCol *> cc(scor->cols);
- Real lastpos=cc->hpos;
-
- // all items in the current line & staff.
- for (; cc.ok(); cc++) {
- Real delta=cc->hpos - lastpos;
- lastpos = cc->hpos;
-
- // moveover
- if (delta)
- s +=String( "\\kern ") + print_dimen(delta);
-
- // now output the items.
-
- for (PCursor<const Item *> ic(cc->its); ic.ok(); ic++) {
- if (ic->pstaff_ == pstaff_)
- s += ic->TeXstring();
- }
- // spanners.
- for (PCursor<const Spanner *> sc(cc->starters); sc.ok(); sc++)
- if (sc->pstaff_ == pstaff_)
- s += sc->TeXstring();
- }
- }
- s+="\\hss}\\vss}";
- return s;
-}
-
-Line_of_staff::Line_of_staff(Line_of_score * sc, PStaff*st)
-{
-
- scor=sc;
- pstaff_=st;
-
- const PCol *linestart= sc->cols.top();
- const PCol *linestop=sc->cols.bottom();
-
- for (PCursor<const Spanner*> sp(pstaff_->spans); sp.ok(); sp++) {
- const PCol *brokenstart = &MAX(*linestart, *sp->left);
- const PCol *brokenstop = &MIN(*linestop, *sp->right);
-
- if (*brokenstop < *brokenstart)
- brokenspans.bottom().add(sp->broken_at(brokenstop, brokenstart));
- }
-}
-
-
-Interval
-Line_of_staff::height() const
-{
- Interval y;
- {
- Symbol s = pstaff_->stafsym->eval(scor->score->paper_->linewidth);
- y = s.dim.y;
- }
- PCursor<const PCol *> cc(scor->cols);
-
- // all items in the current line & staff.
- for (; cc.ok(); cc++) {
- for (PCursor<const Item *> ic(cc->its); ic.ok(); ic++) {
- if (ic->pstaff_ == pstaff_) {
- y.unite(ic->height());
- }
-
- // spanners.
- for (PCursor<const Spanner *> sc(cc->starters); sc.ok(); sc++)
- if (sc->pstaff_ == pstaff_)
- assert(false);
- }
- }
- return y;
-}
-
-
-/****************************************************************/
-String
-Line_of_score::TeXstring() const
-{
- String s("\\vbox{%<- line of score\n");
- for (PCursor<Line_of_staff*> sc(staffs); sc.ok(); sc++){
- s += sc->TeXstring();
- if ((sc+1).ok())
- s+= "\\interstaffline\n";
- }
- s += "}";
- return s;
-}
-
-/// testing this entry
-Line_of_score::Line_of_score(svec<const PCol *> sv,
- const PScore *ps)
-{
- score = ps;
- for (int i=0; i< sv.sz(); i++) {
- PCol *p=(PCol *) sv[i];
- cols.bottom().add(p);
- p->line=this;
- }
-
- for (PCursor<PStaff*> sc(score->staffs); sc.ok(); sc++)
- staffs.bottom().add(new Line_of_staff(this, sc));
-}
-/** construct a line with the named columns. Make the line field
- in each column point to this
-
- #sv# isn't really const!!
- */
-
+++ /dev/null
-#ifndef LINE_HH
-#define LINE_HH
-
-/*
- horizontal structures for broken scores.
-*/
-
-#include "real.hh"
-#include "plist.hh"
-#include "vray.hh"
-#include "glob.hh"
-#include "pstaff.hh"
-
-
-
-/// the columns of a score that form one line.
-struct
-Line_of_score {
- List<const PCol *> cols;
-
- // need to store height of each staff.
- PointerList<Line_of_staff*> staffs;
- const PScore * score; // needed to generate staffs
-
- /****************/
-
- Line_of_score(svec<const PCol *> sv, const PScore *);
-
- String TeXstring() const;
-
- // is #c# contained in #*this#?
- bool element(const PCol *c);
-};
-
-/// one broken line of staff.
-struct Line_of_staff {
- PointerList<Spanner *> brokenspans;
- Line_of_score const * scor;
- const PStaff *pstaff_;
-
- /****************/
-
- String TeXstring() const;
- Line_of_staff(Line_of_score*, PStaff *);
- Interval height() const;
-};
-
-#endif
+++ /dev/null
-#include <math.h>
-#include "linespace.hh"
-#include "debug.hh"
-#include "qlp.hh"
-#include "unionfind.hh"
-
-const Real COLFUDGE=1e-3;
-//#define COLFUDGE 1e-3
-bool
-Spacing_problem::contains(const PCol *w)
-{
- for (int i=0; i< cols.sz(); i++)
- if (cols[i].col == w)
- return true;
- return false;
-}
-
-int
-Spacing_problem::col_id(const PCol *w)const
-{
- for (int i=0; i< cols.sz(); i++)
- if (cols[i].col == w)
- return i;
- assert(false);
-}
-
-void
-Spacing_problem::OK() const
-{
-#ifndef NDEBUG
- Union_find connected(cols.sz());
-
- for (int i=0; i < ideals.sz(); i++) {
- assert(ideals[i]->hooke > 0);
- int l = col_id(ideals[i]->left);
- int r = col_id(ideals[i]->right);
- connected.connect(l,r);
- }
-
- for (int i = 0; i < cols.sz(); i++) {
- assert( connected.equiv(0,i));
- }
-#endif
-}
-
-bool
-Spacing_problem::check_constraints(Vector v) const
-{
- int dim=v.dim();
- // mtor << "checking solution " << v << '\n';
- for (int i=0; i < dim; i++) {
-
- if (cols[i].fixed&& ABS(cols[i].fixpos - v(i)) > COLFUDGE) {
- return false;
- }
- if (!i)
- continue;
-
- Real mindist=cols[i-1].minright()
- +cols[i].minleft();
-
- // ugh... compares
- Real dif =v(i) - v(i-1)- mindist;
- bool b = (dif > - COLFUDGE);
-
-
-#if 1
- if (!b)
- return false;
-
-#else
- mtor << "dif= "<<dif<<" fudge= " << COLFUDGE<< " dif >fudge= "<<
- b << "\n";
-
- /* fucks up for unknown reasons */
- if (dif < -COLFUDGE)
- return false;
-#endif
-
- }
- return true;
-}
-
-bool
-Spacing_problem::check_feasible() const
-{
- Vector sol(try_initial_solution());
- return check_constraints(sol);
-}
-
-// generate a solution which obeys the min distances and fixed positions
-Vector
-Spacing_problem::try_initial_solution() const
-{
- int dim=cols.sz();
- Vector initsol(dim);
- for (int i=0; i < dim; i++) {
- if (cols[i].fixed) {
- initsol(i)=cols[i].fixpos;
- } else {
- Real mindist=cols[i-1].minright()
- +cols[i].minleft();
- assert(mindist >= 0.0);
- initsol(i)=initsol(i-1)+mindist;
-
- //nog niet
- //if (i>0)
- // assert(initsol(i) > initsol(i-1));
- }
- }
-
- return initsol;
-}
-Vector
-Spacing_problem::find_initial_solution() const
-{
- Vector v(try_initial_solution());
- assert(check_constraints(v));
- return v;
-}
-// generate the matrices
-void
-Spacing_problem::make_matrices(Matrix &quad, Vector &lin, Real &c) const
-{
- quad.fill(0);
- lin.fill(0);
- for (int j=0; j < ideals.sz(); j++){
- Idealspacing const*i=ideals[j];
- int l = col_id(i->left);
- int r = col_id(i->right);
-
- quad(r,r) += i->hooke;
- quad(r,l) -= i->hooke;
- quad(l,r) -= i->hooke;
- quad(l,l) += i->hooke;
-
- lin(r) -= i->space*i->hooke;
- lin(l) += i->space*i->hooke;
-
- c += sqr(i->space);
- }
-}
-
-// put the constraints into the LP problem
-void
-Spacing_problem::make_constraints(Mixed_qp& lp) const
-{
- int dim=cols.sz();
- for (int j=0; j < dim; j++) {
- Colinfo *c=&(cols[j]);
- if (c->fixed) {
- lp.add_fixed_var(j,c->fixpos);
- }
- if (j > 0){
- Vector c1(dim);
-
-
- c1(j)=1.0 ;
- c1(j-1)=-1.0 ;
- lp.add_inequality_cons(c1, cols[j-1].minright() +
- cols[j].minleft());
- }
- }
-}
-
-svec<Real>
-Spacing_problem::solve() const
-{
- print();
- OK();
- assert(check_feasible());
-
-
- /* optimalisatiefunctie */
- Mixed_qp lp(cols.sz());
- make_matrices(lp.quad,lp.lin, lp.const_term);
- make_constraints(lp);
- Vector start=find_initial_solution();
- Vector sol(lp.solve(start));
- if (!check_constraints(sol)) {
- WARN << "solution doesn't satisfy constraints.\n" ;
- }
-
-
- svec<Real> posns(sol);
- posns.add(lp.eval(sol));
- return posns;
-}
-
-/*
- add one column to the problem.
-*/
-void
-Spacing_problem::add_column(const PCol *col, bool fixed, Real fixpos)
-{
- Colinfo c;
- c.fixed=fixed;
- c.fixpos=fixpos;
- assert(col);
- c.col=col;
- cols.add(c);
-}
-
-void
-Spacing_problem::add_ideal(const Idealspacing *i)
-{
- const PCol *l =i->left;
- const PCol *r= i->right;
-
- if (!contains(l) || !contains(r)) {
- return;
- }
- ideals.add(i);
-}
-
-void
-Spacing_problem::print_ideal(const Idealspacing*id)const
-{
-#ifndef NPRINT
- int l = col_id(id->left);
- int r = col_id(id->right);
-
- mtor << "between " << l <<","<<r<<":" ;
-#endif
-}
-
-void
-Spacing_problem::print() const
-{
-#ifndef NPRINT
- for (int i=0; i < cols.sz(); i++) {
- mtor << "col " << i<<' ';
- cols[i].print();
- }
- for (int i=0; i < ideals.sz(); i++) {
- print_ideal(ideals[i]);
- }
-#endif
-
-}
-
-void
-Colinfo::print() const
-{
-#ifndef NPRINT
- mtor << "column { ";
- if (fixed)
- mtor << "fixed at " << fixpos<<", ";
- assert(col);
- mtor << "[" << minleft() << ", " << minright() << "]";
- mtor <<"}\n";
-#endif
-}
-
-Colinfo::Colinfo()
-{
- fixed=false;
- col=0;
-}
+++ /dev/null
-#ifndef PROBLEM_HH
-#define PROBLEM_HH
-
-#include "glob.hh"
-#include "plist.hh"
-#include "vray.hh"
-#include "pcol.hh"
-#include "matrix.hh"
-
-/// helper struct for #Spacing_problem#
-struct Colinfo {
- const PCol *col;
- bool fixed;
- Real fixpos;
- Colinfo();
- void print() const;
- Real minright()const { return col->width().max; }
- Real minleft()const { return -col->width().min; }
-};
-
-
-/// spacing for one line.
-class Spacing_problem {
- svec<const Idealspacing*> ideals;
- svec<Colinfo> cols;
-
- /// the index of #c# in #cols#
- int col_id(const PCol *c) const;
-
- /// generate an (nonoptimal) solution
- Vector find_initial_solution() const;
-
- /// check if problem is too tight
- bool check_feasible() const;
- /// does #this# contain the column #w#?
- bool contains(const PCol *w);
-
- /// make the energy function
- void make_matrices(Matrix &quad, Vector &lin,Real&) const;
-
- /// generate the LP constraints
- void make_constraints(Mixed_qp& lp) const;
-
-public:
- /// solve the spacing problem
- svec<Real> solve() const;
- /**
- return the column positions, and the energy (last element)
- */
- /// add a idealspacing to the problem.
- void add_ideal(const Idealspacing *i);
-
- /**
- One pair of columns can have no, one or more idealspacings,
- since they can be "summed" if the columns to which #i# refers are
- not in this problem, the spacing is ignored.
- */
-
-
- /// add a col to the problem
- void add_column(const PCol *, bool fixed=false, Real fixpos=0.0);
- /** columns have to be added left to right. The column contains
- info on it's minimum width.
- */
-
-
- bool check_constraints(Vector v) const;
-
- Vector try_initial_solution() const;
- void OK() const;
- void print() const;
- void print_ideal(const Idealspacing*)const;
-};
-
-
-/** the problem, given by the columns (which include constraints) and
- intercolumn spacing. The problem is:
-
- Generate a spacing which
- \begin{itemize}
- \item
- Satisfies spacing constraints (notes can't be printed through each other)
- \item
- Looks good, ie tries to conform to an ideal spacing as much as possible.
- \end{itemize}
- This is converted by regarding idealspacing as "springs" attached
- to columns. The equilibrium of one spring is the ideal
- distance. The columns have a size, this imposes "hard" constraints
- on the distances. This transforms the problem into a quadratic
- programming problem with linear constraints.
-
- The quality is given by the total potential energy in the
- springs. The lower the energy, the better the configuration.
-*/
-#endif
+++ /dev/null
-#include "linestaff.hh"
-#include "symbol.hh"
-#include "lookupsyms.hh"
-#include "dimen.hh"
-#include "paper.hh"
-#include "pscore.hh"
-
-Linestaff::Linestaff(int l, PScore *s)
- : PStaff(s)
-{
- nolines = l;
- stafsym = s->paper_->lookup_->linestaff(l);
-}
-
-Symbol
-Linestaff::get_stafsym(Real width)const
-{
- String w(print_dimen(width));
- return stafsym->eval(w);
-}
+++ /dev/null
-#include "pstaff.hh"
-
-struct Linestaff : PStaff {
-
- int nolines;
-
-/****************/
-
- Symbol get_stafsym(Real width)const;
- Linestaff(int, PScore*);
-};
+++ /dev/null
-#include "lookupsyms.hh"
-#include "debug.hh"
-#include "symtable.hh"
-#include "dimen.hh"
-#include "tex.hh"
-
-void
-Lookup::parse(Text_db&t)
-{
- symtables_->read(t) ;
-}
-
-Lookup::Lookup()
-{
- symtables_ = new Symtables;
-}
-
-Lookup::~Lookup()
-{
- delete symtables_;
-}
-
-Symbol
-Lookup::ball(int j)
-{
- if (j > 4)
- j = 4;
-
- Symtable * st = (*symtables_)("balls");
- return st->lookup(String(j));
-}
-
-Symbol
-Lookup::rest(int j)
-{
- return (*symtables_)("rests")->lookup(String(j));
-}
-
-
-Symbol
-Lookup::bar(String s)
-{
- return (*symtables_)("bars")->lookup(s);
-}
- Symbol
-Lookup::dots(int j)
-{
- if (j>3)
- error("max 3 dots");
- return (*symtables_)("dots")->lookup(j);
-}
-
-Symbol
-Lookup::flag(int j)
-{
- return (*symtables_)("flags")->lookup(j);
-}
-
-Symbol
-Lookup::streepjes(int i)
-{
- assert(i);
-
- int arg;
- String idx ;
- if (i<0) {
- idx = "botlines";
- arg = -i;
- }else {
- arg = i;
- idx = "toplines";
- }
- Symbol ret = (*symtables_)("streepjes")->lookup(idx);
-
- svec<String> a;
- a.add(arg);
- ret.tex = substitute_args(ret.tex, a);
-
- return ret;
-}
-
-/****************************************************************/
-// bare bones.
-
-struct Linestaf_symbol : Parametric_symbol {
- int lines;
- Linestaf_symbol(int n, Symtables*s): Parametric_symbol(s) { lines = n;}
- Symbol eval(svec<String>)const;
-};
-
-
-Symbol
-Linestaf_symbol::eval(svec<String> w)const
-{
- Real wid = w[0].fvalue();
-
- Symbol s;
- s.dim.x = Interval(0,wid);
- Real dy=(lines-1)*convert_dimen(5,"pt"); // TODO!
- s.dim.y = Interval(0,dy);
- svec<String> a;
- a.add(lines);
- a.add(w[0]);
- s.tex = (*symtables_)("param")->lookup("linestaf").tex;
- s.tex = substitute_args(s.tex, a);
- return s;
-}
-
-/****************************************************************/
-
-
-struct Meter_sym:Parametric_symbol {
-
- Meter_sym(Symtables*s) : Parametric_symbol(s){ }
- Symbol eval(svec<String> a) const{
- Symbol s;
- s.dim.x = Interval( convert_dimen(-5,"pt"),
- convert_dimen(5,"pt"));
- s.dim.y = Interval(0, convert_dimen(10,"pt") ); // todo
- String src = (*symtables_)("param")->lookup("meter").tex;
- s.tex = substitute_args(src,a);
- return s;
- }
-};
-/****************************************************************/
-
-struct Stem_sym:Parametric_symbol {
-
- Stem_sym(Symtables*s) : Parametric_symbol(s) { }
- Symbol eval(svec<String> a) const {
- Real y1 = a[0].fvalue();
- Real y2 = a[1].fvalue();
- assert(y1 <= y2);
- Symbol s;
- s.dim.x = Interval(0,0);
- s.dim.y = Interval(y1,y2);
-
- String src = (*symtables_)("param")->lookup("stem").tex;
- s.tex = substitute_args(src,a);
- return s;
- }
-};
-
-Parametric_symbol *
-Lookup::meter(String )
-{
- return new Meter_sym(symtables_);
-}
-
-Parametric_symbol *
-Lookup::linestaff(int n)
-{
- return new Linestaf_symbol(n,symtables_);
-}
-
-Parametric_symbol*
-Lookup::stem()
-{
- return new Stem_sym(symtables_);
-}
+++ /dev/null
-/*
- lilypond, (c) 1996 Han-Wen Nienhuys
-*/
-#ifndef LOOKUPSYMS_HH
-#define LOOKUPSYMS_HH
-
-#include "symbol.hh"
-
-struct Lookup {
- Symtables *symtables_;
-
- /****************/
-
- void parse (Text_db&t);
- Parametric_symbol *linestaff(int n);
- Parametric_symbol *meter(String);
- Parametric_symbol *stem();
- Symbol streepjes(int pos);
- /**
- pos == 3 : 3 lines above staff (extending below note)
-
- pos == -3: below staff
- */
-
- Symbol ball(int);
- Symbol flag(int);
- Symbol rest(int);
- Symbol bar(String);
- Symbol dots(int);
- Lookup();
- ~Lookup();
-};
-
-#endif
+++ /dev/null
-#include <iostream.h>
-#include <assert.h>
-#include "lgetopt.hh"
-#include "misc.hh"
-#include "string.hh"
-#include "main.hh"
-
-extern void parse_file(String s);
-
-long_option_init theopts[] = {
- 1, "output", 'o',
- 0, "warranty", 'w',
- 0,0,0
-};
-
-
-void notice()
-{
- cout <<
- "LilyPond, a music typesetter.\n"
- "Copyright (C) 1996 by\n"
- " Han-Wen Nienhuys <hanwen@stack.urc.tue.nl>\n"
- "\n"
- "\n"
- " This program is free software; you can redistribute it and/or\n"
- "modify it under the terms of the GNU General Public License version 2\n"
- "as published by the Free Software Foundation.\n"
- "\n"
- " This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
- "General Public License for more details.\n"
- "\n"
- " You should have received a copy (refer to the file COPYING) of the\n"
- "GNU General Public License along with this program; if not, write to\n"
- "the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,\n"
- "USA.\n";
-}
-
-int
-main (int argc, char **argv)
-{
- Getopt_long oparser(argc, argv,theopts);
- debug_init();
- cout << get_version();
-
- while (long_option_init * opt = oparser()) {
- switch ( opt->shortname){
- case 'o':
- set_default_output(oparser.optarg);
- break;
- case 'w':
- notice();
- exit(0);
- break;
- default:
- assert(false);
- break;
- }
- }
- char *arg = oparser.get_next_arg();
-
- if (!arg) arg = "";
- parse_file(arg);
-
- do_scores();
- exit (0);
-}
+++ /dev/null
-#ifndef MAIN_HH
-#define MAIN_HH
-#include "proto.hh"
-
-void debug_init();
-void do_scores();
-void add_score(Score * s);
-void set_default_output(String s);
-const char *get_version();
-
-#endif
+++ /dev/null
-#include "melodicstaff.hh"
-#include "stem.hh"
-#include "notehead.hh"
-#include "paper.hh"
-#include "molecule.hh"
-#include "linestaff.hh"
-#include "rhythmstaff.hh"
-#include "sccol.hh"
-
-const int NO_LINES=5;
-const int BOTTOM_POSITION=2; // e is on bottom line of 5-staff...
-
-void
-Melodic_staff::set_output(PScore*ps)
-{
- theline = new Linestaff(NO_LINES,ps);
- Simple_staff::set_output(ps);
-}
-
-void
-Melodic_column::typeset_command(Command *com, int breakst)
-{
- Molecule*m=create_command_mol(com);
- Item *i =new Item;
- i->output = m;
- typeset_item(i, breakst);
-}
-
-void
-Melodic_column::typeset_req(Request *rq)
-{
- Item *i ;
- if (rq->note()) {
- Notehead *n =new Notehead((NO_LINES-1)*2);
- n->balltype = rq->rhythmic()->balltype;
- n->dots = rq->rhythmic()->dots;
- n->position = rq->note()->height() - BOTTOM_POSITION;
- i = n;
- } else if (rq->rest()) {
- i =new Item;
- Molecule*m=create_req_mol(rq);
- i->output=m;
- }
- typeset_item(i);
-}
-
-
-void
-Melodic_column::typeset_stem(Stem_req*rq)
-{
- Stem * s = new Stem(NO_LINES);
- int n = the_note->note()->height()-BOTTOM_POSITION;
- s->minnote =s->maxnote=n;
- s->flag = rq->stem_number;
- typeset_item(s);
-}
-
-/*
- creation
- */
-Staff *
-get_new_melodicstaff()
-{
- return new Melodic_staff;
-}
-
-
-Staff_column*
-Melodic_staff::create_col(Score_column*s)
-{
- return new Melodic_column(s,this);
-}
-
-Melodic_staff*
-Melodic_staff::clone()const
-{
- return new Melodic_staff(*this);
-}
+++ /dev/null
-/*
- rhythmstaf.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef MELODICSTAFF_HH
-#define MELODICSTAFF_HH
-
-#include "simplestaff.hh"
-
-/// five line staff, no multiple voices
-struct Melodic_staff : public Simple_staff
-{
- Staff_column * create_col(Score_column*);
- virtual void set_output(PScore *);
- virtual Melodic_staff*clone()const;
-};
-
-struct Melodic_column : public Simple_column {
- virtual void typeset_req(Request *rq);
- virtual void typeset_stem(Stem_req *rq);
- virtual void typeset_command(Command *, int brs);
- // virtual void typeset_item(Item*, int=1);
- Melodic_column(Score_column*s,Simple_staff*rs) :
- Simple_column(s,rs) { }
-// virtual Melodic_column*clone()const;
-};
-
-#endif // MELODICSTAFF_HH
-
-
+++ /dev/null
-#include "misc.hh"
-#include "glob.hh"
-
-#include <math.h>
-
-int intlog2(int d) {
- int i=0;
- while (!(d&1)) {
- d/= 2; i++;
- }
- assert(!(d/2));
- return i;
-}
-
+++ /dev/null
-#ifndef MISC_HH
-#define MISC_HH
-
-
-
-
-#endif
+++ /dev/null
-#include "glob.hh"
-#include "dimen.hh"
-#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
-{
- Box b( sym.dim);
- b.translate(off);
- return b;
-}
-
-Atom::Atom(Symbol s)
-{
- sym=s;
-}
-
-
-String
-Atom::TeXstring() const
-{
- // whugh.. Hard coded...
- String s("\\placebox{%}{%}{%}");
- svec<String> a;
- a.add(print_dimen(off.y));
- a.add(print_dimen(off.x));
- a.add(sym.tex);
- return substitute_args(s, a);
-}
-
-
-String
-Molecule::TeXstring() const
-{
- String s;
- for(PCursor<Atom*> c(ats); c.ok(); c++)
- s+=c->TeXstring();
- return s;
-}
-
-Box
-Molecule::extent() const
-{
- Box b;
- for(PCursor<Atom*> c(ats); c.ok(); c++)
- b.unite(c->extent());
- return b;
-}
-
-void
-Molecule::translate(Offset o)
-{
- for (PCursor<Atom*> c(ats); c.ok(); c++)
- c->translate(o);
-}
-
-void
-Molecule::add(const Molecule &m)
-{
- for (PCursor<Atom*> c(m.ats); c.ok(); c++) {
- add(**c);
- }
-}
-
-void
-Molecule::add_right(const Molecule &m)
-{
- Real xof=extent().x.max - m.extent().x.min;
- Molecule toadd(m);
- toadd.translate(Offset(xof, 0.0));
- add(toadd);
-}
-
-void
-Molecule::add_left(const Molecule &m)
-{
- Real xof=extent().x.min - m.extent().x.max;
- Molecule toadd(m);
- toadd.translate(Offset(xof, 0.0));
- add(toadd);
-}
-
-
-void
-Molecule::add_top(const Molecule &m)
-{
- Real yof=extent().y.max - m.extent().y.min;
- Molecule toadd(m);
- toadd.translate(Offset(0,yof));
- add(toadd);
-}
-
-void
-Molecule::add_bot(const Molecule &m)
-{
- Real yof=extent().y.min- m.extent().y.max;
- Molecule toadd(m);
- toadd.translate(Offset(0,yof));
- add(toadd);
-}
-
-void
-Molecule::operator = (const Molecule&)
-{
- assert(false);
-}
-
-Molecule::Molecule(const Molecule&s)
-{
- add(s);
-}
-
-void
-Molecule::print() const
-{
- for (PCursor<Atom*> c(ats); c.ok(); c++)
- c->print();
-}
+++ /dev/null
-#ifndef MOLECULE_HH
-#define MOLECULE_HH
-
-#include "plist.hh"
-#include "boxes.hh"
-#include "item.hh"
-#include "symbol.hh"
-/// a symbol which can be translated, and freely copied
-struct Atom {
- Offset off;
- Symbol sym;
-
- void translate(Offset o) {
- off += o;
- }
-
- /// how big is #this#?
- Box extent() const;
- Atom(Symbol s);
-
- void print() const;
-
- String TeXstring() const;
-};
-
-/// a group of #Atom#s
-struct Molecule {
- PointerList<Atom*> ats;
-
- Molecule() { }
- Molecule(Atom a) { add(a) ; }
-
- 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(Molecule const &m);
- void translate(Offset);
- void add(Atom a) { ats.bottom().add(new Atom(a)); }
- /// how big is #this#?
- Box extent() const;
-
- String TeXstring() const;
-
- Molecule(const Molecule&s);
- void print() const;
-private:
- void operator=(const Molecule&);
-};
-/** a group of individually translated symbols. You can add molecules
- to the top, to the right, etc. */
-#endif
+++ /dev/null
-#include <ctype.h>
-#include "string.hh"
-#include "real.hh"
-#include "debug.hh"
-#include "request.hh"
-#include "voice.hh"
-#include "notename.hh"
-
-int default_duration = 4;
-
-void
-parse_duration(const char *a, int &j, int &intdur, int &dots)
-{
- String durstr;
- while (isdigit(a[j]))
- {
- durstr += a[j++];
- }
-
- dots=0;
-
- while (a[j] == '.')
- {
- j++;
- dots++;
- }
- intdur = (durstr.len()) ?
- durstr.value():default_duration;
-
-
- mtor << "dur " << intdur << "dots " << dots<<eol;
-}
-
-
-
-void
-parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
- int & large, int & small)
-{
- // octave
- oct =0;
-
- while (1)
- {
- if (a[j] == '\'')
- oct ++;
- else if (a[j] == '`')
- oct --;
- else
- break;
- j++;
-
- }
-
- mtor << "oct " << oct;
-
- // accidental
- overide_acc = false;
-
- if (a[j] == '!')
- {
- overide_acc = true;
- j++;
- }
-
-
- // notename.
- String nm;
- while (isalpha(a[j]))
- {
- nm += a[j++];
- }
- if (isupper(nm[0]))
- {
- oct--;
- nm.lower();
- }
-
-
- lookup_notename(large,small,nm);
- mtor << "override: " << overide_acc;
- mtor << "pitch "<< large <<", "<<small<<"\n";
-}
-
-
-Voice_element *
-get_note_element(String pitch, String durstr)
-{
- Voice_element*v = new Voice_element;
- int i=0;
-
- int dur, dots;
- parse_duration(durstr, i, dur, dots);
- i=0;
-
- Note_req * rq = new Note_req( v);
-
- if (dur >= 2) {
- Stem_req * st = new Stem_req(v, dur);
- v->add(st);
- }
-
- int oct, pit, acc;
- bool forceacc;
- parse_pitch(pitch, i, oct, forceacc, pit, acc);
- char nm = pit + 'c';
- if (nm > 'g')
- nm += 'a' - 'h';
- rq->name =nm;
-
- rq->octave = oct;
- rq->accidental = acc;
- rq->forceacc = forceacc;
- rq->balltype = dur;
- rq->dots = dots;
-
- rq->print();
-
- v->add(rq);
-
- return v;
-}
-
-Voice_element *
-get_rest_element(String, String durstr)
-{
- Voice_element*v = new Voice_element;
- int i=0;
-
- int dur, dots;
- parse_duration(durstr, i, dur, dots);
- i=0;
-
- Rest_req * rq = new Rest_req(v);
-
- rq->balltype = dur;
- rq->dots = dots;
- rq->print();
- v->add(rq);
- return v;
-}
+++ /dev/null
-#include "notehead.hh"
-#include "dimen.hh"
-#include "debug.hh"
-#include "pstaff.hh"
-#include "pscore.hh"
-#include "paper.hh"
-#include "lookupsyms.hh"
-#include "molecule.hh"
-
-
-Notehead::Notehead(int ss)
-{
- staff_size=ss;
- position = 0;
- balltype = 0;
- dots = 0;
-}
-
-void
-Notehead::print()const
-{
- mtor << "Head "<<balltype<<", position = "<< position << "dots " << dots;
- Item::print();
-}
-
-void
-Notehead::preprocess()
-{
- brew_molecole();
-}
-
-void
-Notehead::brew_molecole()
-{
- assert(pstaff_);
- assert(!output);
-
- Paperdef *p = pstaff_->pscore_->paper_;
-
- Real dy = p->interline()/2;
- Symbol s = p->lookup_->ball(balltype);
-
- output = new Molecule(Atom(s));
- if (dots) {
- Symbol d = p->lookup_->dots(dots);
- Molecule dm;
- dm.add(Atom(d));
- if (!(position %2))
- dm.translate(Offset(0,dy));
- output->add_right(dm);
- }
- bool streepjes = (position<-1)||(position > staff_size+1);
- if (streepjes) {
- int dir = sgn(position);
- int s =(position<-1) ? -((-position)/2): (position-staff_size)/2;
- Symbol str = p->lookup_->streepjes(s);
- Molecule sm;
- sm.add(Atom(str));
- if (position % 2)
- sm.translate(Offset(0,-dy* dir));
- output->add(sm);
- }
-
-
- output->translate(Offset(0,dy*position));
-}
-
+++ /dev/null
-/*
- notehead.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef NOTEHEAD_HH
-#define NOTEHEAD_HH
-#include "item.hh"
-
-/// ball at the end of the stem
-struct Notehead : public Item
-{
- int position;
- int staff_size;
- int dots;
- int balltype;
-
- /****************/
- void preprocess();
-
- Notehead(int staff_size);
- /**
- position of top line (5 linestaff: 8)
- */
- void print()const;
-private:
- void brew_molecole();
-};
-/**
- takes care of:
-
- * help lines
- * proper placing of dots
-
- */
-#endif // NOTEHEAD_HH
-
+++ /dev/null
-#include "glob.hh"
-#include "string.hh"
-
-
-/// change this along with lex file for other notenames.
-const char *notetab[] =
-{
-"ceses", "ces", "c", "cis", "cisis",
-"deses", "des", "d", "dis", "disis",
-"eses", "es", "e", "eis", "eisis",
-"feses", "fes", "f", "fis", "fisis",
-"geses", "ges", "g", "gis", "gisis",
-"ases", "as", "a", "ais", "aisis",
-"beses", "bes", "b", "bis", "bisis",
-0
-};
-
-void
-lookup_notename(int &large, int &small, String s)
-{
- int i;
- for (i =0; notetab[i]; i++)
- if (s == notetab[i])
- {
- large = i /5;
- small = i %5 - 2;
- return;
- }
- assert(false);
-}
+++ /dev/null
-
-void lookup_notename(int &large, int &small, String s);
+++ /dev/null
-#include <math.h>
-
-#include "paper.hh"
-#include "debug.hh"
-#include "lookupsyms.hh"
-#include "dimen.hh"
-#include "textdb.hh"
-
-double log2(double x) {
- return log(x) /log(2.0);
-}
-
-
-// golden ratio
-const Real PHI = (1+sqrt(5))/2;
-
-// see Roelofs, p. 57
-Real
-Paperdef::duration_to_dist(Real d)
-{
- return whole_width * pow(geometric_, log2(d));
-}
-
-Paperdef::Paperdef()
-{
- lookup_ = new Lookup();
- parse();
- linewidth = convert_dimen(15,"cm"); // in cm for now
- whole_width= 6*note_width();
- geometric_ = PHI;
-}
-
-void
-Paperdef::parse()
-{
- Text_db symini("symbol.ini");
-
-
- while (!symini.eof()) {
-
- Text_record r( symini++);
-
- if (r[0] == "symboltables")
- lookup_->parse(symini);
- }
-}
-
-Paperdef::~Paperdef()
-{
- delete lookup_;
-}
-
-Real
-Paperdef::interline() const
-{
- return lookup_->ball(4).dim.y.length();
-}
-Real
-Paperdef::note_width()const
-{
- return lookup_->ball(4).dim.x.length( );
-}
-Real
-Paperdef::standard_height() const
-{
- return convert_dimen(20,"pt");
-}
-
-void
-Paperdef::print() const
-{
-#ifndef NPRINT
- mtor << "Paper {width: " << print_dimen(linewidth);
- mtor << "whole: " << print_dimen(whole_width);
- mtor << "out: " <<outfile;
- mtor << "}\n";
-#endif
-}
+++ /dev/null
-#include "proto.hh"
-#include "real.hh"
-#include "string.hh"
-
-struct Paperdef {
- Lookup *lookup_;
- String outfile;
- Real linewidth;
- /// how much space does a whole note take (ideally?)
- Real whole_width;
-
- // ideal = geometric_ ^ log2(duration)
- Real geometric_;
-
- /****************/
- void parse();
- Paperdef();
- ~Paperdef();
- Real interline()const;
- Real standard_height()const;
- Real note_width() const;
- void print() const;
- Real duration_to_dist(Real);
-};
-
+++ /dev/null
-
-#include "proto.hh"
-
-Staff * get_new_rhythmstaff();
-Voice_element * get_note_element(String,String);
-Voice_element* get_rest_element(String,String);
-Command * get_bar_command(Real);
-Staff * get_new_melodicstaff();
-Command* get_meterchange_command( int,int);
-Command* get_meter_command( Real,int,int);
-Command* get_skip_command( int,Real);
-
+++ /dev/null
-%{ // -*-Fundamental-*-
-#include <iostream.h>
-
-#include "lexer.hh"
-#include "paper.hh"
-#include "staff.hh"
-#include "score.hh"
-#include "main.hh"
-#include "keyword.hh"
-#include "scommands.hh"
-#include "debug.hh"
-#include "parseconstruct.hh"
-#include "dimen.hh"
-#include "identifier.hh"
-
-#ifndef NDEBUG
-#define YYDEBUG 1
-#endif
-
-%}
-
-
-%union {
- Real real;
- Command *command;
- Identifier *id;
- Score_commands *scommands;
- Voice *voice;
- Voice_element *el;
- Staff *staff;
- String *string;
- Score *score;
- const char *consstr;
- Paperdef *paper;
- int i;
-}
-
-%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
-%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
-%token MELODICSTAFF GEOMETRIC START
-
-%type <consstr> unit
-%token <id> IDENTIFIER
-%token <string> NEWIDENTIFIER
-%token <string> PITCH DURATION RESTNAME
-%token <real> REAL
-%token <string> STRING
-%type <id> declaration
-%type <paper> paper_block paper_body
-%type <real> dim
-%type <voice> voice_block voice_body voice_elts voice_elts_dollar
-%type <el> voice_elt
-%type <command> score_command
-%type <score> score_block score_body
-%type <staff> staff_block rhythmstaff_block rhythmstaff_body
-%type <staff> melodicstaff_block melodicstaff_body staffdecl
-%type <i> int
-%type <scommands> score_commands_block score_commands_body
-
-%%
-
-mudela: /* empty */
- | mudela score_block {
- add_score($2);
- }
- | mudela add_declaration { }
- ;
-
-add_declaration: declaration {
- add_identifier($1);
- }
- ;
-
-declaration:
- NEWIDENTIFIER '=' staff_block {
- $$ = new Staff_id(*$1, $3);
- delete $1; // this sux
- }
- | NEWIDENTIFIER '=' voice_block {
- $$ = new Voice_id(*$1, $3);
- delete $1;
- }
- ;
-
-
-score_block: SCORE '{' score_body '}' { $$ = $3; }
- ;
-
-score_body: { $$ = new Score; }
- | score_body staff_block { $$->add($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_block:
- PAPER '{' paper_body '}' { $$ = $3; }
- ;
-
-paper_body:
- /* empty */ { $$ = new Paperdef; }
- | paper_body WIDTH dim { $$->linewidth = $3;}
- | paper_body OUTPUT STRING { $$->outfile = *$3;
- delete $3;
- }
- | paper_body UNITSPACE dim { $$->whole_width = $3; }
- | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
- ;
-
-dim:
- REAL unit { $$ = convert_dimen($1,$2); }
- ;
-
-
-unit: CM { $$ = "cm"; }
- |IN { $$ = "in"; }
- |MM { $$ = "mm"; }
- |PT { $$ = "pt"; }
- ;
-
-/*
- staff
-*/
-staff_block:
- staffdecl
- | rhythmstaff_block
- | melodicstaff_block
- ;
-
-staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff()->clone(); }
- ;
-
-rhythmstaff_block:
- RHYTHMSTAFF '{' rhythmstaff_body '}' { $$ = $3; }
- ;
-
-rhythmstaff_body:
- /* empty */ { $$ = get_new_rhythmstaff(); }
- | rhythmstaff_body voice_block { $$->add_voice($2); }
- ;
-
-melodicstaff_block:
- MELODICSTAFF '{' melodicstaff_body '}' { $$ = $3; }
- ;
-
-melodicstaff_body:
- /* empty */ { $$ = get_new_melodicstaff(); }
- | melodicstaff_body voice_block { $$->add_voice($2); }
- ;
-
-/*
- voice
-*/
-voice_block:
- VOICE '{' voice_body '}' { $$ = $3; }
- ;
-
-
-voice_body:
- IDENTIFIER { $$ = new Voice(*$1->voice()); }
- | voice_elts_dollar { $$ = $1; }
- | voice_body START REAL { $$->start = $3; }
- ;
-
-
-
-
-voice_elts_dollar:
- '$' voice_elts '$' { $$ = $2; }
- ;
-
-voice_elts:
- /* empty */ {
- $$ = new Voice;
- }
- | voice_elts voice_elt {
- $$->add($2);
- }
- ;
-
-voice_elt:
- PITCH DURATION { $$ = get_note_element(*$1, *$2);
-
- }
- | RESTNAME DURATION { $$ = get_rest_element(*$1, *$2);
-
- }
- ;
-
-score_command:
- SKIP int ':' REAL {
- $$ = get_skip_command($2, $4);
- }
- | METER int int {
- $$ = get_meterchange_command($2, $3);
- }
-/* | PARTIALMEASURE REAL {
- $$ = get_partial_command($2);
- }*/
- ;
-
-
-int:
- REAL {
- $$ = int($1);
- if (ABS($1-Real(int($$))) > 1e-8)
- yyerror("expecting integer number");
-
- }
- ;
-
-%%
-
-void
-parse_file(String s)
-{
- *mlog << "Parsing ... ";
-#ifdef YYDEBUG
- yydebug = !monitor.silence("Parser");
-#endif
- new_input(s);
- yyparse();
- delete_identifiers();
- *mlog << "\n";
-}
+++ /dev/null
-#include "pcol.hh"
-#include "pstaff.hh"
-#include "debug.hh"
-
-void
-Idealspacing::print() const
-{
-#ifndef NPRINT
- mtor << "idealspacing {" ;
- mtor << "distance "<<space<< " strength " << hooke << "}\n";
-#endif
-}
-
-Idealspacing::Idealspacing(const PCol * l,const PCol * r)
-{
- space = 0.0;
- hooke = 0.0;
- left = l;
- right = r;
-}
-
-void
-Idealspacing::OK() const
-{
-#ifndef NDEBUG
- assert(hooke >= 0 && left && right);
-#endif
-}
-
-/****************************************************************/
-
-Interval
-PCol::width() const
-{
- Interval w;
-
- for (PCursor<const Item *> ic(its); ic.ok(); ic++)
- w.unite(ic->width());
- if (w.empty())
- w.unite(Interval(0,0));
- return w;
-}
-
-void
-PCol::print() const
-{
- #ifndef NPRINT
- mtor << "PCol {";
- mtor << "# symbols: " << its.size() ;
- if (breakable()){
- mtor << "pre,post: ";
- prebreak->print();
- postbreak->print();
- }
- mtor << "extent: " << width().min << ", " << width().max << "\n";
- mtor << "}\n";
- #endif
-}
-
-int
-PCol::compare(const PCol &, const PCol &)
-{
- assert(false);
- return 0 ;
-}
-
-void
-PCol::OK () const
-{
- if (prebreak || postbreak ) {
- assert(prebreak&&postbreak);
- assert(prebreak->daddy == this);
- assert(postbreak->daddy == this);
- }
-
-}
-
-void
-PCol::set_breakable()
-{
- if (breakable())
- return;
-
- prebreak = new PCol(this);
- postbreak = new PCol(this);
- used = true;
-}
-
-bool
-PCol::breakable() const
-{
- return prebreak||postbreak;
-}
-
-PCol::PCol(PCol *parent) {
- daddy = parent;
- prebreak=0;
- postbreak=0;
- line=0;
- used = false;
-}
-
-PCol::~PCol()
-{
-
- delete prebreak;
-
- delete postbreak;
-}
-
-void
-PCol::add(const Item *i)
-{
- its.bottom().add(i);
- used = true;
-}
-
+++ /dev/null
-#ifndef COLS_HH
-#define COLS_HH
-
-#include "glob.hh"
-#include "boxes.hh"
-#include "plist.hh"
-#include "item.hh"
-
-/// stuff grouped vertically.
-struct PCol {
- List<const Item*> its;
- List<const Spanner*> stoppers, starters;
-
- /// Can this be broken? true eg. for bars.
- bool breakable()const;
-
- /// does this column have items, does it have spacings attached?
- bool used;
-
- /// prebreak is put before end of line.
- PCol *prebreak;
- /**
- if broken here, then (*this) column is discarded, and prebreak
- is put at end of line, owned by Col
- */
-
- /// postbreak at beginning of the new line
- PCol *postbreak;
- /** \See{prebreak}
- */
- PCol *daddy;
- /*
- if this column is pre or postbreak, then this field points to the parent.
- */
- /// if lines are broken then this column is in #line#
- const Line_of_score *line;
-
- /// if lines are broken then this column x-coord #hpos#
- Real hpos;
-
-
- /****************************************************************/
-
- void add(const Item*i);
-
- Interval width() const;
- ~PCol();
- PCol(PCol * parent);
-
- /// which col comes first?
- static int compare(const PCol &c1, const PCol &c2);
- /**
- signed compare on columns.
-
- return < 0 if c1 < c2.
- */
-
- void OK() const;
- void set_breakable();
- void print()const;
-};
-/**
- This is a class to address items vertically. It contains the data for:
- \begin{itemize}
- \item
- unbroken score
- \item
- broken score
- \item
- the linespacing problem
- \end{itemize}
- */
-
-#include "compare.hh"
-instantiate_compare(const PCol &, PCol::compare);
-
-
-/// ideal spacing between two columns
-struct Idealspacing {
-
- /// the ideal distance
- Real space;
-
- /// Hooke's constant: how strong are the "springs" attached to columns
- Real hooke;
-
- /// the two columns
- const PCol *left, *right;
-
- void print()const;
- void OK() const ;
- Idealspacing(const PCol *left,const PCol *right);
-};
-
-#endif
+++ /dev/null
-/*
- proto.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef PROTO_HH
-#define PROTO_HH
-#include "real.hh"
-
-class Line_of_score;
-class Line_of_staff;
-class PCol;
-class PStaff;
-class Staff;
-class Staff_column;
-class Score;
-class Score_column;
-class Voice;
-class Voice_element;
-class Voicegroup;
-class Request;
-class Command;
-class Request;
-class Stem_req;
-class Span_req;
-class Slur_req;
-class Decresc_req;
-class Cresc_req;
-class Bracket_req;
-class Script_req;
-class Rest_req;
-class Note_req;
-class Lyric_req;
-class Chord;
-class Absdynamic_req;
-struct Offset;
-struct Interval;
-struct Box;
-struct PCol;
-struct Idealspacing;
-struct Spanner;
-struct Item;
-struct Line_of_staff;
-struct Colinfo;
-struct Linestaff;
-struct Atom;
-struct Molecule;
-struct PScore;
-struct Request;
-struct Note_req;
-struct Lyric_req;
-struct Script_req;
-struct Rest_req;
-struct Rhythmic_req;
-struct Chord;
-struct Stem_req;
-struct Span_req;
-struct Beam_req;
-struct Bracket_req;
-struct Slur_req;
-struct Dynamic;
-struct Cresc_req;
-struct Decresc_req;
-struct Absdynamic_req;
-struct Score_column;
-struct Score;
-struct Staff_column;
-struct Staff;
-struct Command;
-struct Symbol;
-struct Output;
-struct Text_gob;
-struct Voice;
-struct Voicegroup;
-struct Voice_element;
-struct String;
-struct Tex_stream;
-struct Identifier;
-struct Keyword;
-class Mixed_qp;
-class Paperdef;
-class Score_commands;
-class Parametric_symbol;
-struct Lookup;
-struct Symtables;
-struct Symtable;
-
-#endif // PROTO_HH
-
+++ /dev/null
-// utility functions for PScore
-#include "debug.hh"
-#include "paper.hh"
-#include "molecule.hh"
-#include "dimen.hh"
-#include "line.hh"
-#include "pscore.hh"
-#include "tstream.hh"
-
-void
-PScore::clean_cols()
-{
- for (PCursor<PCol *> c(cols); c.ok(); )
- if (!c->used) {
- c.del();
- } else
- c++;
-}
-
-
-void
-PScore::add(PStaff *s)
-{
- staffs.bottom().add(s);
-}
-
-void
-PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
-{
- assert(c && i && s);
-// 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);
- i->preprocess();
-}
-
-void
-PScore::add_line(svec<const PCol *> curline, svec<Real> config)
-{
- Line_of_score *p = new Line_of_score(curline,this);
- lines.bottom().add(p);
- for (int i=0; i < curline.sz(); i++){
- PCol *c=(PCol *)curline[i]; // so, this isn't really const.
- c->hpos= config[i];
- }
-}
-
-Idealspacing*
-PScore::get_spacing(PCol*l, PCol*r)
-{
- assert(l!=r);
- for (PCursor<Idealspacing*> ic (suz); ic.ok(); ic++) {
- if (ic->left == l && ic->right == r){
- return ic;
- }
- }
-
- Idealspacing*ip =new Idealspacing(l,r);
- suz.bottom().add(ip);
-
- return ip;
-}
-
-svec<const PCol *>
-PScore::find_breaks() const
-{
- svec<const PCol *> retval;
- for (PCursor<PCol *> c(cols); c.ok(); c++)
- if (c->breakable())
- retval.add(c);
-
- return retval;
-}
-
-void
-PScore::add(PCol *p)
-{
- cols.bottom().add(p);
-}
-
-PScore::PScore( Paperdef*p)
-{
- paper_ = p;
-}
-
-void
-PScore::output(Tex_stream &ts)
-{
- int l=1;
-
- for (PCursor<Line_of_score*> lic(lines); lic.ok(); lic++) {
- ts << "% line of score no. " << l++ <<"\n";
- ts << lic->TeXstring();
- if ((lic+1).ok())
- ts << "\\interscoreline\n";
- }
-}
-
-svec<Item*>
-PScore::select_items(PStaff*ps , PCol*pc)
-{
- svec<Item*> ret;
- assert(ps && pc);
- for (PCursor<const Item*> ic(pc->its); ic.ok(); ic++){
- if (ic->pstaff_ == ps)
- ret.add((Item*)(const Item*)ic);
- }
- return ret;
-}
-
-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 { paper ";
- paper_->print();
- mtor << "\ncolumns: ";
- for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
- cc->print();
-
- mtor << "\nideals: ";
- for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
- ic->print();
- mtor << "}\n";
-#endif
-}
-
-void
-PScore::preprocess()
-{
-#if 0
- for (PCursor<Item*> ic(its); ic.ok(); ic++){
- ic->preprocess();
- }
-#endif
-}
-
-void
-PScore::postprocess()
-{
- for (PCursor<Item*> ic(its); ic.ok(); ic++){
- ic->postprocess();
- }
-}
+++ /dev/null
-// the breaking problem for a score.
-
-#ifndef PSCORE_HH
-#define PSCORE_HH
-
-
-#include "vray.hh"
-#include "pcol.hh"
-#include "pstaff.hh"
-
-/// all stuff which goes onto paper
-struct PScore {
- Paperdef *paper_; // indirection.
-
- /// the columns, ordered left to right
- PointerList<PCol *> cols;
-
- /// the idealspacings, no particular order
- PointerList<Idealspacing*> suz;
-
- /// the staffs ordered top to bottom
- PointerList<PStaff*> staffs;
-
- /// all symbols in score. No particular order.
- PointerList<Item*> its;
-
- /// if broken, the different lines
- PointerList<Line_of_score*> lines;
-
- /// crescs etc; no particular order
- PointerList<Spanner *> spanners;
-
- /****************************************************************/
-
- svec<Item*> select_items(PStaff*, PCol*);
-
- /// before calc_breaking
- void preprocess();
-
- void calc_breaking();
- /**
- calculate where the lines are to be broken.
-
- POST
-
- lines contain the broken lines.
- */
-
- /// after calc_breaking
- void postprocess();
-
- /// search all pcols which are breakable.
- svec<const PCol *> find_breaks() const;
-
- /// add a line to the broken stuff. Positions given in #config#
- void add_line(svec<const PCol *> curline, svec<Real> config);
-
- /// helper: solve for the columns in #curline#.
- svec<Real> solve_line(svec<const PCol *> curline) const;
-
- void add(PStaff *);
- /// add item
- void typeset_item(Item *, PCol *,PStaff*,int=1);
- /// add to bottom of pcols
- void add(PCol*);
- /**
-
- */
- void output(Tex_stream &ts);
-
- Idealspacing* get_spacing(PCol *, PCol *);
- /*
- get the spacing between c1 and c2, create one if necessary.
- */
-
-
- PCursor<PCol *> find_col(PCol *);
- void clean_cols();
- void problem_OK()const ;
- void OK()const ;
- PScore(Paperdef*);
- void print() const;
-};
-/** notes, signs, symbols in a score can be grouped in two ways:
- horizontally (staffwise), and vertically (columns). #PScore#
- contains the items, the columns and the staffs.
- */
-#endif
+++ /dev/null
-#include "pstaff.hh"
-
-PStaff::PStaff(PScore*ps)
-{
- pscore_=ps;
- stafsym = 0;
-}
-
-void
-PStaff::add(Item *i )
-{
- its.bottom().add(i);
- i->pstaff_ = this;
-}
+++ /dev/null
-#ifndef PSTAFF_HH
-#define PSTAFF_HH
-
-#include "plist.hh"
-#include "item.hh"
-#include "symbol.hh"
-
-/// items grouped vertically.
-struct PStaff {
- Parametric_symbol *stafsym;
- PScore * pscore_;
-
- virtual Symbol get_stafsym(Real width)const=0; // maybe overkill
-
- List<const Spanner*> spans;
- List<Item*> its;
-
- void add(Item*i);
- PStaff(PScore*);
- virtual ~PStaff() {}
-};
-
-#endif
+++ /dev/null
-#include "debug.hh"
-#include "const.hh"
-#include "qlp.hh"
-#include "choleski.hh"
-
-void
-Mixed_qp::add_equality_cons(Vector , double )
-{
- assert(false);
-}
-
-void
-Mixed_qp::add_fixed_var(int i, Real r)
-{
- eq_cons.add(i);
- eq_consrhs.add(r);
-}
-
-void
-Ineq_constrained_qp::add_inequality_cons(Vector c, double r)
-{
- cons.add(c);
- consrhs.add(r);
-}
-
-Ineq_constrained_qp::Ineq_constrained_qp(int novars):
- quad(novars),
- lin(novars)
-{
-}
-
-void
-Ineq_constrained_qp::OK() const
-{
-#ifndef NDEBUG
- assert(cons.sz() == consrhs.sz());
- Matrix Qdif= quad - quad.transposed();
- assert(Qdif.norm()/quad.norm() < EPS);
-#endif
-}
-
-
-Real
-Ineq_constrained_qp::eval (Vector v)
-{
- return v * quad * v + lin * v + const_term;
-}
-/*
- eliminate appropriate variables, until we have a Ineq_constrained_qp
- then solve that.
-
- PRE
- cons should be ascending
- */
-Vector
-Mixed_qp::solve(Vector start) const
-{
- print();
- Ineq_constrained_qp pure(*this);
-
- for (int i= eq_cons.sz()-1; i>=0; i--) {
- pure.eliminate_var(eq_cons[i], eq_consrhs[i]);
- start.del(eq_cons[i]);
- }
- Vector sol = pure.solve(start);
- for (int i= 0; i < eq_cons.sz(); i++) {
- sol.insert( eq_consrhs[i],eq_cons[i]);
- }
- return sol;
-}
-
-/*
- assume x(idx) == value, and adjust constraints, lin and quad accordingly
- */
-void
-Ineq_constrained_qp::eliminate_var(int idx, Real value)
-{
- Vector row(quad.row(idx));
- row*= value;
-
- quad.delete_row(idx);
-
- quad.delete_column(idx);
-
- lin.del(idx);
- row.del(idx);
- lin +=row ;
-
- for (int i=0; i < cons.sz(); i++) {
- consrhs[i] -= cons[i](idx) *value;
- cons[i].del(idx);
- }
-}
-
-
-
-
-Mixed_qp::Mixed_qp(int n)
- : Ineq_constrained_qp(n)
-{
-}
-
-void
-Mixed_qp::OK() const
-{
-#ifndef NDEBUG
- Ineq_constrained_qp::OK();
- assert(eq_consrhs.sz() == eq_cons.sz());
-#endif
-}
-void
-Ineq_constrained_qp::print() const
-{
-#ifndef NPRINT
- mtor << "Quad " << quad;
- mtor << "lin " << lin <<"\n";
- for (int i=0; i < cons.sz(); i++) {
- mtor << "constraint["<<i<<"]: " << cons[i] << " >= " << consrhs[i];
- mtor << "\n";
- }
-#endif
-}
-void
-Mixed_qp::print() const
-{
-#ifndef NPRINT
- Ineq_constrained_qp::print();
- for (int i=0; i < eq_cons.sz(); i++) {
- mtor << "eq cons "<<i<<": x["<<eq_cons[i]<<"] == " << eq_consrhs[i]<<"\n";
- }
-#endif
-}
-
-
-void
-Ineq_constrained_qp::assert_solution(Vector sol) const
-{
- svec<int> binding;
- for (int i=0; i < cons.sz(); i++) {
- Real R=cons[i] * sol- consrhs[i];
- assert(R> -EPS);
- if (R < EPS)
- binding.add(i);
- }
- // KKT check...
- // todo
-}
+++ /dev/null
-#ifndef QLP_HH
-#define QLP_HH
-
-#include "matrix.hh"
-
-/// inequality constrained quadratic program
-class Ineq_constrained_qp {
- friend class Active_constraints;
-
- svec<Vector> cons;
- svec<Real> consrhs;
-public:
- Matrix quad;
- Vector lin;
- Real const_term;
-
- ///
- void assert_solution(Vector sol) const;
- /**
- use a KKT method to assert optimality of sol
- */
- /// solve the problem using a projected gradient method
- Vector solve(Vector start) const;
-
- int dim() const{
- return lin.dim();
- }
- /** return the number of variables in the problem */
- ///
- void add_inequality_cons(Vector c, double r);
- /**
- add a constraint
-
-
- c*vars >= r
-
- PRE
- c.dim() == dim();
-
- */
- ///
- Ineq_constrained_qp(int novars);
- /** set up matrices to go with the problem. */
-
- Real eval(Vector v);
- /**
- evaluate the quadratic function for input #v#
- */
-
- void eliminate_var(int idx, Real value);
- void OK()const;
- void print() const;
-
-};
-
-/// Quadratic programming with mixed linear constraints
-class Mixed_qp :public Ineq_constrained_qp {
- svec<int> eq_cons;
- svec<Real> eq_consrhs;
-public:
- Mixed_qp(int n);
- void OK() const;
- void print() const;
-
- Vector solve(Vector start) const;
- void add_fixed_var(int i , Real value);
-
- ///
- void add_equality_cons(Vector c, double r);
- /**
- add a constraint,
-
- c*vars == r
-
- PRE
- c.dim()==dim();
- */
-
-};
-/**
- problem definition of a quadratic optimisation problem with linear
- inequality and equality constraints
-
-
- x^T QUAD x /2 + b^T x
-*/
-
-
-#endif
+++ /dev/null
-#include "qlpsolve.hh"
-#include "const.hh"
-#include "debug.hh"
-#include "choleski.hh"
-
-const Real TOL=1e-2; // roughly 1/10 mm
-
-String
-Active_constraints::status() const
-{
- String s("Active|Inactive [");
- for (int i=0; i< active.sz(); i++) {
- s += String(active[i]) + " ";
- }
-
- s+="| ";
- for (int i=0; i< inactive.sz(); i++) {
- s += String(inactive[i]) + " ";
- }
- s+="]";
-
- return s;
-}
-
-void
-Active_constraints::OK() {
- H.OK();
- A.OK();
- assert(active.sz() +inactive.sz() == opt->cons.sz());
- assert(H.dim() == opt->dim());
- assert(active.sz() == A.rows());
- svec<int> allcons;
-
- for (int i=0; i < opt->cons.sz(); i++)
- allcons.add(0);
- for (int i=0; i < active.sz(); i++) {
- int j = active[i];
- allcons[j]++;
- }
- for (int i=0; i < inactive.sz(); i++) {
- int j = inactive[i];
- allcons[j]++;
- }
- for (int i=0; i < allcons.sz(); i++)
- assert(allcons[i] == 1);
-}
-
-Vector
-Active_constraints::get_lagrange(Vector gradient)
-{
- Vector l(A*gradient);
-
- return l;
-}
-
-void
-Active_constraints::add(int k)
-{
- // add indices
- int cidx=inactive[k];
- active.add(cidx);
-
- inactive.swap(k,inactive.sz()-1);
- inactive.pop();
-
- Vector a( opt->cons[cidx] );
- // update of matrices
- Vector Ha = H*a;
- Real aHa = a*Ha;
- if (ABS(aHa) > EPS) {
- /*
- a != 0, so if Ha = O(EPS), then
- Ha * aH / aHa = O(EPS^2/EPS)
-
- if H*a == 0, the constraints are dependent.
- */
- H -= Matrix(Ha , Ha)/(aHa);
-
-
- /*
- sorry, don't know how to justify this. ..
- */
- Vector addrow(Ha/(aHa));
- A -= Matrix(A*a, addrow);
- A.insert_row(addrow,A.rows());
- }else
- WARN << "degenerate constraints";
-}
-
-void
-Active_constraints::drop(int k)
-{
- int q=active.sz()-1;
-
- // drop indices
- inactive.add(active[k]);
- active.swap(k,q);
- A.swap_rows(k,q);
- active.pop();
-
- Vector a(A.row(q));
- if (a.norm() > EPS) {
- /*
-
- */
- H += Matrix(a,a)/(a*opt->quad*a);
- A -= A*opt->quad*Matrix(a,a)/(a*opt->quad*a);
- }else
- WARN << "degenerate constraints";
- Vector rem_row(A.row(q));
- assert(rem_row.norm() < EPS);
- A.delete_row(q);
-}
-
-
-Active_constraints::Active_constraints(Ineq_constrained_qp const *op)
- : A(0,op->dim()),
- H(op->dim()),
- opt(op)
-{
- for (int i=0; i < op->cons.sz(); i++)
- inactive.add(i);
- Choleski_decomposition chol(op->quad);
- H=chol.inverse();
-}
-
-/* Find the optimum which is in the planes generated by the active
- constraints.
- */
-Vector
-Active_constraints::find_active_optimum(Vector g)
-{
- return H*g;
-}
-
-/****************************************************************/
-
-int
-min_elt_index(Vector v)
-{
- Real m=INFTY; int idx=-1;
- for (int i = 0; i < v.dim(); i++){
- if (v(i) < m) {
- idx = i;
- m = v(i);
- }
- assert(v(i) <= INFTY);
- }
- return idx;
-}
-
-///the numerical solving
-Vector
-Ineq_constrained_qp::solve(Vector start) const
-{
- Active_constraints act(this);
-
-
- act.OK();
-
-
- Vector x(start);
- Vector gradient=quad*x+lin;
-
-
- Vector last_gradient(gradient);
- int iterations=0;
-
- while (iterations++ < MAXITER) {
- Vector direction= - act.find_active_optimum(gradient);
-
- mtor << "gradient "<< gradient<< "\ndirection " << direction<<"\n";
-
- if (direction.norm() > EPS) {
- mtor << act.status() << '\n';
-
- Real minalf = INFTY;
-
- Inactive_iter minidx(act);
-
-
- /*
- we know the optimum on this "hyperplane". Check if we
- bump into the edges of the simplex
- */
-
- for (Inactive_iter ia(act); ia.ok(); ia++) {
-
- if (ia.vec() * direction >= 0)
- continue;
- Real alfa= - (ia.vec()*x - ia.rhs())/
- (ia.vec()*direction);
-
- if (minalf > alfa) {
- minidx = ia;
- minalf = alfa;
- }
- }
- Real unbounded_alfa = 1.0;
- Real optimal_step = MIN(minalf, unbounded_alfa);
-
- Vector deltax=direction * optimal_step;
- x += deltax;
- gradient += optimal_step * (quad * deltax);
-
- mtor << "step = " << optimal_step<< " (|dx| = " <<
- deltax.norm() << ")\n";
-
- if (minalf < unbounded_alfa) {
- /* bumped into an edge. try again, in smaller space. */
- act.add(minidx.idx());
- mtor << "adding cons "<< minidx.idx()<<'\n';
- continue;
- }
- /*ASSERT: we are at optimal solution for this "plane"*/
-
-
- }
-
- Vector lagrange_mult=act.get_lagrange(gradient);
- int m= min_elt_index(lagrange_mult);
-
- if (m>=0 && lagrange_mult(m) > 0) {
- break; // optimal sol.
- } else if (m<0) {
- assert(gradient.norm() < EPS) ;
-
- break;
- }
-
- mtor << "dropping cons " << m<<'\n';
- act.drop(m);
- }
- if (iterations >= MAXITER)
- WARN<<"didn't converge!\n";
-
- mtor << ": found " << x<<" in " << iterations <<" iterations\n";
- assert_solution(x);
- return x;
-}
-
-/** Mordecai Avriel, Nonlinear Programming: analysis and methods (1976)
- Prentice Hall.
-
- Section 13.3
-
- This is a "projected gradient" algorithm. Starting from a point x
- the next point is found in a direction determined by projecting
- the gradient onto the active constraints. (well, not really the
- gradient. The optimal solution obeying the active constraints is
- tried. This is why H = Q^-1 in initialisation) )
-
-
- */
-
+++ /dev/null
-#include "qlp.hh"
-#include "matrix.hh"
-
-
-class Active_constraints {
- friend class Inactive_iter;
-
-
- Matrix A,H;
- svec<int> active;
- svec<int> inactive; // actually this is a set, not an array.
- const Ineq_constrained_qp *opt;
-
-public:
- String status()const;
-
- Vector vec(int k) const { return opt->cons[k]; }
- Real rhs(int k) const { return opt->consrhs[k]; }
-
- /// drop constraint
- void drop (int k);
- /** drop constraint k from the active set. k is the index of the
- constraint in #active#
-
- */
-
- /// add constraint j
- void add(int j);
- /**
- add constraint j to the active set j is the index of the
- constraint in #inactive#
- */
-
- /// exchange in and out.
- void exchange(int in, int out) { add(in); drop (out); }
-
- ///
- Vector find_active_optimum(Vector g);
-
- /// get lagrange multipliers.
- Vector get_lagrange(Vector v);
-
- Active_constraints(Ineq_constrained_qp const *op);
- /** construct: no constraints active, n vars. Put the equalities
- into the constraints. */
-
- /// check invariants
- void OK();
-};
-
-/**
- This class represents the set of active (binding) constraints
- which can be active while the QLP algorithm is in a feasible
- point. The active constraints are numbered.
- If the constraints are of the form
-
- A^T*x >= b
-
- then the binding constraints are those where the >= is equality.
-
- */
-
-///
-class Inactive_iter {
- int j;
- Active_constraints const* ac;
-public:
- Inactive_iter(Active_constraints const &c) { ac=&c; j=0; }
- int idx() const { return j; }
- void operator ++(int) { j++; }
- int constraint_id() const { return ac->inactive[j]; }
- Vector vec() const { return ac->vec(constraint_id()); }
- Real rhs() const { return ac->rhs(constraint_id()); }
- bool ok() const { return j < ac->inactive.sz(); }
-};
-/**
- loop through the inactive constraints.
- */
+++ /dev/null
-#include "request.hh"
-#include "debug.hh"
-
-#define VIRTUALCONS(T,R) R *T::clone() const { return new T(*this); } struct T
-#define RCONS(T) VIRTUALCONS(T, Request)
-
-RCONS(Rest_req);
-RCONS(Rhythmic_req);
-RCONS(Stem_req);
-RCONS(Note_req);
-
-
-void
-Request::print() const
-{
-#ifndef NPRINT
- mtor << "Req{ unknown }\n";
-#endif
-}
-
-Request::Request(Voice_element*v)
-{
- elt = v;
-}
-
-Note_req::Note_req(Voice_element*v)
- : Rhythmic_req(v)
-{
- name = 'c';
- octave = 0;
- accidental = 0;
- forceacc = false;
-}
-
-int
-Note_req::height() const
-{
- int s = name -'c';
- if (s < 0)
- s+=7;
- return s + octave*7;
-}
-
-Rhythmic_req::Rhythmic_req(Voice_element*v)
- :Request(v)
-{
- balltype = 1;
- dots = 0;
-}
-
-void
-Rhythmic_req::print() const
-{
- mtor << "rhythmic: " << balltype ;
- int d =dots;
- while (d--)
- mtor << '.';
- mtor<<"\n";
-}
-
-void
-Note_req::print() const
-{
- mtor << "note: " << name << " oct: "<< octave;
- Rhythmic_req::print();
-}
-
-Request::Request()
-{
- elt = 0;
-}
-
-void
-Rest_req::print() const
-{
- mtor << "rest, " ;
- Rhythmic_req::print();
-}
-
-Real
-wholes(int dur, int dots)
-{
- Real f = 1.0/Real(dur);
- Real delta = f;
-
- while (dots--) {
- delta /= 2.0;
- f += delta;
- }
- return f;
-}
-
-Real
-Rhythmic_req::duration() const {
- return wholes( balltype,dots);
-}
-
+++ /dev/null
-// LilyPond's second egg of columbus!
-#ifndef REQUEST_HH
-#define REQUEST_HH
-
-#include "glob.hh"
-#include "string.hh"
-
-/// a voice element wants something printed
-struct Request {
- Voice_element*elt; // indirection.
-
- /****************/
-
- virtual void print()const ;
- virtual Note_req *note() {return 0;}
- virtual Stem_req *stem() {return 0;}
- virtual Rest_req *rest() {return 0;}
- virtual Rhythmic_req*rhythmic() { return 0;}
- Request(Voice_element*);
- Request();
- virtual Real duration() const { return 0.0; }
- virtual Request* clone() const =0;
-};
-
-/**
- Any Voice_element can do a number of requests. A request is done
- to the #Staff# which contains the #Voice_element#. The staff decides
- whether to to honor the request, ignore it, or merge it with other
- requests. Merging of requests is preferably done with other
- requests done by members of the same voicegroups (beams, brackets, stems)
-
- Please refer to the documentation of the Child classes of
- #Request# for explanation of each request type.
-
- The result of a request will be an #Item# or a #Spanner#, which
- will be put on a #PStaff#. Note that the #PStaff# and the original
- #Staff# need not have anything in common. For example, the
- ``double'' piano Staff could interpret commands which juggle
- melodies across the left and right hand, and may put the result in
- two five-line PStaffs (maybe with extra PStaffs to carry the dynamic
- signs and any lyric.
-
- The class #Staff# should be thought as a container for the
- #Voice#s, and an interpreter for #Request#s and #Command#s.
- Different staffs can produce different outputs; a melodious voice
- which is put into a percussion-Staff, will be typeset as the rythm of
- that voice.
-
- After #Staff# made up her mind (Would #Staff# be a smart
- name? How about #struct Susan {}# :-), the resultant items and
- spanners are put on the PScore, and pointers to these items are
- stored in the #Voice_element#. This construction enables the
- beams/stems to look up the balls it has to connect to. */
-
-
-/// a request with a duration
-struct Rhythmic_req : Request {
- int balltype;
- int dots;
-
- /****************/
-
- Real duration() const;
- Rhythmic_req(Voice_element*);
- Rhythmic_req*rhythmic() { return this;}
- void print ()const;
- Request*clone() const;
-};
-
-/// Put a note of specified type, height, and with accidental on the staff.
-struct Note_req : Rhythmic_req {
- char name;
- int octave;
- int accidental;
- bool forceacc;
-
- /****************/
-
- // return height from central c (in halflines)
- int height()const;
- Note_req(Voice_element*v);
- Note_req*note() { return this;}
- virtual void print() const;
- Request*clone() const;
-};
-/**
-Staff has to decide if the ball should be hanging left or right. This
-influences the horizontal dimensions of a column, and this is why
-request processing should be done before horizontal spacing.
-
-Other voices' frivolities may cause the need for accidentals, so this
-is also for the Staff to decide. The Staff can decide on positioning
-based on ottava commands and the appropriate clef.
-*/
-
-
-///Put a rest on the staff.
-struct Rest_req : Rhythmic_req {
- void print()const;
- Rest_req(Voice_element*v) : Rhythmic_req(v) { }
- Rest_req * rest() { return this;}
- Request*clone() const ;
-};
-/**
-Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
-*/
-
-/// attach a stem to the noteball
-struct Stem_req : Request {
- /// 4,8,16, ..
- int stem_number;
- virtual Stem_req *stem() {return this;}
- Stem_req(Voice_element*v, int s) : Request(v) { stem_number = s; }
- Request*clone() const;
-};
-
-
-#if 0
-
-///Put a lyric above or below (?) this staff.
-struct Lyric_req : Request {
- String text;
-};
-
-
-///Put a script above or below this ``note''
-struct Script_req : Request {
- int orientation;
- Symbol sym;
-};
-/**
-eg upbow, downbow. Why a request? These symbols may conflict with slurs and brackets, so this
-also a request
-*/
-
-
-
-
-///Draw a (Guitar) chord above or below this ``note''
-struct Chord : Request {
- // don't know how this looks.
-};
-/**
-Why a request?
-Because everything else is done in requests.
-*/
-
-
-/// for absolute dynamics
-enum Loudness {
- FFF, FF, F, MF, MP, P, PP, PPP
-} ;
-
-/// requests to start or stop something.
-struct Span_req : Request {
- /// should the spanner start or stop, or is it unwanted?
- enum {
- NOSPAN, START, STOP
- } spantype ;
-};
-/**
- This type of request typically results in the creation of a #Spanner#
-*/
-
-
-///Start / stop a beam at this note.
-struct Beam_req : Span_req {
- int nplet;
-};
-/** Staff will have to combine this with the stem_request, since the
- number of flags that a stem wants to carry will determine the
- number of beams. if #nplet# is set, the staff will try to put an
- appropriate number over the beam
-
- [what to do if the nplet fields of start and stop conflict?]
- */
-
-///Start / stop a slur or a bracket.
-struct Bracket_req : Span_req {
- int nplet;
-};
-/**
-Start/stop a bracket at this note. if #nplet# is set, the staff will
-try to put an appropriate number over the bracket
-*/
-
-/// a slur
-struct Slur_req : Span_req {
-
-};
-
-/// helper in the hierarchy
-struct Dynamic {
- 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).
- Dynamic changes can occur in a smaller time than the length of its
- note, therefore fore each Dynamic request carries a time, measured
- from the start of its note.
-
- This subfield would come in handy, if mpp96 was adapted for midi
- support.
-
- Dynamic should have been derived from request, but I don't want to
- fuss with virtual baseclasses. */
-
-/// do a crescendo
-struct Cresc_req : Span_req, Dynamic {
-
-};
-
-/// do a decrescendo
-struct Decresc_req : Span_req, Dynamic {
-
-};
-
-/// do a dynamic like "fff" or "mp"
-struct Absdynamic_req : Request, Dynamic {
- Loudness loudness;
-};
-#endif
-#endif
+++ /dev/null
-#include "molecule.hh"
-#include "notehead.hh"
-#include "stem.hh"
-#include "linestaff.hh"
-#include "rhythmstaff.hh"
-#include "paper.hh"
-#include "sccol.hh"
-
-
-void
-Rhythmic_staff::set_output(PScore*ps)
-{
- theline = new Linestaff(1,ps);
- Simple_staff::set_output(ps);
-}
-
-
-void
-Rhythmic_column::typeset_command(Command *com, int breakst)
-{
- Item *i =new Item;
- Molecule*m = create_command_mol(com);
- i->output=m;
- m->translate(Offset(0,
- -staff_->score_->paper_->standard_height()/2));
- typeset_item(i, breakst);
-}
-
-void
-Rhythmic_column::typeset_req(Request *rq)
-{
- Item *i ;
- if (rq->note()) {
- Notehead *n =new Notehead(1);
- n->balltype = rq->rhythmic()->balltype;
- n->dots = rq->rhythmic()->dots;
- n->position = 0;
- i = n;
- } else if (rq->rest()) {
- i =new Item;
- Molecule*m=create_req_mol(rq);
- i->output=m;
- }
- typeset_item(i);
-}
-
-void
-Rhythmic_column::typeset_stem(Stem_req*rq)
-{
- Stem * s = new Stem(0);
- s->minnote = s->maxnote = 0;
- s->flag = rq->stem_number;
- typeset_item(s);
-}
-
-/*
- creation
- */
-Staff *
-get_new_rhythmstaff()
-{
- return new Rhythmic_staff;
-}
-
-
-Staff_column*
-Rhythmic_staff::create_col(Score_column*s)
-{
- return new Rhythmic_column(s,this);
-}
-
-Rhythmic_staff*
-Rhythmic_staff::clone() const
-{
- return new Rhythmic_staff(*this);
-}
+++ /dev/null
-/*
- rhythmstaf.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef RHYTHMSTAF_HH
-#define RHYTHMSTAF_HH
-
-#include "simplestaff.hh"
-
-/// all notes on one line
-struct Rhythmic_staff : public Simple_staff
-{
- // Rhythmic_staff();
- Staff_column * create_col(Score_column*);
- virtual void set_output(PScore *);
- virtual Rhythmic_staff*clone()const;
-};
-
-/// this does the typesetting
-struct Rhythmic_column : public Simple_column {
- virtual void typeset_req(Request *rq);
- virtual void typeset_stem(Stem_req *rq);
- virtual void typeset_command(Command *, int brs);
-
-
-// virtual void typeset_item(Item *rq, int=1);
- Rhythmic_column(Score_column*s,Simple_staff*rs) :
- Simple_column(s,rs) { }
-// virtual Rhythmic_column*clone()const;
-};
-
-#endif // RHYTHMSTAF_HH
-
-
+++ /dev/null
-#include "sccol.hh"
-#include "debug.hh"
-
-Score_column::Score_column(Real w)
-{
- when = w;
- pcol = new PCol(0);
- musical = false;
-}
-
-bool
-Score_column::used() {
- return pcol->used;
-}
-
-void
-Score_column::print() const
-{
-#ifndef NPRINT
- mtor << "Score_column { mus "<< musical <<" at " << when<<'\n';
- mtor << "durations: [";
- for (int i=0; i < durations.sz(); i++)
- mtor << durations[i] << " ";
- mtor << "]\n";
- pcol->print();
- mtor << "}\n";
-#endif
-}
+++ /dev/null
-/*
- sccol.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef SCCOL_HH
-#define SCCOL_HH
-#include "pcol.hh"
-
-
-struct Score_column {
- PCol * pcol;
- svec<Real> durations;
- Real when;
-
- ///
- bool musical;
-
-
- Score_column(Real when);
-
- static int compare(Score_column & c1, Score_column &c2) {
- return sgn(c1.when - c2.when);
- }
- void set_breakable() {
- pcol->set_breakable();
- }
- bool used();
- void print() const;
-};
-/**
-
- When typesetting hasn't started on PScore yet, the columns which
- contain data have a rhythmical position. Score_column is the type
- with a rhythmical time attached to it. The calculation of
- idealspacing is done with data in these columns. (notably: the
- #durations# field)
-
- */
-
-instantiate_compare(Score_column&, Score_column::compare);
-
-#endif // SCCOL_HH
-
+++ /dev/null
-#include "scommands.hh"
-#include "debug.hh"
-#include "parseconstruct.hh"
-
-/*
- maybe it's time for a "narrowing" cursor?
- */
-PCursor<Command*>
-Score_commands::first(Real w)
-{
- PCursor<Command*> pc(*this);
- while (pc.ok() && pc->when < w)
- pc++;
-
- return pc;
-}
-
-PCursor<Command*>
-Score_commands::last_insertion(Real w)
-{
- PCursor<Command*> pc(*this);
- while (pc.ok() && pc->when <= w)
- pc++;
- return pc;
-}
-
-void
-Score_commands::add_seq(svec<Command> com)
-{
- if (!com.sz())
- return;
- Real when = com[0].when;
-
- PCursor<Command*> pc(last_insertion(when));
- for (int i = 0; i < com.sz(); i++) {
- Command *c = new Command(com[i]);
- assert(com[i].when == when);
- if (!pc.ok())
- pc.add(c);
- else
- pc.insert(c);
- }
-}
-
-void
-Score_commands::set_breakable(Real when)
-{
- bool found_typeset(false);
- PCursor<Command*> cc = first(when);
- for (; cc.ok() && cc->when == when; cc++) {
- if (cc->isbreak())
- return;
- if (cc->code == TYPESET)
- found_typeset=true;
- }
-
- assert(!found_typeset);
-
- svec<Command> seq;
- Command k(when);
- k.code = BREAK_PRE;
- seq.add(k);
- k.code = BREAK_MIDDLE;
- seq.add(k);
- k.code = BREAK_POST;
- seq.add(k);
- k.code = BREAK_END;
- seq.add(k);
-
- add_seq(seq);
-}
-bool
-Score_commands::is_breakable(Real w)
-{
- PCursor<Command*> cc = first(w);
- for (; cc.ok() && cc->when == w; cc++) {
- if (cc->isbreak())
- return true;
- }
- 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;
- PCursor<Command*> c ( first(w)), f(c), l(c);
-
- while (!c->isbreak())
- c++;
- f = c++;
- while (!c->isbreak())
- c++;
- l = c++;
-
- insert_between(pre, f, l);
- f = l;
- while (!c->isbreak())
- c++;
- 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::parser_add(Command *c)
-{
- bottom().add(c);
-}
-
-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(w);
- encapsulate = true;
- mid = c;
- pre = c;
- }
- if (c.args[0] == "METER" && is_breakable(w)) {
- encapsulate = true;
- mid = c;
- pre = c;
- post =c;
- }
- }
-
- if (encapsulate)
- add_command_to_break(pre, mid, post);
- else {
- svec<Command> seq;
- seq.add(c);
- add_seq(seq);
- }
-}
-
-/*
- first and last column should be breakable.
- Remove any command past the last musical column.
- */
-void
-Score_commands::clean(Real l)
-{
- assert(l>0);
- if (!is_breakable(0.0)) {
- Command c(0.0);
- c.code = TYPESET;
- c.args.add("BAR");
- c.args.add("empty");
- process_add(c);
- }
-
- PCursor<Command*> bot(bottom());
-
- while (bot.ok() && bot->when > l) {
- mtor <<"removing ";
- bot->print();
- bot.del();
- bot = bottom();
- }
-
- if (!is_breakable(l)) {
- Command c(l);
- c.code = TYPESET;
- c.args.add("BAR");
- c.args.add("||");
- process_add(c);
- }
- OK();
-}
-
-void
-Score_commands::OK() const
-{
- 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);
- }
-}
-
-void
-Score_commands::print() const
-{
- for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
- 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;
-}
+++ /dev/null
-/*
- lilypond, (c) 1996 Han-Wen Nienhuys
-*/
-#ifndef SCOMMANDS_HH
-#define SCOMMANDS_HH
-
-#include "proto.hh"
-#include "command.hh"
-#include "vray.hh"
-#include "plist.hh"
-
-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);
- bool is_breakable(Real w);
- PCursor<Command*> last_insertion(Real w);
- PCursor<Command*> first(Real w);
- 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. */
-
-#endif
-
+++ /dev/null
-#include "scommands.hh"
-#include "tstream.hh"
-#include "score.hh"
-#include "sccol.hh"
-#include "pscore.hh"
-#include "staff.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;
-
- *mlog << "output to " << paper_->outfile << "...\n";
- Tex_stream the_output(paper_->outfile);
- pscore_->output(the_output);
-}
-
-
-void
-Score::process()
-{
- *mlog << "Processing ... ";
- set(commands_->parse(last()));
- commands_->print();
-
- if (!paper_)
- paper_ = new Paperdef;
-
- commands_->clean(last());
-
- /// distribute commands to disciples
- distribute_commands();
-
- pscore_ = new PScore(paper_);
- for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->set_output(pscore_);
- sc->process();
- }
-
- // do this after processing, staffs first have to generate PCols.
- do_pcols();
- calc_idealspacing();
- clean_cols();
- OK();
- // print();
-
- pscore_->preprocess();
- *mlog << "Calculating ... ";
- pscore_->calc_breaking();
- pscore_->postprocess();
-
- // TODO: calculate vertical structs
- // TODO: calculate mixed structs.
- *mlog << "\n";
-}
-
-// remove empty cols with no spacing attached.
-/* should rethink ownership of cols
- */
-void
-Score::clean_cols()
-{
- for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
- sc->clean_cols();
-
- for (PCursor<Score_column*> c(cols_); c.ok(); ) {
- if (!c->pcol->used) {
- mtor << "removing : ";
- c->print();
- c.del();
- } else
- c++;
- }
-
- pscore_->clean_cols();
-}
-/* this sux. We should have Score_column create the appropriate PCol.
- Unfortunately, PCols don't know about their position.
- */
-// todo
-PCursor<Score_column*>
-Score::create_cols(Real w)
-{
- Score_column* c1 = new Score_column(w);
- Score_column* c2 = new Score_column(w);
-
- c1->musical = false;
- c2->musical = true;
-
- PCursor<Score_column*> scc(cols_);
-
- for (; scc.ok(); scc++) {
- assert(scc->when != w);
- if (scc->when > w)
- break;
- }
-
- if (!scc.ok()) {
- cols_.bottom().add(c1);
- cols_.bottom().add(c2);
- scc = cols_.bottom();
- scc --;
- } else {
- scc.insert(c1);
- scc.insert(c2);
- scc -= 2;
- }
- return scc;
-}
-
-Score_column*
-Score::find_col(Real w,bool mus)
-{
- PCursor<Score_column*> scc(cols_);
- for (; scc.ok(); scc++) {
- if (scc->when == w && scc->musical == mus)
- return scc;
- if (scc->when > w)
- break;
- }
- scc = create_cols(w);
- if (mus)
- scc++;
- return scc;
-}
-
-void
-Score::distribute_commands(void)
-{
- for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->add_commands(*commands_);
- }
-}
-void
-Score::add(Staff*s)
-{
- s->score_ = this;
- staffs_.bottom().add(s);
-}
-
-
-void
-Score::do_pcols()
-{
- PCursor<Score_column*> sc(cols_);
- for (; sc.ok(); sc++) {
- pscore_->add(sc->pcol);
- }
-}
-Real
-Score::last() const
-{
- Real l = 0;
- for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
- l = MAX(l, stc->last());
- }
- return l;
-}
-
-void
-Score::OK() const
-{
-#ifndef NDEBUG
- for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->OK();
- assert(sc->score_ == this);
- }
- staffs_.OK();
- cols_.OK();
- for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
- assert(cc->when <= (cc+1)->when);
- }
- commands_->OK();
-#endif
-}
-
-
-void
-Score::print() const
-{
-#ifndef NPRINT
- mtor << "score {\n";
- for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->print();
- }
- for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
- sc->print();
- }
- commands_->print();
- mtor << "}\n";
-#endif
-}
-
-Score::Score()
-{
- pscore_=0;
- paper_ = 0;
- commands_ = new Score_commands;
-}
-
-Score::~Score()
-{
- delete pscore_;
- delete commands_;
- delete paper_;
-}
-
-void
-Score::set(Score_commands*c)
-{
- delete commands_;
- commands_ = c;
-}
+++ /dev/null
-#ifndef SCORE_HH
-#define SCORE_HH
-#include "vray.hh"
-#include "proto.hh"
-#include "plist.hh"
-
-
-/// the total music def of one movement
-struct Score {
- /// paper_, staffs_ and commands_ form the problem definition.
- Paperdef *paper_;
- PointerList<Staff *> staffs_;
- Score_commands *commands_;
-
- /// "runtime" fields for setting up spacing
- PointerList<Score_column*> cols_;
- PScore *pscore_;
-
- /****************************************************************/
-
- /// 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(Real,bool);
- void process();
- void output(String fn);
- PCursor<Score_column*> create_cols(Real);
- void print() const;
- Real last() const;
-
-private:
- void do_pcols();
- void clean_cols();
- void distribute_commands();
- void do_connect(PCol *c1, PCol *c2, Real d);
- void connect_nonmus(PCol* c1, PCol *c2, Real d);
- /// add #Idealspacings# to #pscore_#
- void calc_idealspacing();
- /** add the score wide commands (bars, breaks) to each staff so
- they can process (typeset) them if needed */
-};
-/**
-
- */
-#endif
+++ /dev/null
-#include "main.hh"
-#include "score.hh"
-#include "string.hh"
-
-static svec<Score*> sv;
-
-static String outfn="lelie.uit";
-
-// todo: check we don't overwrite default output.
-
-void
-do_scores()
-{
- for (int i=0; i < sv.sz(); i++) {
- sv[i]->process();
- sv[i]->output(outfn);
- delete sv[i];
- sv[i] =0;
- }
-}
-
-void
-add_score(Score * s)
-{
- sv.add(s);
-}
-
-
-void
-set_default_output(String s)
-{
- outfn = s;
-}
-
+++ /dev/null
-#include "lookupsyms.hh"
-#include "request.hh"
-#include "pscore.hh"
-#include "paper.hh"
-#include "simplestaff.hh"
-#include "molecule.hh"
-#include "sccol.hh"
-
-Molecule *
-Simple_column::create_req_mol(Request *rq)
-{
- assert(rq->rest());
- Symbol s;
- int dots=0;
- if (rq->rest())
- s = staff_->paper()->lookup_->rest(rq->rest()->balltype);
-
- if (rq->rhythmic())
- dots=rq->rhythmic()->dots;
-
-
- Molecule *m = new Molecule(Atom(s));
- if (dots) {
- Symbol d = staff_->paper()->lookup_->dots(dots);
- Molecule dm;
- dm.add(Atom(d));
- m->add_right(dm);
- }
- return m;
-}
-
-Molecule *
-Simple_column::create_command_mol(Command *com)
-{
- Symbol s;
-
- if (com -> args[0] == "BAR" ) {
- s = staff_->paper()->lookup_->bar(com->args[1]);
- } else if (com->args[0] == "METER") {
- Parametric_symbol *p = staff_->paper()->lookup_->meter("general");
- svec<String> arg( com->args);
- arg.del(0);
- s = p->eval(arg);
- } else
- assert(false);
-
- Molecule * m =new Molecule(Atom(s));
- {
- Interval wid;
- svec<Item*> sv(staff_->pscore_->
- select_items(staff_->theline, score_column->pcol));
- for (int j=0; j<sv.sz(); j++) {
- wid.unite(sv[j]->output->extent().x);
- }
- if (!wid.empty())
- m->translate(Offset(wid.max,0));
- }
-
- return m;
-}
-
-void
-Simple_column::typeset_item(Item *i, int breakst)
-{
- // ugh
- staff_->pscore_->typeset_item(i, score_column->pcol,
- staff_->theline,breakst);
-}
-
-void
-Simple_staff::set_output(PScore* ps )
-{
- pscore_ = ps;
- pscore_->add(theline);
-}
+++ /dev/null
-#include "request.hh"
-#include "debug.hh"
-#include "staff.hh"
-#include "command.hh"
-#include "simplestaff.hh"
-#include "sccol.hh"
-
-
-
-
-Simple_column::Simple_column(Score_column*s, Simple_staff *rs)
- : Staff_column(s)
-{
- the_note = 0;
- stem_ = 0;
- staff_ = rs;
-}
-
-Simple_staff::Simple_staff()
-{
- theline = 0;
-}
-
-void
-Simple_column::process_commands( )
-{
- int breakstat = BREAK_END - BREAK_PRE;
- for (int i = 0 ; i < s_commands.sz(); i++) {
- Command *com = s_commands[i];
- switch (com->code){
- case INTERPRET:
- break;
- case BREAK_PRE:
- case BREAK_MIDDLE:
- case BREAK_POST:
- case BREAK_END:
- score_column->set_breakable();
- breakstat = com->code- BREAK_PRE;
- break;
-
- case TYPESET:
- typeset_command ( com , breakstat);
- break;
- default :
- break;
- }
- }
-}
-/**
- accept:
-
- BREAK: all
- TYPESET: bar, meter,
-
- */
-
-
-
-void
-Simple_column::process_requests()
-{
- for (int i = 0 ; i < v_elts.sz(); i ++)
- for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
- Request *rq= rqc;
- if (rq->rhythmic()){
- if (the_note){
- WARN << "too many notes.\n";
- }
- the_note = rq;
-
- }
- if (rq->stem()) {
- stem_ = rq->stem();
- }
-
- }
-}
-
-void
-Simple_staff::grant_requests()
-{
- for (PCursor<Staff_column*> cc(cols); cc.ok(); cc++) {
- Simple_column *rp = (Simple_column*)*cc;
- if (rp->the_note)
- rp->typeset_req( rp->the_note);
- if (rp->stem_)
- rp->typeset_stem(rp->stem_->stem());
- }
-}
-
-
+++ /dev/null
-/*
- simplestaff.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef SIMPLESTAFF_HH
-#define SIMPLESTAFF_HH
-
-#include "stcol.hh"
-#include "staff.hh"
-/*
- mega-stupido staffs and cols: they do notes one at each moment.
- */
-
-struct Simple_staff;
-
-/// column of Simple_staff: store one request
-struct Simple_column : Staff_column {
-
- Request *the_note;
- Stem_req *stem_;
-
- Simple_staff* staff_;
-
- /****************/
- virtual void typeset_stem(Stem_req *rq)=0;
- virtual void typeset_req(Request *rq)=0;
- virtual void typeset_command(Command *, int brs)=0;
- virtual void typeset_item(Item *, int=1);
-
- Molecule *create_command_mol(Command *com);
- Molecule *create_req_mol(Request *rq);
- void take_request(Request *rq);
-
- virtual void process_commands( );
- virtual void process_requests();
-
- Simple_column(Score_column*s,Simple_staff*rs);
-};
-
-
-/// Simple staff: one note at a time
-struct Simple_staff : Staff {
- /// indirection to the PStaff.
- PStaff *theline;
-
- /****************/
- virtual void set_output(PScore *);
-
- void process_commands( PCursor<Command*> &where);
- void grant_requests();
-// virtual Staff*clone()const;
-
- Simple_staff();
-};
-
-#endif // SIMPLESTAFF_HH
-
-
-
+++ /dev/null
-
-#include "spanner.hh"
-#include "line.hh"
-
-#include "symbol.hh"
-#include "molecule.hh"
-#include "pcol.hh"
-
-String
-Spanner::TeXstring() const
-{
- assert(right->line);
- Real w = left->hpos - right->hpos;
- return strets->eval(w).tex;
-}
-
-// todo.
-Spanner *
-Spanner::broken_at(const PCol *c1, const PCol *c2) const
-{
- Spanner *sp = new Spanner(*this);
- sp->left = c1;
- sp->right = c2;
- return sp;
-}
-
-Spanner::Spanner()
-{
- pstaff_=0;
- strets=0;
- left = right = 0;
-}
-
+++ /dev/null
-/*
- spanner.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef SPANNER_HH
-#define SPANNER_HH
-#include "proto.hh"
-
-/// a symbol which is attached between two columns.
-struct Spanner {
- const PCol *left, *right;
- Parametric_symbol *strets;
- PStaff * pstaff_;
- /// clone a piece of this spanner.
- virtual Spanner *broken_at(const PCol *c1, const PCol *c2) const;
- /**
-
- PRE
- c1 >= start, c2 <= stop
- */
- /****************/
- String TeXstring () const ;
- Spanner();
- virtual void process();
-};
-/** 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.
-
- */
-#endif
--- /dev/null
+#include "leastsquares.hh"
+
+void
+Least_squares::minimise(Real &coef, Real &offset)
+{
+ Real sx = 0.0;
+ Real sy = 0.0;
+ Real sqx =0.0;
+ Real sxy = 0.0;
+
+ for (int i=0; i < input.sz();i++) {
+ Real x=input[i].x;
+ Real y = input[i].y;
+ sx += x;
+ sy += y;
+ sqx += sqr(x);
+ sxy += x*y;
+ }
+ int N = input.sz();
+
+
+ coef = (N * sxy - sx*sy )/(N*sqx - sqr(sx));
+ offset = (sy - coef * sx)/N;
+
+}
+++ /dev/null
-#include "staff.hh"
-#include "stcol.hh"
-#include "sccol.hh"
-#include "debug.hh"
-
-Staff::Staff(Staff const&src)
-{
- PL_copy(voices,src.voices);
- PL_copy(commands,src.commands);
- assert(!cols.size()); // cols is a runtime field.
-
- score_ = src.score_;
- pscore_ = src.pscore_;
-}
-
-Paperdef*
-Staff::paper() const{
- return score_->paper_;
-}
-
-void
-Staff::clean_cols()
-{
- PCursor<Staff_column *> stc(cols);
- for(; stc.ok(); ){
- if (!stc->score_column->used())
- stc.del();
- else
- stc++;
- }
-}
-
-Staff_column *
-Staff::get_col(Real w, bool mus)
-{
- Score_column* sc = score_->find_col(w,mus);
- assert(sc->when == w);
- PCursor<Staff_column *> stc(cols);
- for (; stc.ok(); stc++) {
- if (*stc->score_column > *sc) // too far
- break;
- if (sc == stc->score_column)
- return stc;
- }
- Staff_column* newst = create_col(sc);
-
- if (!stc.ok()) {
- cols.bottom().add(newst);
- return cols.bottom();
- }
-
- if (mus) {
- stc.insert(newst);
- return newst;
- }
-
- if ((stc-1)->when() == newst->when()) {
- stc--;
- }
-
- stc.insert(newst);
-
- return newst;
-}
-
-
-void
-Staff::add_voice(Voice *v)
-{
- voices.bottom().add(v);
-}
-
-/*
- put all stuff grouped vertically in the Staff_cols
- */
-void
-Staff::setup_staffcols()
-{
-
- for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
-
- Real now = vc->start;
- for (PCursor<Voice_element *> ve(vc->elts); ve.ok(); ve++) {
-
- Staff_column *sc=get_col(now,true);
- sc->add(ve);
- now += ve->duration;
- }
- }
-
- for (PCursor<Command*> cc(commands); cc.ok(); cc++) {
- Staff_column *sc=get_col(cc->when,false);
- sc->s_commands.add(cc);
- }
-}
-
-/// merge commands from score
-void
-Staff::add_commands(PointerList<Command*> const &cl)
-{
- PCursor<Command*> score_c(cl);
- PCursor<Command*> cc(commands);
-
- while (score_c.ok()) {
- while (cc.ok() && cc->when <= score_c->when)
- cc++;
-
- Command*nc = new Command (*(* score_c));
- if (cc.ok()) {
- // cc->when > score_c->when
- cc.insert( nc );
- } else {
- commands.bottom().add( nc);
- cc = commands.bottom();
- }
- score_c++;
- }
-
- // now integrate break commands with other commands.
- // maybe do this in derived functions.
-}
-
-void
-Staff::process()
-{
- setup_staffcols();
- OK();
- for (PCursor<Staff_column*> sc(cols); sc.ok(); sc++) {
- sc->process_commands();
- sc->process_requests();
- }
- grant_requests();
-}
-
-void
-Staff::OK() const
-{
-#ifndef NDEBUG
- cols.OK();
- commands.OK();
- voices.OK();
- assert(score_);
-#endif
-}
-
-
-Real
-Staff::last() const
-{
- Real l = 0.0;
- for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
- l = MAX(l, vc->last());
- }
- return l;
-}
-
-
-void
-Staff::print() const
-{
-#ifndef NPRINT
- mtor << "Staff {\n";
- for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
- vc->print();
-
- }
- mtor <<"}\n";
-#endif
-}
-
-Staff::Staff()
-{
- score_ =0;
- pscore_=0;
-}
+++ /dev/null
-#ifndef STAFF_HH
-#define STAFF_HH
-
-#include "score.hh"
-#include "voice.hh"
-#include "command.hh"
-
-
-/// base class for a collection of voices.
-struct Staff {
- /// synchronous horizontal stuff
- PointerList<Voice*> voices;
-
- /// commands in chronological order
- PointerList<Command *> commands;
-
- /// runtime field
- PointerList<Staff_column*> cols;
-
- /// indirections to the Score and PScore
- Score *score_;
- PScore *pscore_;
-
- /****************************************************************/
- Staff(const Staff&src);
- void add_voice(Voice *v);
- void add_staff_column(Staff_column *sp);
-
- Paperdef*paper()const;
- /// interpret all requests and add items to #destination#.
- void process();
- /**
- This routines calls virtual functions from Staff, to delegate the
- interpretation of requests to a derived class of Staff */
- void setup_staffcols();
-
- 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);
- /**
- add all commands from sv.
-
- PRE
- sv is time-ordered.
- */
-
- Staff();
- /**
- Should construct with Score as arg, but this isn't known during parsing.
- */
- /****************************************************************
- VIRTUALS
- ****************************************************************/
- virtual Staff*clone()const=0;
- virtual void set_output(PScore * destination)=0;
- virtual void grant_requests()=0;
- virtual Staff_column * create_col(Score_column * )=0;
- virtual ~Staff() { }
-};
-#endif
-
-
+++ /dev/null
-#include "stcol.hh"
-#include "sccol.hh"
-#include "voice.hh"
-
-bool
-Staff_column::mus() const
-{
- return score_column->musical;
-}
-
-Real
-Staff_column::when() const
-{
- return score_column->when;
-}
-
-void
-Staff_column::add(Voice_element*ve)
-{
- Real d= ve->duration;
- if (d){
- score_column->durations.add(d);
- }
-
- v_elts.add(ve);
-}
-
-Staff_column::Staff_column(Score_column*s) {
- score_column = s;
-}
+++ /dev/null
-/*
- stcol.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef STCOL_HH
-#define STCOL_HH
-#include "proto.hh"
-#include "vray.hh"
-
-/// store simultaneous requests
-struct Staff_column {
- Score_column *score_column;
-
- /// fields to collect data vertically.
- svec<Voice_element *> v_elts;
- svec<Command *> s_commands;
-
- Staff_column(Score_column*s);
- bool mus() const;
- Real when() const;
- void add(Voice_element*ve);
- /****************************************************************
- VIRTUAL
- ****************************************************************/
- //virtual Staff_column *clone() const=0;
- virtual void process_requests()=0;
- virtual void process_commands()=0;
- virtual ~Staff_column() { }
-};
-
-
-#endif // STCOL_HH
-
+++ /dev/null
-#include "stem.hh"
-#include "dimen.hh"
-#include "debug.hh"
-#include "pstaff.hh"
-#include "pscore.hh"
-#include "paper.hh"
-#include "lookupsyms.hh"
-#include "molecule.hh"
-
-const int STEMLEN=7;
-
-Stem::Stem(int c)
-{
- minnote = maxnote = 0;
- bot = top = 0;
- flag = 4;
- staff_center=c;
-}
-
-void
-Stem::print()const
-{
- mtor << "Stem minmax=["<< minnote<<","<<maxnote<<"], flag: "<<flag;
- Item::print();
-}
-
-void
-Stem::calculate()
-{
- assert(minnote<=maxnote);
- int stafftop = 2*staff_center;
-
- if (maxnote < -2){
- bot = minnote;
- top = staff_center - staff_center/2; // uhh... how about non 5-line staffs?
-
- }else if (minnote > stafftop + 2) {
- top = maxnote;
- bot = staff_center + staff_center/2;
- flag = -flag;
- }else {
- Real mean = (minnote+maxnote)/2;
-
- top = (mean > staff_center) ? maxnote : maxnote+STEMLEN;
- bot = (mean > staff_center) ? minnote-STEMLEN : minnote;
- flag = (mean > staff_center) ? -flag : flag;
- }
-}
-
-void
-Stem::postprocess()
-{
- calculate();
- brew_molecole();
-}
-
-Interval
-Stem::width()const
-{
- if (ABS(flag) <= 4)
- return Interval(0,0); // TODO!
- Paperdef*p= pstaff_->pscore_->paper_;
- return p->lookup_->flag(flag).dim.x;
-}
-
-void
-Stem::brew_molecole()
-{
- assert(pstaff_);
- assert(bot!=top);
- assert(!output);
-
- Paperdef *p = pstaff_->pscore_->paper_;
- Parametric_symbol *stem = p->lookup_->stem();
-
- Real dy = p->interline()/2;
- String y1 =print_dimen( dy * bot);
- String y2 = print_dimen(dy * top);
- Symbol ss =stem->eval(y1,y2);
- delete stem;
-
- output = new Molecule(Atom(ss));
-
- if (ABS(flag) > 4){
- Symbol fl = p->lookup_->flag(flag);
- Molecule m(fl);
- if (flag < -4){
- output->add_bot(m);
- } else if (flag > 4) {
- output->add_top(m);
- } else
- assert(false);
- }
-
- if (flag > 0){
- Real dx = pstaff_->pscore_->paper_->note_width(); // ugh
- output->translate(Offset(dx,0));
- }
-}
+++ /dev/null
-/*
- stem.hh -- part of LilyPond
-
- (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef STEM_HH
-#define STEM_HH
-#include "item.hh"
-
-/// the rule attached to the ball
-struct Stem : public Item {
- // heads the stem encompasses (positions)
- int minnote, maxnote;
-
- int staff_center;
-
- // extent of the stem (positions)
- int bot, top;
-
- // flagtype? 4 none, 8 8th flag, 0 = beam.
- int flag;
-
- /****************/
-
- void postprocess();
- Stem(int center);
- void print() const;
- Interval width() const;
-private:
- void calculate();
- void brew_molecole();
-};
-/**
- takes care of:
-
- \begin{itemize}
- \item the rule
- \item the flag
- \item up/down position.
- \end{itemize}
- */
-
-#endif
+++ /dev/null
-% testje
-
-score{
- rhythmstaff {
- 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}
-}
+++ /dev/null
-#include "symbol.hh"
-
-Symbol::Symbol()
- : dim(Interval(0,0),Interval(0,0))
-{
- tex = "\\unknown";
-}
-Symbol::Symbol(String s, Box b)
- : dim(b)
-{
- tex = s;
-}
-
-/****************************************************************/
-
-Symbol
-Parametric_symbol::eval(String args1)const
-{
- svec<String> a;
- a.add(args1);
- return eval(a);
-}
-
-Symbol
-Parametric_symbol::eval(String args1,String arg2)const
-{
- svec<String> a;
- a.add(args1);
- a.add(arg2);
- return eval(a);
-}
-
+++ /dev/null
-#ifndef SYMBOL_HH
-#define SYMBOL_HH
-#include "string.hh"
-#include "boxes.hh"
-#include "proto.hh"
-
-struct Symbol {
- String tex;
- Box dim;
-
- Symbol (String, Box);
- Symbol();
-};
-
-struct Parametric_symbol {
- Symtables*symtables_; // indirection
-
- /*****************/
-
- Parametric_symbol(Symtables*s) { symtables_ = s; }
- Symbol eval(String args1) const; // convenience
- Symbol eval(String args1,String arg2) const; // convenience
- virtual Symbol eval(svec<String> args)const =0;
- virtual ~Parametric_symbol(){}
-};
-
-#endif
+++ /dev/null
-#include "misc.hh"
-#include "dimen.hh"
-#include "debug.hh"
-#include "real.hh"
-#include "symbol.hh"
-#include "assoc.hh"
-#include "symtable.hh"
-
-
-Symbol
-Symtable::lookup(String s) const
-{
- if (elt_query(s))
- return (*this)[s];
- else {
- error( "Unknown symbol " +s+'\n');
- }
-}
-
-Symtable*
-Symtables::operator()(String s)
-{
- return Assoc<String, Symtable*>::operator[](s);
-}
-
-void
-Symtables::read(Text_db &symini)
-{
- while (!symini.eof()) {
- Text_record r( symini++);
- if (r[0] == "end" )
- return;
- assert (r[0] == "table");
-
- String tabnam = r[1];
- Symtable * sp = new Symtable;
- while (!symini.eof()){
- r = symini++;
- if (r[0] == "end")
- break;
-
- assert(r.sz() == 6);
- int i=0;
- String id=r[i++];
- String tex=r[i++];
- svec<Real> dims;
- for (int j=0; j < 4; j++)
- dims.add( parse_dimen(r[i++]));
-
- Symbol s(tex, Box(dims));
- (*sp)[id] = s;
- }
- (*this)[tabnam] = sp;
- }
-}
-
-
-
+++ /dev/null
-/*
- lilypond, (c) 1996 Han-Wen Nienhuys
-*/
-#ifndef SYMTABLE_HH
-#define SYMTABLE_HH
-#include "assoc.hh"
-#include "string.hh"
-#include "symbol.hh"
-
-struct Symtable : public Assoc<String, Symbol> {
- Symbol lookup(String)const;
-};
-
-
-struct Symtables : private Assoc<String, Symtable*> {
- void read(Text_db&) ;
- Symtable* operator()(String s);
-
-};
-
-
-#endif
-
+++ /dev/null
-#include "glob.hh"
-#include "debug.hh"
-#include "string.hh"
-#include "identifier.hh"
-#include "keyword.hh"
-#include "associter.hh"
-#include "parser.hh"
-
-static Keyword_ent the_key_tab[]={
- "voice", VOICE,
- "rhythmstaff", RHYTHMSTAFF,
- "melodicstaff", MELODICSTAFF,
- "score", SCORE,
- "bar", BAR,
- "output", OUTPUT,
- "cm", CM,
- "pt", PT,
- "in", IN,
- "mm", MM,
- "paper", PAPER,
- "width", WIDTH,
- "meter", METER,
- "unitspace", UNITSPACE,
- "skip", SKIP,
- "commands", COMMANDS,
- "staff", STAFF,
- "geometric", GEOMETRIC,
- 0,0
-} ;
-
-
-int
-lookup_keyword(String s)
-{
- static Keyword_table table(the_key_tab);
- return table.lookup(s);
-}
-
-Assoc<String, Identifier*> the_id_tab;
-
-Identifier*
-lookup_identifier(String s)
-{
- if (!the_id_tab.elt_query(s))
- return 0;
-
- return the_id_tab[s];
-}
-
-void
-add_identifier(Identifier*i)
-{
- the_id_tab[i->name] = i;
-}
-
-void
-delete_identifiers()
-{
-
- for (Assoc_iter<String,Identifier*> ai(the_id_tab); ai.ok(); ai++) {
- mtor << "deleting: " << ai.key()<<'\n';
- delete ai.val();
- }
-}
+++ /dev/null
-#include "line.hh"
-
-#include "plist.hh"
-#include "pcol.hh"
-#include "item.hh"
-#include "request.hh"
-#include "command.hh"
-#include "spanner.hh"
-
-#include "list.cc"
-#include "plist.cc"
-#include "cursor.cc"
-
-#define PLC_instantiate(a) PL_instantiate(a); PL_instantiate(const a)
-
-PLC_instantiate(Line_of_score);
-PLC_instantiate(Line_of_staff);
-PLC_instantiate(Item);
-PLC_instantiate(Spanner);
-PLC_instantiate(PStaff);
-PLC_instantiate(Idealspacing);
-PLC_instantiate(PCol);
-
+++ /dev/null
-#include "line.hh"
-#include "symbol.hh"
-#include "voice.hh"
-
-#include "staff.hh"
-#include "sccol.hh"
-#include "stcol.hh"
-#include "spanner.hh"
-
-#include "list.cc"
-#include "plist.cc"
-#include "cursor.cc"
-PL_instantiate(Score_column);
-PL_instantiate(Staff_column);
-PL_instantiate(Staff);
-PL_instantiate(Voice_element);
-PL_instantiate(Voice);
-
-
+++ /dev/null
-#include "request.hh"
-#include "command.hh"
-#include "molecule.hh"
-#include "list.cc"
-#include "plist.cc"
-#include "cursor.cc"
-PL_instantiate(Atom);
-PL_instantiate(Command);
-PL_instantiate(Request);
-
-
-
+++ /dev/null
-#include "dimen.hh"
-#include "tex.hh"
-#include "symbol.hh"
-#include "const.hh"
-
-String
-vstrut(Real h)
-{
- return String("\\vrule height ") + print_dimen(h) + "depth 0pt width 0pt";
-}
-
-
-static void
-substitute_arg(String& r, String arg)
-{
- int p = r.pos('%');
- if (!p ) return ;
- else p--;
- r = r.left(p) + arg + r.right(r.len() - p -1);
-}
-
-
-String
-substitute_args(String source, svec<String> args)
-{
- String retval (source);
- for (int i = 0 ; i < args.sz(); i++)
- substitute_arg(retval, args[i]);
- while (retval.pos('%'))
- substitute_arg(retval, "");
- return retval;
-}
+++ /dev/null
-#ifndef TEX_HH
-#define TEX_HH
-
-#include "string.hh"
-#include "boxes.hh"
-
-/// parameter substitution in TeXstrings
-String
-substitute_args(String source, svec<String> args);
-/**
- this structure provides a simple macro mechanism:
-
- if source == "tex%bla%", then
- eval({"X","Y"}) == "texXblaY"
- */
-
-/// #h# is in points
-String vstrut(Real h);
-
-
-#endif
+++ /dev/null
-#include <fstream.h>
-#include <time.h>
-#include "tex.hh"
-#include "main.hh"
-#include "tstream.hh"
-#include "debug.hh"
-
-Tex_stream::Tex_stream(String filename)
-{
- os = new ofstream(filename);
- if (!*os)
- error("can't open `" + filename+"\'");
- nest_level = 0;
- outputting_comment=false;
- header();
-}
-void
-Tex_stream::header()
-{
- *os << "% Creator: " << get_version();
- *os << "% Automatically generated, at ";
- time_t t(time(0));
- *os << ctime(&t);
-//*os << "% from input file ..\n";
-}
-Tex_stream::~Tex_stream()
-{
- delete os;
- assert(nest_level == 0);
-}
-
-// print string. don't forget indent.
-Tex_stream &
-Tex_stream::operator<<(String s)
-{
-
- for (const char *cp = s; *cp; cp++) {
- if (outputting_comment) {
- *os << *cp;
- if (*cp == '\n') {
- outputting_comment=false;
-
- }
- continue;
- }
- switch(*cp)
- {
- case '%':
- outputting_comment = true;
- *os << *cp;
- break;
- case '{':
- nest_level++;
- *os << *cp;
- break;
- case '}':
- nest_level--;
- *os << *cp;
- assert (nest_level >= 0);
- /* FALTHROUGH */
-
- case '\n':
- *os << "%\n";
- *os << String(' ', nest_level);
- break;
- default:
- *os << *cp;
- break;
- }
- }
- return *this;
-}
-
-
-/****************************************************************/
+++ /dev/null
-#ifndef TSTREAM__HH
-#define TSTREAM__HH
-
-#include <iostream.h>
-#include "string.hh"
-
-/// TeX output
-struct Tex_stream {
- bool outputting_comment;
- ostream *os;
- int nest_level;
-
- /// open a file for writing
- Tex_stream(String filename);
- void header();
- /// delegate conversion to string class.
- Tex_stream &operator<<(String);
-
- /// close the file
- ~Tex_stream();
-};
-/**
- Use this class for writing to a TeX file.
- It counts braces to prevent nesting errors, and
- it will add a comment sign before each newline.
- */
-#endif
+++ /dev/null
-#include "version.hh"
-
-static char *s = "LilyPond version " VERSIONSTR " compiled on " __DATE__ " at " __TIME__ "\n";
-
-const char *
-get_version()
-{
- return s;
-}
+++ /dev/null
-#include "debug.hh"
-#include "voice.hh"
-
-Voice::Voice(Voice const&src)
-{
- PL_copy(elts, src.elts);
- start = src.start;
-}
-
-Voice::Voice()
-{
- start = 0.0;
-}
-
-void
-Voice::add(Voice_element*v)
-{
- elts.bottom().add(v);
-}
-
-void
-Voice::print() const
-{
- #ifndef NPRINT
-
- mtor << "start: "<< start<<eol;
- for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
- vec->print();
-#endif
-}
-
-Real
-Voice::last() const
-{
- Real l =start;
- for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
- l += vec->duration;
- return l;
-}
-/****************************************************************/
-void
-Voice_element::print() const
-{
-#ifndef NPRINT
- mtor << "voice_element { dur :"<< duration <<"\n";
- for (PCursor<Request*> rc(reqs); rc.ok(); rc++) {
- rc->print();
- }
- mtor << "}\n";
-#endif
-}
-void
-Voice_element::add(Request*r)
-{
- if (r->rhythmic()) {
- assert (!duration);
- duration = r->duration();
- }
- reqs.bottom().add(r);
-}
-
-
-Voice_element::Voice_element()
-{
- voice = 0;
- group = 0;
- duration = 0.0;
-}
-
-Voice_element::Voice_element(Voice_element const&src)
-{
- duration=src.duration;
- voice=src.voice;
- PointerList__copy(Request*, reqs, src.reqs, clone());
- group=src.group;
- assert(!granted_items.size() && !granted_spanners.size());
-}
+++ /dev/null
-#ifndef VOICE_HH
-#define VOICE_HH
-
-
-#include "plist.hh"
-#include "request.hh"
-
-/// class for horizontal stuff.
-struct Voice {
- PointerList<Voice_element *> elts;
- Real start;
-
- /****************/
- Real when(const Voice_element*)const;
- Real last() const;
- Voice();
- Voice(Voice const&);
- void add(Voice_element*);
- void print() const;
-};
-/**
-
- Voice is a ordered row of Voice_elements. It is strictly horizontal:
- you cannot have two rhythmic elements running parallel in a Voice
-
- */
-
-struct Voicegroup {
- /// don't know how to identify these.
-};
-
-/// one horizontal bit.
-struct Voice_element {
- Real duration;
- const Voicegroup *group;
- const Voice *voice;
- PointerList<Request*> reqs;
-
- List<const Item *> granted_items;
- List<const Spanner *> granted_spanners;
-
- /****************/
-
- void add(Request*);
- Voice_element();
- Voice_element(Voice_element const & src );
- void print ()const;
-};
-/** Apart from being a container for the requests, Voice_element is
- glue between related items and spanners, between requests and
- (voice)groups
- */
-#endif
+++ /dev/null
-#include "debug.hh"
- ostream &warnout (cerr);
- ostream *mlog(&cerr);
-
-
-
-void warning(String s)
-{
- WARN << s;
-}
-
-
-void error(String s)
-{
- cerr << "\n" << s << "\nexiting..\n";
- exit(1);
-}
-