Rhythmic_req 1
Rest_req 1
delete_identifiers 1
+Staff 0
+Voice 0
+Voice_element 0
+Request 1
+Input_cursor 1
\ No newline at end of file
PREREQUISITES
-TeX, the MusixTeX fonts, g++ > v2.7. The "flower" library, which should be
-available from the same source you got this from.
+TeX, the MusixTeX fonts, g++ > v2.7. The "flower" library, which
+should be available from the same source you got this from. The
+Makefile uses perl for trivial operation, but you could tinker with it
+to use sed or awk.
COMPILING
HOW DOES IT WORK
* Use The Source, Luke. If you don't know C++, you can try editing
-.dstreamrc for copious debugging output.
+.dstreamrc for copious debugging output. (use -d)
* the subdir Documentation/ contains some in depth matter on LilyPond
algorithms
parseconstruct.hh debug.hh globvars.hh keyword.hh\
misc.hh score.hh notename.hh lexer.hh symtable.hh\
symbol.hh main.hh dimen.hh paper.hh lookup.hh\
- sccol.hh stcol.hh scommands.hh melodicstaff.hh\
+ sccol.hh stcol.hh staffcommands.hh melodicstaff.hh\
identifier.hh simplestaff.hh spanner.hh stem.hh\
notehead.hh leastsquares.hh beam.hh rest.hh\
swalker.hh bar.hh meter.hh accidental.hh\
key.hh keyitem.hh localkeyitem.hh simplewalker.hh\
- clef.hh clefitem.hh slur.hh
+ clef.hh clefitem.hh slur.hh inputcommands.hh\
+ getcommand.hh inputmusic.hh
mycc= qlp.cc qlpsolve.cc \
break.cc linespace.cc molecule.cc staffline.cc\
warn.cc debug.cc symtable.cc boxes.cc\
pstaff.cc tstream.cc\
calcideal.cc scores.cc identifier.cc \
- dimen.cc paper.cc lookup.cc scommands.cc\
+ dimen.cc paper.cc lookup.cc staffcommands.cc\
sccol.cc stcol.cc getcommands.cc simplestaff.cc\
melodicstaff.cc simpleprint.cc stem.cc\
spanner.cc notehead.cc leastsquares.cc beam.cc\
simplewalker.cc bar.cc meter.cc accidental.cc\
key.cc keyitem.cc localkeyitem.cc\
clef.cc clefitem.cc texslur.cc slur.cc\
+ inputcommands.cc inputmusic.cc\
+ inputcursor.cc\
template1.cc template2.cc template3.cc template4.cc\
version.cc
+
+
+
# version info
MAJVER=0
MINVER=0
-PATCHLEVEL=11
+PATCHLEVEL=13
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
# directories
# distribution files.
othersrc=lexer.l parser.y
SCRIPTS=make_version make_patch genheader
-IFILES=dimen.tex symbol.ini kortjakje.ly maartje.ly\
+IFILES=dimen.tex symbol.ini kortjakje.ly pavane.ly maartje.ly\
lilyponddefs.tex test.tex .dstreamrc
OFILES=Makefile Variables.make Sources.make COPYING README
DFILES=$(OFILES) $(IFILES) $(SCRIPTS)
\font\musicfnt=musix20
-%\def\mb#1{{\musicfnt\musicfnt\char#1}}
-\font\slurfont=xslhz20
-\def\mb#1{{\musicfnt\slurfont\char#1}}
+\font\slurfont=xslhu20
+\def\thefont{\musicfnt}
+
+\def\mb#1{{\thefont\char#1}}
+
\newdimen\wid
\newdimen\inc
\newdimen\here
MAJVER=1
MINVER=0
-PATCHLEVEL=12
+PATCHLEVEL=13
PACKAGENAME=flower
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
findcurs.hh unionfind.hh compare.hh handle.hh matrix.hh\
smat.hh vsmat.hh vector.hh real.hh choleski.hh\
tsmat.hh tvsmat.hh plist.hh associter.hh fproto.hh\
- interval.hh scalar.hh
+ interval.hh scalar.hh sstack.hh
struct Assoc_iter {
int i;
Assoc<K,V> &assoc_;
-
- Assoc_iter(Assoc<K,V> &a) :
- assoc_(a)
+ /// we don't want to be bothered by const correctness
+ Assoc_iter(const Assoc<K,V> &a) :
+ assoc_((Assoc<K,V> &)a)
{
i= next(0);
}
#ifndef COMPARE_HH
#define COMPARE_HH
+#define one_operator(type, function, op) \
+inline bool \
+operator op (type t1, type t2) {\
+ return function(t1, t2) op 0;\
+}\
-#define one_operator(type, function, op) \
-inline bool operator op (type t1, type t2) { return function(t1, t2) op 0; }
+#define gpp_minmax_operator(type, op, opp) \
+inline type \
+operator op(type t1, type t2)\
+{\
+ return (t1 opp t2) ? t1 : t2;\
+}\
+
+#ifdef __GNUC__
+#define gpp_minmax(type, prefix)\
+ prefix gpp_minmax_operator(type, <?, <)\
+ prefix gpp_minmax_operator(type, >?, >)
+#else
+#define gpp_minmax(type, prefix)
+#endif
/// handy notations for a signed comparison
-#define template_instantiate_compare(type, function, prefix) \
+#define template_instantiate_compare(type, function, prefix) \
prefix one_operator(type, function, >)\
prefix one_operator(type, function, >=)\
prefix one_operator(type, function, ==)\
prefix one_operator(type, function, !=)\
prefix one_operator(type, function, <)\
prefix one_operator(type, function, <=)\
+gpp_minmax(type, prefix)\
prefix inline type MAX(type t1, type t2) { return (t1 > t2 )? t1 : t2; }\
prefix inline type MIN(type t1, type t2) { return (t1 < t2 )? t1 : t2; }\
\
void concatenate(PointerList<T> const &s) { List<void*>::concatenate(s); }
PointerList() {}
};
+/** This class does no deletion of the pointers, but it knows how to
+ copy itself (shallow copy). We could have derived it from List<T>,
+ but this design saves a lot of code dup; for all PointerLists in the
+ program only one parent List<void*> is instantiated. */
-
-/// intrusive pl. deletes pointers given to it.
+/// pl. which deletes pointers given to it.
template<class T>
struct IPointerList : public PointerList<T> {
IPointerList(IPointerList&) { set_empty(); }
};
/**
NOTE:
+
The copy constructor doesn't do what you'd want:
Since T might have a virtual ctor, we don't try to do a
--- /dev/null
+/*
+ sstack.hh -- part of Flower lib
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SSTACK_HH
+#define SSTACK_HH
+
+#include "vray.hh"
+
+/// A simple stack based on svec.
+template<class T>
+struct sstack : svec<T> {
+ T top() { return last(); }
+ T pop() {
+ assert(!empty());
+ T l = last();
+ svec<T>::pop();
+ return l;
+ }
+ void push(T l) { add(l); }
+};
+/**
+ Same as for #svec# goes here.
+*/
+
+
+#endif // SSTACK_HH
+
#include <stdio.h>
#include <ctype.h>
-
-//#include "globals.hh"
#include "string.hh"
-#include "vray.hh"
+#include "sstack.hh"
/// line counting input stream.
class Text_stream
*/
-/// A simple stack based on svec.
-template<class T>
-class sstack : svec<T> {
- public:
- T top() { return last(); }
- T pop() {
- assert(!empty());
- T l = last();
- svec<T>::pop();
- return l;
- }
- void push(T l) { add(l); }
- bool empty() { return svec<T>::empty(); }
-};
-/**
- Same as for #svec# goes here.
-*/
#endif
struct Clef_item : Item {
String type;
int y_off;
+ bool change;
+
Clef_item();
void read(Clef);
#include <assert.h>
#include <iostream.h>
#include "dstream.hh"
+#include "real.hh"
void error(String s); // errors
-
+void error_t(String s, Real when);
// warnings
void warning(String s);
#define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
#ifdef NPRINT
#define mtor if (0) monitor // clever hack
#else
-#define mtor monitor.identify_as(__PRETTY_FUNCTION__)
+#define mtor if (check_debug) monitor.identify_as(__PRETTY_FUNCTION__)
#endif
+extern bool check_debug;
#endif
--- /dev/null
+Command*get_clef_interpret_command(String w);
+Command *get_bar_command(Real);
+Command* get_meterchange_command( int,int);
+Command* get_meter_command( Real,int,int);
+Command* get_skip_command( int,Real);
+Command* get_key_interpret_command(svec<String>);
+Command *get_reset_command();
+Command*get_partial_command(Real u);
Identifier(String n) ;
virtual ~Identifier();
virtual Staff * staff() { assert(false); }
- virtual Voice * voice() { assert(false); }
+ virtual Voice_list * voices() { assert(false); }
};
struct Staff_id : Identifier {
~Staff_id();
};
-struct Voice_id : Identifier {
- Voice_id(String s, Voice*st):Identifier(s) { data = st; }
- virtual Voice * voice() { return (Voice*)data; }
- ~Voice_id();
+struct Voices_id : Identifier {
+ Voices_id(String s, Voice_list*st):Identifier(s) { data = st; }
+ virtual Voice_list * voices() { return (Voice_list*)data; }
+ ~Voices_id();
};
#endif // IDENTIFIER_HH
--- /dev/null
+/*
+ inputcommands.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTCOMMANDS_HH
+#define INPUTCOMMANDS_HH
+#include "pcursor.hh"
+#include "proto.hh"
+#include "plist.hh"
+#include "real.hh"
+
+struct Input_cursor : public PCursor<Command*>
+{
+ /// current measure info
+ Real whole_per_measure;
+
+ /// where am i
+ Real whole_in_measure;
+
+ /// Real last when which was read
+ Real last;
+
+ int bars;
+
+ Input_cursor(PCursor<Command*>);
+ /// hmm. not safe. Should rethink cursor.
+ void operator++(int);
+ /** warning: no optor -- () defined.. */
+ void reset();
+ Real when()const;
+ void add(Command*);
+ void setpartial(Real);
+ void addbot(Command*);
+ void sync();
+ void print()const;
+ void last_command_here();
+};
+
+/// the list of commands in Score
+struct Input_commands : public IPointerList<Command*> {
+ Input_cursor ptr;
+
+ /****************/
+
+ void find_moment(Real);
+ void do_skip(int & bars, Real & wholes);
+ void truncate(Real);
+
+ Input_commands();
+ Input_commands(Input_commands const&);
+ void add(Command*);
+ void reset();
+ void print()const;
+ Staff_commands *parse() const;
+};
+
+
+void
+interpret_meter(Command *c, int &beats_per_meas, int& one_beat,
+ Real& whole_per_measure);
+#endif // INPUTCOMMANDS_HH
+
--- /dev/null
+/*
+ inputmusic.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTMUSIC_HH
+#define INPUTMUSIC_HH
+
+#include "plist.hh"
+#include "proto.hh"
+
+struct Voice_list : public PointerList<Voice*> {
+ void translate_time(Real dt);
+ /// delete stuff; not in destructor!
+ void junk();
+};
+
+struct Vertical_music {
+ virtual Vertical_simple *simple() { return 0;}
+ virtual Voice_list convert()=0;
+ virtual Real length()=0;
+ virtual void translate_time(Real dt)=0;
+};
+
+struct Horizontal_music {
+ virtual Voice_list convert()=0;
+ virtual Real length()=0;
+ virtual void translate_time(Real dt)=0;
+};
+
+struct Horizontal_simple : Horizontal_music {
+ Voice * voice_;
+
+ /****************/
+
+ Horizontal_simple();
+ void set(Voice*);
+ virtual Real length();
+ virtual Voice_list convert();
+ virtual void translate_time(Real dt);
+
+};
+
+struct Vertical_simple : Vertical_music {
+ Voice * voice_;
+
+ /****************/
+ Vertical_simple();
+ void add(Voice_element*);
+ virtual Vertical_simple*simple() { return this; }
+ virtual Real length();
+ virtual Voice_list convert();
+ virtual void translate_time(Real dt);
+};
+
+struct Music_voice : Horizontal_music {
+ PointerList<Vertical_music*> voice_ ;
+
+ /****************/
+
+ Real length();
+ void add(Vertical_music*);
+ void add(Voice_element*);
+ virtual Voice_list convert();
+ virtual void translate_time(Real dt);
+};
+
+struct Music_general_chord : Vertical_music {
+ PointerList<Horizontal_music*> chord_;
+
+ /****************/
+ void add(Horizontal_music*);
+ virtual Real length();
+ virtual Voice_list convert();
+ virtual void translate_time(Real dt);
+};
+
+
+#endif // INPUTMUSIC_HH
bool close_input();
int yylex();
void yyerror(const char *s);
-
+bool busy_parsing();
int lookup_keyword(String s);
Identifier* lookup_identifier(String s);
/****************/
- Symbol get_stafsym(Real width)const;
+ void brew_molecule(Real width);
Linestaff(int, PScore*);
};
/****************/
Real internote();
void parse (Text_db&t);
- Parametric_symbol *linestaff(int n);
+ Symbol linestaff(int n, Real w);
Symbol beam_element(int,int,Real=0);
/// round slope to closest TeXslope
#include "proto.hh"
void debug_init();
+void set_debug(bool);
void do_scores();
void add_score(Score * s);
void set_default_output(String s);
/****************/
+ virtual Rest *get_rest(Rest_req *rq);
virtual void set_output(PScore *);
virtual Melodic_staff*clone()const;
virtual Item* get_TYPESET_item(Command*);
#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;
}
Box extent() const;
Atom(Symbol s);
- void print() const;
+ void print() const;
String TeXstring() const;
};
struct Molecule {
IPointerList<Atom*> ats;
+ /****************/
+
Molecule() { }
Molecule(Atom a) { add(a) ; }
struct Notehead : public Item
{
int position;
+
+ /// needed for the help-lines
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();
};
#include "proto.hh"
-template<class T>
-struct svec;
-
void set_default_duration(String);
void set_default_pitch(String);
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();
void add_requests( Voice_element*v, svec<Request*>&req);
-Command* get_meterchange_command( int,int);
-Command* get_meter_command( Real,int,int);
-Command* get_skip_command( int,Real);
-Command* get_key_interpret_command(svec<String>);
Request* get_request(char);
-Command*get_clef_interpret_command(String w);
+
+
/*
proto.hh -- part of LilyPond
#ifndef PROTO_HH
#define PROTO_HH
+
+#include "fproto.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 Absdynamic_req;
+struct Accidental;
+struct Atom;
+struct Beam;
+struct Beam_req;
struct Box;
-struct PCol;
+struct Bracket_req;
+struct Chord;
+struct Clef;
+struct Clef_item;
+struct Colinfo;
+struct Command;
+struct Cresc_req;
+struct Decresc_req;
+struct Dynamic;
struct Idealspacing;
-struct Spanner;
+struct Identifier;
+struct Input_commands;
+struct Interval;
struct Item;
+struct Key;
+struct Keyitem;
+struct Keyword;
+struct Line_of_score;
struct Line_of_staff;
-struct Colinfo;
struct Linestaff;
-struct Atom;
+struct Local_key;
+struct Local_key_item;
+struct Lookup;
+struct Lyric_req;
+struct Mixed_qp;
struct Molecule;
+struct Note_req;
+struct Notehead;
+struct Offset;
+struct Output;
+struct PCol;
struct PScore;
+struct PStaff;
+struct Paperdef;
+struct Parametric_symbol;
struct Request;
-struct Note_req;
-struct Lyric_req;
-struct Script_req;
+struct Rest;
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 Score_column;
+struct Staff_commands;
+struct Script_req;
+struct Slur;
+struct Slur_req;
+struct Span_req;
+struct Spanner;
struct Staff;
-struct Command;
+struct Staff_column;
+struct Stem;
+struct Stem_req;
+struct String;
struct Symbol;
-struct Output;
+struct Symtable;
+struct Symtables;
+struct Tex_stream;
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;
-struct Stem;
-struct Notehead;
-struct Beam;
-struct Rest;
-struct Accidental;
-struct Key;
-struct Local_key;
-struct Keyitem;
-struct Local_key_item;
-struct Clef;
-struct Clef_item;
-struct Slur;
-#endif // PROTO_HH
+struct Voicegroup;
+struct Voice_list;
+struct Vertical_music;
+struct Horizontal_music;
+struct Horizontal_simple;
+struct Vertical_simple ;
+struct Music_voice;
+struct Music_general_chord;
+
+#endif // PROTO_HH
#include "item.hh"
#include "symbol.hh"
-/// items grouped vertically.
+/// items grouped horizontally
struct PStaff {
- Parametric_symbol *stafsym;
+ Molecule * stafsym;
PScore * pscore_;
PointerList<Item*> its;
/****************/
- virtual Symbol get_stafsym(Real width)const=0; // maybe overkill
+ virtual void brew_molecule(Real width)=0; // maybe overkill
void add(Item*i);
PStaff(PScore*);
- virtual ~PStaff() {}
+ virtual ~PStaff();
};
#endif
+++ /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"
-
-/// the list of commands in Score
-struct Score_commands : public IPointerList<Command*> {
- void process_add(Command);
- Score_commands*parse(Real last)const;
- void parser_add(Command*);
- void add_seq(svec<Command>,bool);
- 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.
-
- This class serves two purposes: it stores the commands (via
- parser_add()) in the yacc parser. at a later stage, some 'high
- level' commands are converted (method: parse())
- */
-
-#endif
-
/// paper_, staffs_ and commands_ form the problem definition.
Paperdef *paper_;
IPointerList<Staff*> staffs_;
- Score_commands *commands_;
+
+ svec<Command*> input_commands_;
/// "runtime" fields for setting up spacing
IPointerList<Score_column*> cols_;
PScore *pscore_;
/****************************************************************/
-
+ void add(svec<Command*> &s);
+
/// 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);
+ PCursor<Score_column *> find_col(Real,bool);
void process();
void output(String fn);
PCursor<Score_column*> create_cols(Real);
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);
+ void do_connect(PCol *c1, PCol *c2, Real d,Real);
+ void connect(PCol* c1, PCol *c2, Real d,Real = 1.0);
+
/// add #Idealspacings# to #pscore_#
void calc_idealspacing();
/** add the score wide commands (bars, breaks) to each staff so
PScore * pscore_; // needed to generate staffs
/****************/
-
+ void process() ;
Line_of_score(svec<const PCol *> sv, PScore *);
String TeXstring() const;
#ifndef STAFF_HH
#define STAFF_HH
-#include "score.hh"
-#include "voice.hh"
-#include "command.hh"
+#include "staffcommands.hh"
/// base class for a collection of voices.
IPointerList<Voice*> voices;
/// commands in chronological order
- IPointerList<Command *> commands;
-
+ Staff_commands *staff_commands_;
+
/// runtime field
IPointerList<Staff_column*> cols;
Score *score_;
PScore *pscore_;
+ svec<Command*> input_commands_;
+
/****************************************************************/
+ void add(svec<Command*> &s);
+ void add(PointerList<Voice*> &s);
+ void process_input_commands(svec<Command*> &s, Real l);
+
Staff(const Staff&src);
void add_voice(Voice *v);
void add_staff_column(Staff_column *sp);
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.
--- /dev/null
+/*
+ lilypond, (c) 1996 Han-Wen Nienhuys
+*/
+#ifndef SCORECOMMANDS_HH
+#define SCORECOMMANDS_HH
+
+#include "proto.hh"
+#include "command.hh"
+#include "vray.hh"
+#include "plist.hh"
+
+/// the list of commands in Score
+struct Staff_commands : public IPointerList<Command*> {
+ void process_add(Command);
+ void add_seq(svec<Command>,bool);
+ 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.
+
+ This class serves two purposes: it stores the commands (via
+ parser_add()) in the yacc parser. at a later stage, some 'high
+ level' commands are converted (method: parse())
+ */
+
+#endif
+
struct Line_of_staff {
Line_of_score * line_of_score_;
- const PStaff *pstaff_;
+ PStaff *pstaff_;
/****************/
String TeXstring() const;
Line_of_staff(Line_of_score*, PStaff *);
Interval height() const;
-
+ void process();
};
#endif
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
#ifndef VOICE_HH
#define VOICE_HH
-
+#include "proto.hh"
#include "plist.hh"
-#include "request.hh"
/// class for horizontal stuff.
struct Voice {
const Voice *voice_;
IPointerList<Request*> reqs;
- PointerList<const Item *> granted_items;
- PointerList<const Spanner *> granted_spanners;
-
/****************/
void add(Request*);
%
% bare bones version. (written down from memory :-)
-melodie = voice {
- $ \octave c
+melodie = $ \octave {c}
%%% theme
- c c g g a a g2 f f e e d d c2
+ c c g g a a g2 f f e e d d c2
g g f f e e d d g g f f e e d d
%%% var 1
c r8 c8 ( ) g r8 g8 ( ) a r8 a8 ( ) g r4
f r8 f8 ( ) e4 r8 e8 ( ) d4 r8 d8 ( ) c4 r4
- $
-}
+$
-begeleiding = voice {
- $ \octave `c
+begeleiding = $
+ \octave {`c}
%%% theme
`c c e c f c e c d `b c `a `f `g `c2
- \octave `c
+ \octave {`c}
e `g d `g c `g `b `g e `g d `g c `g `b `g
%%%% var 1
r8 e8() c r8 e8() c r8 f8()c r8 e8()c
r8 d8()`b r8 c8()`a r8 `a8()`f r8 `e8()`c
- $
-}
+$
-score {
- melodicstaff {
- voice { melodie }
+bstaf = melodicstaff {
+ voices { begeleiding }
+ commands {
+ clef bass
+ }
}
- melodicstaff {
- voice { begeleiding }
+vstaf = melodicstaff {
+ voices { melodie }
}
+
+
+score {
+ staff { vstaf }
+ staff { bstaf }
paper {
- unitspace 2.5cm
+% unitspace 2.5cm
}
commands {
- meter 2 4
- clef bass
- skip 2:0
- clef violin
-% skip 2:0
+ meter 2 4
skip 32:0
}
}
\mdef\doubledot{'01}
\mdef\tripledot{'02}
\mdef\mussepline{155}
+
\mdef\violinclef{71}
\mdef\bassclef{73}
+\mdef\cviolinclef{72}
+\mdef\cbassclef{74}
\mdef\deigthflag{45}
\mdef\dsixteenthflag{46}
ritme = rhythmstaff {
- voice { $ c2 c2
+ $
+ c8 c2 c2
%[c8( )'a8 c8 c8]
c2 c2
[fis16 'dis16( fis16 'dis16 ][fis16) 'dis16 fis16 'dis16]
- c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
+ c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $
}
melody=
melodicstaff {
- voice { $ c () `bes $ start 0.5 }
- voice { $
- %[fis16 'dis16 fis16 'dis16 fis16 'dis16 fis16 'dis16]
- c2
- 'fis ()'gisis $ }
+ $
+ c8
+ r1
+ 'cis2.. r8
+ r4 r8 r16 r32 r32
+ \duration {4} \chord {
+ \voice { c () `bes c}
+ \voice {'fis ()'gisis fis }
+ \voice { d () d dis }
+ \voice { a () bes eis }
+ \voice { fis () g gis }
+ }
+ c4
- voice { $ d () d $ start 0.5 }
- voice { $ a () bes $ start 0.5 }
- voice { $ fis () g $ start 0.5 }
-
-
- voice { $
- ''c2.. r8 r4 r8 r16 r32 r32
- [d8 e8 'f8 g8] [d8 e8 f8 g8]
- ''fis1
+ [d8 e8 'f8 g8] d8 e8 f8 g8
+ ''fis2
a8 b8 'c8 'd8 ''c8 ```c8 c4 c4 c4 c4
- \duration 16 `b16 `a16 `g16 `f16 \duration 4
- c `b `a `g `f `e `d `c ``b ``a ``g ``f ``e ``d ``c$
- start 1.0 }
+ \duration{ 16 } `b `a `g `f \duration{ 4}
+ c `b `a `g `f `e `d `c ``b ``a ``g ``f ``e ``d ``c
+ $
+
+
+commands {
+ skip 2:0
+ key $ fis cis gis $
+ skip 2:0
+ key $ $
+ skip 5:0
+ clef bass
+}
}
+
score {
paper {
geometric 1.4
staff { melody }
% staff { melody }
commands {
+ partial 0.125 skip 0:0.125
+
meter 4 4
- key $ fis cis gis $
- skip 2:0
- key $ $
+ skip 2:0
meter 2 4
skip 19:0
}
--- /dev/null
+% pavane pour une Infante d\'efunte
+%
+% M. Ravel
+%
+% (Ravel has been dead for over 50 years. This does not have copyright)
+%
+
+horn = melodicstaff {
+ $
+ \octave { 'c }
+ \duration { 8}
+
+% 1
+ d2( [)d e cis `b] `a4 [`b cis] [cis `b] `b4
+ fis2( [)fis g e d] cis4 [d e(] [)e fis d cis]
+ `b4 [cis d(] [)d e cis `b] cis2 r2
+ r4 fis2 fis4 fis2()[fis e a fis]
+ fis4 e4 d4 e4 `b2()[`b `a( d cis]
+% 11
+ )`b [`fis `a `b] cis4 `b4 `fis2 r2
+ cis4 d4()[d cis d e]
+\octave { c }
+ a4 gis2.
+ a4 b4()[b a b cis] fis4 e4 cis2
+ e4 fis4 () [fis e fis gis] cis4 `b4()`b8 r8 r4
+
+ r4 r4 'cis4 'd4 () ['d 'cis 'd 'e]
+ a4 gis2. a4 b4()[b a b cis]
+ fis4 e4 cis2 e4 fis4()[fis e fis gis]
+ cis4 `b4()`b8 r8 r4 r1
+ r2 r4 r4
+%% cut 'n paste.
+ \octave { 'c }
+ d2( [)d e cis `b] `a4 [`b cis] [cis `b] `b4
+ fis2( [)fis g e d] cis4 [d e(] [)e fis d cis]
+ `b4 [cis d(] [)d e cis `b] cis2 r2
+ r4 fis2 fis4 fis2()[fis e a fis]
+ fis4 e4 d4 e4 `b2() [`b `a d cis]
+ `b [`fis `a `b] cis4 `b4 `fis2 r2
+ $
+ commands {
+ key $fis cis $
+ }
+}
+
+score {
+ staff { horn }
+ paper { unitspace 2.2 cm
+ geometric 1.5
+ }
+ commands { meter 4 4
+ skip 18:0
+ meter 2 4
+ skip 1:0
+ meter 4 4
+ skip 20:0
+ }
+}
\ No newline at end of file
left_pos *= dir;
slope *= dir;
- {
- Real inter =paper()->internote();
- Real unitslope = slope*inter;
-
- // set beamslope, for setting stems correctly
- // ignoring return.
- Symbol sy = paper()->lookup_->beam(unitslope, width().length());
- slope =unitslope / inter;
- }
}
void
set_default_dir();
solve_slope();
- set_stemlens();
}
void
{
calculate();
brew_molecule();
+ set_stemlens();
}
Real sl = slope*inter;
Real w = width().length() + paper()->rule_thickness();
Symbol s = paper()->lookup_->beam(sl,w);
-
+ slope = sl / inter;
+
Atom a(s);
Real dx = width().min -left->hpos;
#include "paper.hh"
#include "sccol.hh"
#include "debug.hh"
+#include "dimen.hh"
void
-Score::do_connect(PCol *c1, PCol *c2, Real d)
+Score::do_connect(PCol *c1, PCol *c2, Real d, Real h)
{
+ if (!c1 || !c2 )
+ return;
Idealspacing*sp=pscore_->get_spacing(c1,c2);
if (!sp->hooke){
- sp->hooke = 1.0;
+ sp->hooke = h;
sp->space =d;
}
}
void
-Score::connect_nonmus(PCol* c1, PCol *c2, Real d)
+Score::connect(PCol* c1, PCol *c2, Real d, Real h)
{
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);
- }
+ do_connect(c1,c2,d,h);
+ do_connect(c1->postbreak, c2,d,h);
+ do_connect(c1, c2->prebreak,d,h);
+ do_connect(c1->postbreak, c2->prebreak,d,h);
}
}
+
/* this needs A LOT of rethinking.
generate springs between columns.
void
Score::calc_idealspacing()
{
- PCursor<Score_column*> sc(cols_);
+ PCursor<Score_column*> i(cols_);
- for (; sc.ok(); sc++) {
- if (sc->musical)
- for (int i=0; i < sc->durations.sz(); i++) {
- Real d = sc->durations[i];
+ for (; i.ok(); i++) {
+
+ PCursor<Score_column*> j (i+1);
+ if (i->musical) {
+ for (int n=0; n < i->durations.sz(); n++) {
+ Real d = i->durations[n];
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);
+ while (d + i->when > j->when)
+ j++;
+
+ if (j->used())
+ connect(i->pcol_, j->pcol_, dist);
+ if (!j->musical && (j+1)->used && (j+1)->when == j->when) {
+ j++;
+ connect(i->pcol_, j->pcol_, dist);
+ }
+ }
+ } else if (i->used()) {
+
+ /* attach i to the next column in use. This exists, since
+ the last col is breakable, and therefore in use
+ */
+ for (;j.ok(); j++) {
+ if (j->used()) {
+ Real d = j->when - i->when;
+ Real dist = (d) ? paper_->duration_to_dist(d) :
+ convert_dimen(2,"pt");
+
+ connect(i->pcol_, j->pcol_, dist, (d) ? 1.0:1.0);
+ break;
+ }
}
- else if (sc->used()) { // ignore empty columns
- PCol * c2 = find_col(sc->when,true)->pcol_;
- connect_nonmus(sc->pcol_, c2, 0.0);
+ // !j.ok() might hold if we're at the last col.
}
}
}
Clef_item::Clef_item()
{
+ change = true;
read("violin");
}
void
void
Clef_item::preprocess()
{
- Symbol s = paper()->lookup_->clef(type);
+ String t = type;
+ if (change)
+ t += "_change";
+ Symbol s = paper()->lookup_->clef(t);
output = new Molecule(Atom(s));
output->translate(Offset(0, paper()->interline()/2 * y_off));
}
set_new_handler(&mynewhandler);
set_matrix_debug(monitor);
}
+
+bool check_debug=false;
+
+void
+set_debug(bool b)
+{
+ check_debug =b;
+}
#include "parseconstruct.hh"
#include "command.hh"
+Command*
+get_partial_command(Real u)
+{
+ Command*c = new Command;
+ c->code = INTERPRET;
+ c->args.add("PARTIAL");
+ c->args.add(u);
+ return c;
+}
+
+Command*
+get_reset_command()
+{
+ Command*c = new Command;
+ c->code = INTERPRET;
+ c->args.add("RESET");
+ return c;
+}
Command*
get_key_interpret_command(svec<String> which)
#include "identifier.hh"
#include "staff.hh"
#include "lexer.hh"
+#include "inputmusic.hh"
Identifier::Identifier(String n)
delete staff();
}
-Voice_id::~Voice_id()
+Voices_id::~Voices_id()
{
- delete voice();
+ voices()->junk();
+ delete voices();
}
--- /dev/null
+/*
+ it still sucks.
+ */
+
+#include "inputcommands.hh"
+#include "debug.hh"
+#include "staffcommands.hh"
+#include "getcommand.hh"
+#include "command.hh"
+
+Input_commands::Input_commands(Input_commands const&src)
+ : ptr(src.ptr)
+{
+ IPointerList<Command*> &me(*this);
+ const IPointerList<Command*> &that(src);
+
+ PL_copy(me, that);
+}
+
+Input_commands::Input_commands()
+ : ptr (bottom())
+{
+ Command c(0.0);
+ bottom().add(new Command(c));
+ ptr = bottom();
+}
+
+void
+Input_commands::truncate(Real last)
+{
+ bool reset_ = false;
+
+ if (ptr.when() >= last)
+ reset_=true;
+ PCursor<Command*> i(*this);
+
+ while (i.ok() && i ->when < last)
+ i++;
+
+ while (i.ok())
+ i.del();
+
+ if (reset_) {
+ reset();
+
+ while(ptr.ok())
+ ptr++;
+ }
+}
+
+/*
+ ugh. This sux.
+ */
+void
+Input_commands::find_moment(Real w)
+{
+ assert(w >= ptr.when());
+ while (ptr.ok() && ptr.when() < w) {
+ ptr++;
+ }
+
+ if (!ptr.ok()) {
+ int bars_left =int(floor( (w - ptr.last + ptr.whole_in_measure)
+ /ptr.whole_per_measure));
+ if (bars_left) {
+ Real bar_when = ptr.last - ptr.whole_in_measure + ptr.whole_per_measure;
+ ptr.addbot(get_bar_command(bar_when));
+ find_moment(w); // tail-recursion. todo
+ } else {
+ ptr.addbot(new Command(w));
+ }
+
+ } else if (ptr.when() != w) {
+ ptr.insert(new Command(w));
+ ptr--;
+ }
+}
+
+void
+Input_commands::do_skip(int & bars, Real & wholes)
+{
+ if (wholes) {
+ find_moment(ptr.when() +wholes);
+ wholes = 0.0;
+ }
+
+ if (bars) {
+ ptr.last_command_here(); // find any METER change commands.
+ if (ptr.whole_in_measure){
+ Real barleft = ptr.whole_per_measure - ptr.whole_in_measure;
+ do_skip(bars, barleft);
+ }else {
+ find_moment(ptr.when() + bars*ptr.whole_per_measure);
+ bars = 0;
+ }
+ }
+}
+
+
+void
+Input_commands::add(Command *c)
+{
+ assert(c->code==INTERPRET);
+ if (c->args[0] == "PARTIAL") {
+ Real p = c->args[1].fvalue();
+ ptr.setpartial(p);
+
+ } else if (c->args[0] == "METER") {
+ int beats_per_meas, one_beat;
+ Real r;
+
+ interpret_meter(c, beats_per_meas, one_beat, r);
+ Command *ch = get_meterchange_command(beats_per_meas, one_beat);
+ ch->when = ptr.when();
+ ptr.add(ch);
+
+ delete c;
+
+ } else if (c->args[0] == "KEY" || c->args[0] == "CLEF") {
+ c->when = ptr.when();
+ ptr.add(c);
+ } else if (c->args[0] == "SKIP") {
+ int bars = c->args[1].value() ;
+ Real wholes= c->args[2].fvalue();
+ while (bars > 0 || wholes > 0.0) {
+ do_skip(bars, wholes);
+ }
+ delete c;
+ } else if (c->args[0] == "RESET") {
+ delete c;
+
+ reset();
+ }
+
+}
+
+void
+Input_commands::reset()
+{
+ ptr = top();
+ ptr.reset();
+}
+
+
+Staff_commands*
+Input_commands::parse() const
+{
+ Staff_commands*nc = new Staff_commands;
+
+ { /* all pieces should start with a breakable. */
+ Command c(0.0);
+ c.code = INTERPRET;
+ c.args.add("BAR");
+ c.args.add("empty");
+ nc->process_add(c);
+ }
+
+ for (PCursor<Command*> cc(*this); cc.ok(); cc++) {
+ if (cc->code != NOP)
+ nc->process_add(**cc);
+ }
+
+ return nc;
+}
+
+
+void
+Input_commands::print() const
+{
+#ifndef NPRINT
+ for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
+ cc->print();
+ }
+ ptr.print();
+#endif
+}
--- /dev/null
+/*
+ it still sucks.
+ */
+
+#include "inputcommands.hh"
+#include "debug.hh"
+#include "staffcommands.hh"
+#include "getcommand.hh"
+#include "command.hh"
+
+void
+interpret_meter(Command *c, int &beats_per_meas, int& one_beat,
+ Real& whole_per_measure)
+{
+ beats_per_meas = c->args[1].value();
+ one_beat = c->args[2].value();
+ whole_per_measure = beats_per_meas/Real(one_beat);
+}
+
+Real
+Input_cursor::when()const
+{
+ return (*this)->when;
+}
+
+void
+Input_cursor::print() const
+{
+#ifndef NPRINT
+ mtor << "meter " << whole_per_measure
+ << " pos "<< bars << ":" << whole_in_measure <<'\n';
+#endif
+}
+
+void
+Input_cursor::reset()
+{
+ whole_per_measure = 1.0; // ?
+ whole_in_measure =0.0;
+ bars = 0;
+ last=0;
+}
+
+Input_cursor :: Input_cursor(PCursor<Command*>c)
+ :PCursor<Command*>(c)
+{
+ reset();
+}
+
+void
+Input_cursor::sync()
+{
+ assert(ok());
+
+ whole_in_measure += when() - last;
+ while (whole_per_measure > 0 && whole_in_measure >= whole_per_measure) {
+ bars ++;
+ whole_in_measure -= whole_per_measure;
+ }
+ if (whole_in_measure < 1e-5) // ugr
+ whole_in_measure = 0.0;
+}
+
+void
+Input_cursor::operator++(int)
+{
+ last = when();
+ (*(PCursor<Command*> *) this) ++;
+
+ if (ok()) {
+ sync();
+ if (ptr()->code == INTERPRET && ptr()->args[0] == "METER") {
+ int i,j;
+ interpret_meter(ptr(), i, j, whole_per_measure);
+ }
+ }
+}
+
+void
+Input_cursor::addbot(Command*c)
+{
+ assert(!ok());
+ add(c);
+}
+
+
+void
+Input_cursor::add(Command*c)
+{
+ PCursor<Command*> ::add(c);
+ (*this)++;
+}
+
+void
+Input_cursor::last_command_here()
+{
+ assert(ok());
+ PCursor<Command*> next = (*this)+1;
+ while (next.ok() && next->when == when()){
+ *this = next;
+ next = *this +1;
+
+ }
+}
+
+void
+Input_cursor::setpartial(Real p)
+{
+ if (when())
+ error_t ("Partial measure only allowed at beginning.", when() );
+ if (p<0||p > whole_per_measure)
+ error_t ("Partial measure has incorrect size", when());
+
+ whole_in_measure = whole_per_measure - p;
+}
--- /dev/null
+#include "inputmusic.hh"
+#include "voice.hh"
+
+Vertical_simple::Vertical_simple()
+{
+ voice_ = new Voice;
+}
+
+void
+Vertical_simple::add(Voice_element*v)
+{
+ voice_->add(v);
+}
+
+Real
+Vertical_simple::length()
+{
+ return voice_->last();
+}
+void
+Vertical_simple::translate_time(Real t)
+{
+ voice_->start += t;
+}
+Voice_list
+Vertical_simple::convert()
+{
+ Voice_list l;
+ l.bottom().add(voice_);
+ return l;
+}
+
+
+/****************/
+
+void
+Music_voice::add(Voice_element*v)
+{
+ PCursor<Vertical_music*> c(voice_.bottom());
+ if (!c.ok() || !c->simple()) {
+ Vertical_simple*vs = new Vertical_simple;
+
+ c.add(vs);
+ }
+
+ c = voice_.bottom();
+ Vertical_simple *s = c->simple();
+ s->add(v);
+}
+
+void
+Music_voice::add(Vertical_music*v)
+{
+ // v->translate_time(length());
+ voice_.bottom().add(v);
+}
+
+Real
+Music_voice::length()
+{
+ Real l = 0.0;
+
+ for (PCursor<Vertical_music*> i(voice_); i.ok(); i++)
+ l += i->length();
+ return l;
+}
+
+
+Voice_list
+Music_voice::convert()
+{
+ Voice_list l;
+ Real here = 0.0;
+
+ for (PCursor<Vertical_music*> i(voice_); i.ok(); i++) {
+ Real len = i->length(); // has to be stored, since translate_time doesn't work on copies of the contents of i.
+ Voice_list k(i->convert());
+ k.translate_time(here);
+ l.concatenate(k);
+ here +=len;
+
+ }
+ return l;
+}
+
+void
+Music_voice::translate_time(Real t)
+{
+ for (PCursor<Vertical_music*> i(voice_); i.ok(); i++)
+ i->translate_time(t);
+}
+
+
+
+/****************/
+
+void
+Music_general_chord::translate_time(Real t)
+{
+ for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++)
+ i->translate_time(t);
+}
+
+
+
+Real
+Music_general_chord::length()
+{
+ Real l =0.0;
+
+ for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++)
+ l = MAX(l, i->length());
+ return l;
+}
+
+void
+Music_general_chord::add(Horizontal_music*h)
+{
+ chord_.bottom().add(h);
+}
+
+Voice_list
+Music_general_chord::convert()
+{
+ Voice_list l;
+ for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++) {
+ Voice_list k(i->convert());
+ l.concatenate(k);
+ }
+ return l;
+}
+
+/****************/
+
+void
+Voice_list::translate_time(Real x)
+{
+ for (PCursor<Voice*> i(*this); i.ok(); i++)
+ i->start += x;
+}
+
+void
+Voice_list::junk()
+{
+ for (PCursor<Voice*> i(*this); i.ok(); i++)
+ delete i.ptr();
+}
}
<notes>[ \t\n]+ {
}
-<notes>%.* {
+<notes>%.*$ {
}
<notes>\$ {
BEGIN(INITIAL); return '$';
}
-<notes>[\[{)] { /* parens () are NO mistake */
+<notes>[{}] {
+ return YYText()[0];
+
+}
+<notes>[\[)] { /* parens () are NO mistake */
yylval.c = YYText()[0];
return OPEN_REQUEST_PARENS;
}
-<notes>[\]}(] { /* parens () are NO mistake */
+<notes>[\](] { /* parens () are NO mistake */
yylval.c = YYText()[0];
return CLOSE_REQUEST_PARENS;
}
yyFlexLexer *lexer=0;
+bool
+busy_parsing()
+{
+ return lexer;
+}
+
// set the new input to s, remember old file.
void
new_input(String s)
kill_lexer()
{
delete lexer;
+ lexer = 0;
}
#include "linestaff.hh"
+#include "molecule.hh"
#include "symbol.hh"
#include "lookup.hh"
#include "dimen.hh"
: 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);
+void
+Linestaff::brew_molecule(Real width)
+{
+ Atom a = pscore_->paper_->lookup_->linestaff(nolines,width);
+ stafsym = new Molecule(a);
}
+
+
+
+
+
+
+
/****************************************************************/
// 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
+Lookup::linestaff(int lines, Real wid)
{
- Real wid = w[0].fvalue();
-
Symbol s;
s.dim.x = Interval(0,wid);
- Real dy=(lines-1)*convert_dimen(5,"pt"); // TODO!
+ Real dy=(lines-1)*internote()*2;
s.dim.y = Interval(0,dy);
+
svec<String> a;
a.add(lines);
- a.add(w[0]);
+ a.add(print_dimen(wid));
+
s.tex = (*symtables_)("param")->lookup("linestaf").tex;
s.tex = substitute_args(s.tex, a);
+
return s;
}
}
-Parametric_symbol *
-Lookup::linestaff(int n)
-{
- return new Linestaf_symbol(n,symtables_);
-}
-
1, "output", 'o',
0, "warranty", 'w',
0, "help", 'h',
+ 0, "debug", 'd',
0,0,0
};
cout <<
"--help, -h This help\n"
"--warranty, -w show warranty & copyright\n"
- "--output, -o set default output\n";
+ "--output, -o set default output\n"
+ "--debug, -d enable debug output\n"
+ ;
+
}
void notice()
{
help();
exit(0);
break;
+ case 'd':
+ set_debug(true);
+ break;
default:
assert(false);
break;
#include "rhythmstaff.hh"
#include "sccol.hh"
#include "localkeyitem.hh"
+#include "request.hh"
const int NO_LINES=5;
return new Melodic_staff;
}
-
+Rest*
+Melodic_staff::get_rest(Rest_req*rq)
+{
+ Rest*r = Simple_staff::get_rest(rq);
+ if (rq->balltype <= 2)
+ r->translate(Offset(0, NO_LINES * paper()->internote()));
+ return r;
+}
Melodic_staff*
Melodic_staff::clone()const
}
-
-void
-parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
- int & large, int & small)
-{
- // octave
- oct =default_octave;
-
+void
+parse_octave (const char *a, int &j, int &oct)
+{
while (1)
- {
+ {
if (a[j] == '\'')
oct ++;
else if (a[j] == '`')
else
break;
j++;
-
- }
+ }
+}
+
+void
+parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
+ int & large, int & small)
+{
+ // octave
+ oct =default_octave;
+ parse_octave(a,j,oct);
- mtor << "oct " << oct;
+ mtor << "oct " << oct;
// accidental
overide_acc = false;
set_default_pitch(String d)
{
int i=0;
- bool b;
- int l,s;
- parse_pitch(d, i, default_octave, b, l,s);
+ default_octave=0;
+ parse_octave(d, i, default_octave);
}
Request*
#include "score.hh"
#include "main.hh"
#include "keyword.hh"
-#include "scommands.hh"
+#include "getcommand.hh"
#include "debug.hh"
#include "parseconstruct.hh"
#include "dimen.hh"
#include "identifier.hh"
+#include "inputmusic.hh"
#ifndef NDEBUG
#define YYDEBUG 1
Real real;
Command *command;
Identifier *id;
- Score_commands *scommands;
Voice *voice;
Voice_element *el;
Staff *staff;
const char *consstr;
Paperdef *paper;
Request* request;
+ Horizontal_music *horizontal;
+ Vertical_music *vertical;
+ Music_general_chord *chord;
+ Music_voice *mvoice;
int i;
char c;
+
svec<String> * strvec;
+ svec<Command*> *commandvec;
+ Voice_list *voicelist;
}
%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
%token MELODICSTAFF GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
-%token KEY CLEF VIOLIN BASS
+%token KEY CLEF VIOLIN BASS MULTI TABLE CHORD VOICES
+%token PARTIAL
%token <id> IDENTIFIER
%token <string> NEWIDENTIFIER
%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 <el> voice_elt full_element
+%type <command> score_command staff_command skipcommand
%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
+%type <commandvec> score_commands_block score_commands_body
+%type <commandvec> staff_commands_block staff_commands_body
%type <request> post_request pre_request
%type <strvec> pitch_list
%type <string> clef_id
+%type <vertical> vertical_music
+%type <chord> music_chord music_chord_body
+%type <horizontal> horizontal_music
+%type <mvoice> music_voice_body music_voice
+%type <voicelist> voices
+
%%
mudela: /* empty */
}
| mudela add_declaration { }
;
-
+/*
+ DECLARATIONS
+*/
add_declaration: declaration {
add_identifier($1);
}
$$ = new Staff_id(*$1, $3);
delete $1; // this sux
}
- | NEWIDENTIFIER '=' voice_block {
- $$ = new Voice_id(*$1, $3);
+ | NEWIDENTIFIER '=' voices {
+ $$ = new Voices_id(*$1, $3);
delete $1;
}
;
+/*
+ SCORE
+*/
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 score_commands_block {
+ $$->add(*$2);
+ delete $2;
+ }
| score_body paper_block { $$->set($2); }
;
+/*
+ COMMANDS
+*/
score_commands_block:
COMMANDS '{' score_commands_body '}' { $$ =$3;}
;
-score_commands_body: { $$ = new Score_commands; }
+score_commands_body: { $$ = new svec<Command*>; }
| score_commands_body score_command {
- $$->parser_add($2);
+ $$->add($2);
+ }
+ ;
+
+staff_commands_block: COMMANDS '{' staff_commands_body '}' {
+ $$ = $3; }
+ ;
+
+staff_commands_body:
+ /* empty */ { $$ = new svec<Command*>; }
+ | staff_commands_body staff_command {
+ $$->add($2);
}
;
+staff_command:
+ skipcommand
+ | KEY '$' pitch_list '$' {/*UGH*/
+ $$ = get_key_interpret_command(*$3);
+ delete $3;
+ }
+ | CLEF clef_id {
+ $$ = get_clef_interpret_command(*$2);
+ delete $2;
+ }
+ ;
+
+skipcommand:
+ SKIP int ':' REAL {
+ $$ = get_skip_command($2, $4);
+ }
+
+score_command:
+ skipcommand
+ | METER int int {
+ $$ = get_meterchange_command($2, $3);
+ }
+ | PARTIAL REAL {
+ $$ = get_partial_command($2);
+ }
+ ;
+
+
+/*
+ PAPER
+*/
paper_block:
PAPER '{' paper_body '}' { $$ = $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
+ STAFFs
*/
staff_block:
staffdecl
rhythmstaff_body:
/* empty */ { $$ = get_new_rhythmstaff(); }
- | rhythmstaff_body voice_block { $$->add_voice($2); }
+ | rhythmstaff_body voices { $$->add(*$2);
+ delete $2;
+ }
+ | rhythmstaff_body staff_commands_block {
+ $$->add(*$2);
+ delete $2;
+ }
;
melodicstaff_block:
melodicstaff_body:
/* empty */ { $$ = get_new_melodicstaff(); }
- | melodicstaff_body voice_block { $$->add_voice($2); }
+ | melodicstaff_body voices {
+ $$->add(*$2);
+ delete $2;
+ }
+ | melodicstaff_body staff_commands_block {
+ $$->input_commands_.add(get_reset_command());
+ $$->add(*$2);
+ delete $2;
+ }
;
-/*
- voice
-*/
-voice_block:
- VOICE '{' voice_body '}' { $$ = $3; }
+voices:
+ '$' music_voice_body '$' {
+ $$ = new Voice_list($2->convert());
+ }
+ | VOICES '{' IDENTIFIER '}' {
+ $$ = new Voice_list(*$3->voices());
+ }
+ ;
+
+
+horizontal_music:
+ music_voice { $$ = $1; }
;
+vertical_music:
+ music_chord { $$ = $1; }
+ ;
-voice_body:
- IDENTIFIER { $$ = new Voice(*$1->voice()); }
- | voice_elts_dollar { $$ = $1; }
- | voice_body START_T REAL { $$->start = $3; }
+music_voice: VOICE '{' music_voice_body '}' { $$ = $3; }
;
+music_voice_body: {
+ $$ = new Music_voice;
+ }
+ | music_voice_body full_element {
+ $$->add($2);
+ }
+ | music_voice_body voice_command {
+ }
+ | music_voice_body vertical_music {
+ $$->add($2);
+ }
+ ;
-
-voice_elts_dollar:
- '$' voice_elts '$' { $$ = $2; }
- ;
+music_chord: CHORD '{' music_chord_body '}' { $$ = $3; }
+ ;
+
+music_chord_body: {
+ $$ = new Music_general_chord;
+ }
+ | music_chord_body horizontal_music {
+ $$ -> add($2);
+ }
+ ;
-voice_elts:
- /* empty */ {
- $$ = new Voice;
- }
- | voice_elts pre_requests voice_elt post_requests {
- add_requests($3, pre_reqs);
- add_requests($3, post_reqs);
- $$->add($3);
- }
- | voice_elts voice_command { }
+
+/*
+ VOICE ELEMENTS
+*/
+full_element: pre_requests voice_elt post_requests {
+ add_requests($2, pre_reqs);
+ add_requests($2, post_reqs);
+ $$ = $2;
+ }
;
post_requests:
pre_request:
OPEN_REQUEST_PARENS { $$ = get_request($1); }
;
-/*
-*/
+
voice_command:
- DURATIONCOMMAND DURATION {
- set_default_duration(*$2);
- delete $2;
+ DURATIONCOMMAND '{' DURATION '}' {
+ set_default_duration(*$3);
+ delete $3;
}
- | OCTAVECOMMAND PITCH {
- set_default_pitch(*$2);
- delete $2;
+ | OCTAVECOMMAND '{' PITCH '}' {
+ set_default_pitch(*$3);
+ delete $3;
}
;
delete $1;
}
;
-
+/*
+ UTILITIES
+*/
pitch_list: {
$$ = new svec<String>;
}
delete $2;
}
-score_command:
- SKIP int ':' REAL {
- $$ = get_skip_command($2, $4);
- }
- | METER int int {
- $$ = get_meterchange_command($2, $3);
- }
- | KEY '$' pitch_list '$' {/*UGH*/
- $$ = get_key_interpret_command(*$3);
- delete $3;
- }
- | CLEF clef_id {
- $$ = get_clef_interpret_command(*$2);
- delete $2;
- }
-/* | PARTIALMEASURE REAL {
- $$ = get_partial_command($2);
- }*/
- ;
-
-clef_id:
- VIOLIN { $$ = new String("violin"); }
- | BASS { $$ = new String("bass"); }
- ;
int:
REAL {
$$ = int($1);
}
;
+
+dim:
+ REAL unit { $$ = convert_dimen($1,$2); }
+ ;
+
+
+unit: CM { $$ = "cm"; }
+ |IN { $$ = "in"; }
+ |MM { $$ = "mm"; }
+ |PT { $$ = "pt"; }
+ ;
+
+clef_id:
+ VIOLIN { $$ = new String("violin"); }
+ | BASS { $$ = new String("bass"); }
+ ;
%%
void
parse_file(String s)
{
*mlog << "Parsing ... ";
+
#ifdef YYDEBUG
- yydebug = !monitor.silence("Parser");
+ yydebug = !monitor.silence("Parser") & check_debug;
#endif
+
new_input(s);
yyparse();
delete_identifiers();
kill_lexer();
*mlog << "\n";
}
+
for (PCursor<Item*> ic(its); ic.ok(); ic++){
ic->postprocess();
}
+ for (PCursor<Line_of_score*> i(lines); i.ok(); i++)
+ i->process();
}
PCursor<PCol *>
#include "pstaff.hh"
+#include "molecule.hh"
+PStaff::~PStaff()
+{
+ delete stafsym;
+}
PStaff::PStaff(PScore*ps)
{
#include "molecule.hh"
+#include "score.hh"
+#include "request.hh"
#include "notehead.hh"
#include "stem.hh"
#include "linestaff.hh"
Item *
Rhythmic_staff::get_TYPESET_item(Command *com)
{
- if (com->args[0] == "KEY" || com->args[0] == "CLEF")
+ if (com->args[0] == "KEY" || com->args[0] == "CLEF"||
+ com->args[0] == "CURRENTCLEF")
return 0;
Item *i = Simple_staff::get_TYPESET_item(com);
if (!i) return 0;
+++ /dev/null
-#include "scommands.hh"
-#include "debug.hh"
-#include "parseconstruct.hh"
-
-/*
- ARG!
- */
-
-/*
- 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++;
- if (!pc.ok() || pc->when != w) {
- Command *c = new Command(w);
- c->priority = 10000;
- if (!pc.ok())
- pc.add(c);
- else
- pc.insert(c);
- }
-
- return pc;
-}
-/*
- RETURN: pc->when == w && pc.ok
- */
-
-PCursor<Command*>
-Score_commands::last_insertion(Real w)
-{
- PCursor<Command*> pc(first(w)), next(pc);
- while (next.ok() && next->when == w) {
- pc=next;
- next++;
- }
- if (pc->priority != -10000) {
- Command*c = new Command(w);
- c->priority = -10000;
- pc.add(c);
- pc++;
- }
-
- return pc;
-}
-
-/*
- */
-void
-Score_commands::add_seq(svec<Command> com, bool checkbreak)
-{
- if (!com.sz())
- return;
-
- Real when = com[0].when;
-
- PCursor<Command*> begin(first(when));
- PCursor<Command*> end(last_insertion(when));
- if (checkbreak && is_breakable(when)) {
- if (com[0].priority < 0)
- while (begin->code != BREAK_END)
- begin++;
- else
- while (end->code != BREAK_PRE)
- end--;
- }
- for (int i = 0; i < com.sz(); i++) {
- insert_between(com[i], begin, end);
- }
-}
-
-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.priority = 5;
- k.code = BREAK_PRE;
- seq.add(k);
- k.priority = 4;
- k.code = BREAK_MIDDLE;
- seq.add(k);
- k.priority = 3;
- k.code = BREAK_POST;
- seq.add(k);
- k.priority = 2;
- k.code = BREAK_END;
- seq.add(k);
-
- add_seq(seq,false);
-}
-
-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)
-{
- PCursor<Command*> c(firstc+1);
- assert(last->when==firstc->when&&firstc < last&&last.ok());
-
- while (c < last) {
- if (c->priority <= victim.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;
- assert(w >= 0);
- 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++;
- assert(l.ok() && l->when ==w && l->code == BREAK_END);
-
- insert_between(post, f, l);
-}
-
-void
-Score_commands::parser_add(Command *c)
-{
- bottom().add(c);
-}
-
-void
-Score_commands::process_add(Command c)
-{
- bool encapsulate =false;
- Real w = c.when;
- assert(w >= 0);
-
- Command pre(w);
- Command mid(w);
- Command post(w);
-
- if (c.code == INTERPRET)
- { // UGH
- if (c.args[0] == "BAR") {
- Command typeset(w); // kut met peren
- typeset.code = TYPESET;
- typeset.args = c.args;
- typeset.priority = 100;
- process_add(typeset);
- } else if (c.args[0] == "KEY") {
- Command typeset(w);
- typeset.code = TYPESET;
- typeset.args.add("KEY");
- typeset.priority = 70;
- process_add(typeset);
- } else if (c.args[0] == "CLEF") {
- Command typeset(w);
- typeset.code = TYPESET;
- typeset.args=c.args;
- typeset.priority = 90;
- process_add(typeset);
- }
- }
-
- // kut en peer
- if (c.code == TYPESET) {
- if (c.args[0] == "BAR") {
- set_breakable(w);
- encapsulate = true;
- mid = c;
- pre = c;
- { /* every line a currentkey. */
- Command kc(w);
- kc.code =TYPESET;
- kc.args.add( "CURRENTKEY");
- kc.priority = 60;
- process_add(kc);
- }
- { /* every line a currentclef. */
- Command kc(w);
- kc.code =TYPESET;
- kc.args.add( "CURRENTCLEF");
- kc.priority = 80;
- process_add(kc);
- }
- }else
- if (c.args[0] == "METER" && is_breakable(w)) {
- encapsulate = true;
- mid = c;
- pre = c;
- post =c;
- }else
- if( c.args[0] == "KEY" && is_breakable(c.when)) {
- encapsulate = true;
- mid = c;
- pre = c;
- post = c;
- }else
- if (c.args[0] == "CURRENTKEY" && is_breakable(w)) {
- post = c;
- encapsulate = true;
- }else
- if (c.args[0] == "CURRENTCLEF" && is_breakable(w)) {
- post = c;
- encapsulate = true;
- }else
- if (c.args[0] == "CLEF" && is_breakable(w)) {
- encapsulate = true;
- post = c;
- pre = c;
- mid = c;
- }
- }
-
- if (encapsulate)
- add_command_to_break(pre, mid, post);
- else {
- svec<Command> seq;
- seq.add(c);
- add_seq(seq,true);
- }
-}
-
-/*
- 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();
- }
-}
-
-/*
- TODO
- */
-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;
-
- { /* all pieces should start with a breakable. */
- Command c(0.0);
- c.code = INTERPRET;
- 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] == "KEY"||cc->args[0] == "CLEF") {
- cc->when = wholes;
- nc->process_add(**cc);
- }
- if (cc->args[0] == "SKIP") {
- stoppos = wholes + cc->args[1].value() * measlen +
- cc->args[2].fvalue();
- wholes += (measlen-inbar); // skip at least 1 measure
- barcount++;
- while (wholes <= stoppos) {
- nc->process_add(*get_bar_command(wholes)); // liek
- wholes += measlen;
- barcount ++;
- }
- wholes = stoppos;
- //something
- }
- }
-
- return nc;
-}
-#include "scommands.hh"
+#include "staffcommands.hh"
#include "tstream.hh"
+#include "getcommand.hh"
+#include "inputcommands.hh"
#include "score.hh"
#include "sccol.hh"
#include "pscore.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();
// do this after processing, staffs first have to generate PCols.
do_pcols();
calc_idealspacing();
- clean_cols();
+ clean_cols(); // ugh. Would want to clean the columns before anything else.
+
+
OK();
- // print();
pscore_->preprocess();
*mlog << "Calculating ... ";
pscore_->calc_breaking();
+ *mlog << "Postprocessing ... ";
pscore_->postprocess();
- // TODO: calculate vertical structs
- // TODO: calculate mixed structs.
+ // TODO: calculate vertical structs?
+ // TODO: calculate mixed structs.?
*mlog << "\n";
}
-// remove empty cols with no spacing attached.
-/* should rethink ownership of cols
- */
+// remove empty cols.
void
Score::clean_cols()
{
pscore_->clean_cols();
}
-/* this sux. We should have Score_column create the appropriate PCol.
- Unfortunately, PCols don't know about their position.
- */
+/*
+ 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)
return scc;
}
-Score_column*
+PCursor<Score_column*>
Score::find_col(Real w,bool mus)
{
PCursor<Score_column*> scc(cols_);
}
void
-Score::distribute_commands(void)
+Score::distribute_commands()
{
for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
- sc->add_commands(*commands_);
+ sc->process_input_commands(input_commands_, last());
}
}
void
for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
assert(cc->when <= (cc+1)->when);
}
- commands_->OK();
#endif
}
for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
sc->print();
}
- commands_->print();
mtor << "}\n";
#endif
}
{
pscore_=0;
paper_ = 0;
- commands_ = new Score_commands;
}
Score::~Score()
{
delete pscore_;
- delete commands_;
+ for (int i=0; i<input_commands_.sz(); i++)
+ delete input_commands_[i];
delete paper_;
}
+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::set(Score_commands*c)
+Score::add(svec<Command*> &s)
{
- delete commands_;
- commands_ = c;
+ input_commands_.add(get_reset_command());
+ input_commands_.concat(s);
}
+
#sv# isn't really const!!
*/
+
+void
+Line_of_score::process()
+{
+ for (PCursor<Line_of_staff*> i(staffs); i.ok(); i++)
+ i->process();
+}
+
s = new Bar(com->args[1]);
} else if (type == "METER") {
s = new Meter(arg);
- } else if (type == "CLEF") {
- s = new Clef_item;
+ } else if (type == "CLEF" ||type == "CURRENTCLEF") {
+ Clef_item * c = new Clef_item;
+ s = c;
+ c->change = (type == "CLEF");
}else{
WARN << "ignoring TYPESET command for " << type << '\n';
#include "request.hh"
+#include "voice.hh"
#include "swalker.hh"
#include "debug.hh"
#include "clef.hh"
#include "request.hh"
+#include "voice.hh"
#include "clef.hh"
#include "beam.hh"
#include "pscore.hh"
s.del(0);
clef_.read(s);
} else {
- WARN << " ignoring INTERPRET command: " << com->args[0];
+ WARN << " ignoring INTERPRET command: " << com->args[0]<< '\n';
}
}
else
com->args[0] = "KEY";
- if (com->args[0] == "CURRENTCLEF")
- if (processed_clef) {
+ if (com->args[0] == "CURRENTCLEF") {
+ if (processed_clef)
return;
- } else
- com->args[0] = "CLEF";
+ }
Item* i = staff()->get_TYPESET_item(com);
((Keyitem*) i)->read(typesetkey); // ugh
}
- if (com->args[0] == "CLEF") {
+ if (com->args[0] == "CLEF"||com->args[0] == "CURRENTCLEF") {
processed_clef =true;
- ((Clef_item*)i)->read(clef_);
+ Clef_item*c=(Clef_item*)i;
+ c->read(clef_);
+ c->change = (break_status != BREAK_POST - BREAK_PRE);
}
col()->typeset_item_directional(i, 1, break_status);
}
if ( local_key_.oct(n->octave).acc(n->name) != n->accidental) {
if (!local_key_item_) {
local_key_item_ = staff()->get_local_key_item();
+ local_key_item_->c0_position = clef_.c0_pos;
}
local_key_item_->add(n->octave, n->name, n->accidental);
Simple_staff *s = staff();
if (c->beam_&& c->beam_->spantype == Span_req::START) {
if (beam_)
- error("Too many beams");
+ error("Too many beams (t = "
+ +String(c->when())+")");
beam_ = new Beam;
}
for (int i=0; i < c->slurs.sz(); i++) {
}
if (beam_) {
+ if (!stem_)
+ error("beamed note should have a stem (t = "
+ +String(c->when())+")");
beam_->add(stem_);
}
if (stem_) {
c->typeset_item(stem_);
/* needed, otherwise placement of
local_key fucks up */
- stem_->set_default_extents();
+// stem_->set_default_extents();
+ // can somebody explain myself?
}
if (c->beam_&& c->beam_->spantype == Span_req::STOP) {
pscore_->typeset_spanner(beam_, s->theline);
#include "staff.hh"
+#include "score.hh"
+#include "voice.hh"
#include "swalker.hh"
+#include "getcommand.hh"
#include "stcol.hh"
#include "sccol.hh"
+#include "inputcommands.hh"
+#include "staffcommands.hh"
#include "debug.hh"
Staff::Staff(Staff const&src)
{
PL_copy(voices,src.voices);
- PL_copy(commands,src.commands);
+ staff_commands_ = src.staff_commands_;
assert(!cols.size()); // cols is a runtime field.
-
+ input_commands_ = src.input_commands_;
+
score_ = src.score_;
pscore_ = src.pscore_;
}
+void
+Staff::add(svec<Command*> &s)
+{
+ input_commands_.add(get_reset_command());
+ input_commands_.concat(s);
+}
+void
+Staff::add(PointerList<Voice*> &l)
+{
+ for (PCursor<Voice*> i(l); i.ok(); i++)
+ voices.bottom().add(i);
+}
+void
+Staff::process_input_commands(svec<Command*> &s, Real l)
+{
+ Input_commands commands;
+ for (int i = 0 ; i< s.sz(); i++)
+ commands.add(new Command(*s[i]));
+ for (int i = 0 ; i< input_commands_.sz(); i++)
+ commands.add(input_commands_[i]);
+ commands.truncate(l);
+ commands.print();
+
+ staff_commands_ = commands.parse();
+ staff_commands_->clean(l);
+ commands.print();
+ print();
+}
+
Paperdef*
-Staff::paper() const{
+Staff::paper() const
+{
return score_->paper_;
}
// ; assert((i-1).ok())
// todo!
- // making a fix at 2:30 am, with several beers drunk.
+ // making a fix at 2:30 am, with several beers drunk.
+ // but it works :-)
if ((i-1).ok()&& (i-1)->when() == newst->when()) {
i--;
}
*/
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++) {
}
}
- for (PCursor<Command*> cc(commands); cc.ok(); cc++) {
+ for (PCursor<Command*> cc(*staff_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()
{
{
#ifndef NDEBUG
cols.OK();
- commands.OK();
voices.OK();
assert(score_);
#endif
#ifndef NPRINT
mtor << "Staff {\n";
for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
- vc->print();
-
+ vc->print();
}
+ if (staff_commands_)
+ staff_commands_->print();
+ for (int i =0; i <input_commands_.sz(); i++)
+ input_commands_[i]->print();
mtor <<"}\n";
#endif
}
Staff::Staff()
{
+ staff_commands_ = 0;
score_ =0;
pscore_=0;
}
--- /dev/null
+#include "staffcommands.hh"
+#include "debug.hh"
+#include "parseconstruct.hh"
+
+/*
+ ARG!
+ */
+
+/*
+ maybe it's time for a "narrowing" cursor?
+ */
+PCursor<Command*>
+Staff_commands::first(Real w)
+{
+ PCursor<Command*> pc(*this);
+ while (pc.ok() && pc->when < w)
+ pc++;
+ if (!pc.ok() || pc->when != w) {
+ Command *c = new Command(w);
+ c->priority = 10000;
+ if (!pc.ok())
+ pc.add(c);
+ else
+ pc.insert(c);
+ }
+
+ return pc;
+}
+/*
+ RETURN: pc->when == w && pc.ok
+ */
+
+PCursor<Command*>
+Staff_commands::last_insertion(Real w)
+{
+ PCursor<Command*> pc(first(w)), next(pc);
+ while (next.ok() && next->when == w) {
+ pc=next;
+ next++;
+ }
+ if (pc->priority != -10000) {
+ Command*c = new Command(w);
+ c->priority = -10000;
+ pc.add(c);
+ pc++;
+ }
+
+ return pc;
+}
+
+/*
+ */
+void
+Staff_commands::add_seq(svec<Command> com, bool checkbreak)
+{
+ if (!com.sz())
+ return;
+
+ Real when = com[0].when;
+
+ PCursor<Command*> begin(first(when));
+ PCursor<Command*> end(last_insertion(when));
+ if (checkbreak && is_breakable(when)) {
+ if (com[0].priority < 0)
+ while (begin->code != BREAK_END)
+ begin++;
+ else
+ while (end->code != BREAK_PRE)
+ end--;
+ }
+ for (int i = 0; i < com.sz(); i++) {
+ insert_between(com[i], begin, end);
+ }
+}
+
+void
+Staff_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.priority = 5;
+ k.code = BREAK_PRE;
+ seq.add(k);
+ k.priority = 4;
+ k.code = BREAK_MIDDLE;
+ seq.add(k);
+ k.priority = 3;
+ k.code = BREAK_POST;
+ seq.add(k);
+ k.priority = 2;
+ k.code = BREAK_END;
+ seq.add(k);
+
+ add_seq(seq,false);
+}
+
+bool
+Staff_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
+Staff_commands::insert_between(Command victim, PCursor<Command*> firstc,
+ PCursor<Command*> last)
+{
+ PCursor<Command*> c(firstc+1);
+ assert(last->when==firstc->when&&firstc < last&&last.ok());
+
+ while (c < last) {
+ if (c->priority <= victim.priority) {
+ c.insert(new Command(victim));
+ return;
+ }
+ c++;
+ }
+ last.insert(new Command(victim));
+}
+
+void
+Staff_commands::add_command_to_break(Command pre, Command mid, Command post)
+{
+ Real w = pre.when;
+ assert(w >= 0);
+ 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++;
+ assert(l.ok() && l->when ==w && l->code == BREAK_END);
+
+ insert_between(post, f, l);
+}
+
+void
+Staff_commands::process_add(Command c)
+{
+ bool encapsulate =false;
+ Real w = c.when;
+ assert(w >= 0);
+
+ Command pre(w);
+ Command mid(w);
+ Command post(w);
+
+ if (c.code == INTERPRET)
+ { // UGH
+ if (c.args[0] == "BAR") {
+ Command typeset(w); // kut met peren
+ typeset.code = TYPESET;
+ typeset.args = c.args;
+ typeset.priority = 100;
+ process_add(typeset);
+ } else if (c.args[0] == "KEY") {
+ Command typeset(w);
+ typeset.code = TYPESET;
+ typeset.args.add("KEY");
+ typeset.priority = 70;
+ process_add(typeset);
+ } else if (c.args[0] == "CLEF") {
+ Command typeset(w);
+ typeset.code = TYPESET;
+ typeset.args=c.args;
+ typeset.priority = 90;
+ process_add(typeset);
+ } else if (c.args[0] == "METER") {
+ Command typeset(w);
+ typeset.code = TYPESET;
+ typeset.args=c.args;
+ typeset.priority = 40;
+ process_add(typeset);
+ return;
+ }
+ }
+
+ // kut en peer
+ if (c.code == TYPESET) {
+ if (c.args[0] == "BAR") {
+ set_breakable(w);
+ encapsulate = true;
+ mid = c;
+ pre = c;
+ { /* every line a currentkey. */
+ Command kc(w);
+ kc.code =TYPESET;
+ kc.args.add( "CURRENTKEY");
+ kc.priority = 60;
+ process_add(kc);
+ }
+ { /* every line a currentclef. */
+ Command kc(w);
+ kc.code =TYPESET;
+ kc.args.add( "CURRENTCLEF");
+ kc.priority = 80;
+ process_add(kc);
+ }
+ }else
+ if (c.args[0] == "METER" && is_breakable(w)) {
+ encapsulate = true;
+ mid = c;
+ pre = c;
+ post =c;
+ }else
+ if( c.args[0] == "KEY" && is_breakable(c.when)) {
+ encapsulate = true;
+ mid = c;
+ pre = c;
+ post = c;
+ }else
+ if (c.args[0] == "CURRENTKEY" && is_breakable(w)) {
+ post = c;
+ encapsulate = true;
+ }else
+ if (c.args[0] == "CURRENTCLEF" && is_breakable(w)) {
+ post = c;
+ encapsulate = true;
+ }else
+ if (c.args[0] == "CLEF" && is_breakable(w)) {
+ encapsulate = true;
+ post = c;
+ pre = c;
+ mid = c;
+ }
+ }
+
+ if (encapsulate)
+ add_command_to_break(pre, mid, post);
+ else {
+ svec<Command> seq;
+ seq.add(c);
+ add_seq(seq,true);
+ }
+}
+
+/*
+ first and last column should be breakable.
+ Remove any command past the last musical column.
+ */
+void
+Staff_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
+Staff_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
+Staff_commands::print() const
+{
+#ifndef NPRINT
+ for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
+ cc->print();
+ }
+#endif
+}
#include "spanner.hh"
#include "symbol.hh"
#include "paper.hh"
+#include "molecule.hh"
#include "pcol.hh"
#include "pscore.hh"
s+=make_vbox(height());
// the staff itself: eg lines, accolades
s += "\\hbox{";
- {
- Symbol sym = pstaff_->get_stafsym(line_of_score_->pscore_-> // ugh
- paper_->linewidth);
- s+=sym.tex;
+ {
+ ((PStaff*)pstaff_)->
+ brew_molecule(line_of_score_->pscore_->paper_->linewidth);
+
+ s+=pstaff_->stafsym->TeXstring();
PCursor<const PCol *> cc(line_of_score_->cols);
Real lastpos=cc->hpos;
{
Interval y;
{
- Symbol s = pstaff_->stafsym->eval(line_of_score_->pscore_->
- paper_->linewidth);
- y = s.dim.y;
+ y = pstaff_->stafsym->extent().y;
}
PCursor<const PCol *> cc(line_of_score_->cols);
return y;
}
-
+void
+Line_of_staff::process()
+{
+ if (!pstaff_->stafsym)
+ pstaff_->brew_molecule(line_of_score_->pscore_->
+ paper_->linewidth);
+}
void
Stem::postprocess()
{
- set_default_extents();
+ if (bot == top)
+ set_default_extents();
brew_molecole();
}
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);
-}
#include "associter.hh"
#include "parser.hh"
-static Keyword_ent the_key_tab[]={
- "voice", VOICE,
- "rhythmstaff", RHYTHMSTAFF,
- "melodicstaff", MELODICSTAFF,
- "clef", CLEF,
- "score", SCORE,
+static Keyword_ent the_key_tab[]={
"bar", BAR,
- "output", OUTPUT,
+ "bass", BASS,
+ "clef", CLEF,
"cm", CM,
- "start", START_T,
- "pt", PT,
+ "commands", COMMANDS,
+ "duration", DURATIONCOMMAND,
+ "geometric", GEOMETRIC,
"in", IN,
+ "key", KEY,
+ "melodicstaff", MELODICSTAFF,
+ "meter", METER,
"mm", MM,
+ "octave", OCTAVECOMMAND,
+ "output", OUTPUT,
+ "partial", PARTIAL,
"paper", PAPER,
- "width", WIDTH,
- "violin", VIOLIN,
- "bass", BASS,
- "meter", METER,
- "unitspace", UNITSPACE,
+ "pt", PT,
+ "rhythmstaff", RHYTHMSTAFF,
+ "score", SCORE,
"skip", SKIP,
- "octave", OCTAVECOMMAND,
- "commands", COMMANDS,
"staff", STAFF,
- "geometric", GEOMETRIC,
- "duration", DURATIONCOMMAND,
- "key", KEY,
+ "start", START_T,
+ "table", TABLE,
+ "chord", CHORD,
+ "multi", MULTI,
+ "unitspace", UNITSPACE,
+ "violin", VIOLIN,
+ "voice", VOICE,
+ "voices", VOICES,
+ "width", WIDTH,
0,0
} ;
#include "symbol.hh"
#include "voice.hh"
-
+#include "request.hh"
#include "staff.hh"
#include "sccol.hh"
#include "stcol.hh"
-#include "request.hh"
#include "command.hh"
#include "molecule.hh"
#include "plist.cc"
IPL_instantiate(Atom);
IPL_instantiate(Command);
-IPL_instantiate(Request);
+
if (s>0)
return 6*i +122;
else
- return -6 * i+ 188;
+ return -6 * i+ 186;
}
Symbol
if (dx >= convert_dimen(4*54, "pt"))
error("slur too wide");
idx = widx;
- if (dir > 0)
+ if (dir < 0)
idx += 54;
}
Lookup::big_slur(int dy , Real &dx, int dir)
{
assert(dx >= convert_dimen(24,"pt"));
-
Real slur_extra =ABS(dy) /2.0 + 2;
int l_dy = Real (dy)/2 + slur_extra*dir;
int r_dy = dy - l_dy;
Atom l = half_slur(l_dy, left_wid, dir, -1);
Atom r = half_slur(r_dy, right_wid, dir, 1);
Real mid_wid = dx - left_wid - right_wid;
+
Atom m = half_slur(0, mid_wid, dir, 0);
Molecule mol;
a.translate(Offset(0,slur_extra * internote()));
mol.add_right(m);
mol.add_right(r);
- mol.translate(Offset(l_dy * internote(), 0));
+ mol.translate(Offset(0, l_dy * internote()));
Symbol s;
s.tex = mol.TeXstring();
s.dim = mol.extent();
#include "debug.hh"
#include "voice.hh"
+#include "request.hh"
Voice::Voice(Voice const&src)
{
voice_=src.voice_;
IPointerList__copy(Request*, reqs, src.reqs, clone());
group=src.group;
- assert(!granted_items.size() && !granted_spanners.size());
+// assert(!granted_items.size() && !granted_spanners.size());
}
#include "debug.hh"
- ostream &warnout (cerr);
- ostream *mlog(&cerr);
+#include "lexer.hh"
+
+ostream &warnout (cerr);
+ostream *mlog(&cerr);
void
error(String s)
{
- cerr << "\nerror: " << s << "\n";
+ if (busy_parsing())
+ yyerror(s);
+ else
+ cerr << "\nerror: " << s << "\n";
+
+ exit(1);
+}
+
+void
+error_t(String s, Real r)
+{
+ String e=s+ "(t = " + r + ")";
+ error(e);
exit(1);
}
violin \violinclef 0pt 16pt -12.5pt 22.5pt
bass \bassclef 0pt 16pt 0pt 20pt
viola \violaclef 0pt 16pt 0pt 20pt
+ violin_change \cviolinclef 0pt 16pt -12.5pt 22.5pt
+ bass_change \cbassclef 0pt 16pt 0pt 20pt
+ viola_change \cviolaclef 0pt 16pt 0pt 20pt
end
table balls
table bars
empty \emptybar 0pt 0pt 0pt 0pt
- | \maatstreep 0pt 1pt -12pt 12pt
+ | \maatstreep 0pt 5pt -12pt 12pt
|| \finishbar 0pt 2pt -12pt 12pt
end