Commands_at 1
Input_command 1
Time_description 1
-Melodic_req 1
+Melodic_req 0
Midi_walker 0
Stem_req 1
Group_change_req 1
score. Practically it is a typesetter, which only uses TeX as an
output medium. (this is handy because there exist music fonts for TeX)
+As a bonus, you can also output a MIDI file of what you typed.
+
HOW DOES IT WORK
The input is a script file (example appended) which is read. The
WHY A CALL FOR HACKERS
-Currently, the development has three people. I'd this project to have
-more people working on it (there is a lot of work to be done) I think
-this program is pretty original, so join in if you anything about
-music and computers!
+Currently, the development team has three people. I'd this project to
+have more people working on it (there is a lot of work to be done) I
+think this program is pretty original, so join in if you know anything
+about music and computers!
As an aside, I really like the anarchist approach of linux development.
WHAT HAS TO BE DONE
-LilyPond is written in Gnu C++, and it is (imo) written very cleanly
-(Lots of classes, lots of comments, small files/small functions) and
-with extensions in mind.
+LilyPond is written in Gnu C++, and it is (if I say so myself) written
+very cleanly (Lots of classes, lots of comments, small files/small
+functions) and with extensions in mind.
- Coding. For this time, there won't any biggish (global)
source hackings. There are a lot of small projects which could use
}
commands {
meter {2 * 4}
- skip 24*2
+ skip {24*2}
bar "||"
}
}
The source is commented in the DOC++ style. Check out doc++ at
http://www.zib.de/Visual/software/doc++/index.html
+ /*
+ C style comments for multiline comments.
+ [...]
+ */
+
+
/**
short description.
Long class documentation.
(Hungarian postfix)
*/
class Class {
- /** short description.
+ /**
+ short description.
long description
*/
/**
short memo. long doco of member()
+ @param description of arguments
+ @return Rettype
*/
- member();
+ Rettype member(Argtype);
/// memo only
boring_member();
add F<FILE> to the search path for input files.
+
+=item B<-M,--midi>
+
+do midi output only
+
=item B<-d,--debug>,
Turn debugging info. LilyPond will read the file F<.dstreamrc>, which
Q: I want a DOS/NT/W95 port.
-A0: Reconsider. Try Linux. It-s fun!
+A0: Reconsider. Try Linux. It's fun!
A1: Currently (patchlevel 27), LilyPond (and flowerLib) compiles, links
and runs on windhoos-nt, using the cygnus gnu port (release b17.1).
make $OS. (I am not promising to maintain this platform, it is just that
when having to use doze, i-m sometimes too lazy to reboot.)
-A2: I haven't had time to find a GCC crosscompiler to DOS/win (in rpm,
-please :).
+A2: I haven't had time to find a GCC crosscompiler (*with* g++, mind you) to
+DOS/win (in rpm, please :).
+
Q: Why GPL?
A: Yes.
+
Q: Why shouldn't I put all commands (\clef, \meter) inside the music?
A: You should do what you like, but at some time we will enable
quoting of music ("Stichnoten"). Besides if you are going to type an
-orchestral score, then you'd probably want to enter most of those
-commands only once.
+orchestral score, then you'd probably want to enter most of the meter,
+repeat commands only once.
+
+Q: Could you implement feature XXXX? It is really easy, just extend
+the syntax to allow YYYY!
+A: If it is reasonable, I'll add XXXX to the TODO list. In general
+finding a cute syntax (such as YYYY) isn't very hard. The complicated
+issue how to adapt the internals to do XXXX. The parser is really a
+simple front end to the complicated internals.
+# Generate.make ?
+# -> Rules.make: containing all compile/flex/bison/... rules (jcn)
parsheadorig=$(CCDIR)/parser.tab.h
parsheadnew=$(HEADERDIR)/parser.hh
#
# take some trouble to avoid overwriting the old y.tab.h
+# why? (jcn)
$(CCDIR)/parser.cc: $(CCDIR)/parser.y
$(BISON) -d $<
(if diff $(parsheadorig) $(parsheadnew)>/dev/null; then \
$(HEADERDIR)/version.hh: Variables.make make_version
make_version $(MAJVER) $(MINVER) $(PATCHLEVEL) "$(CXX) $(CXXVER)" > $@
-$(CCDIR)/lexer.cc: $(CCDIR)/lexer.l
- $(FLEX) -t $< > $@
-
-
+$(CCDIR)/%.cc: $(CCDIR)/%.y
+ $(BISON) -d $<
+ mv $(CCDIR)/$(shell basename $@ .cc ).tab.h $(HEADERDIR)/$(shell basename $@ .cc).hh
+ mv $(CCDIR)/$(shell basename $@ .cc ).tab.c $@
+$(CCDIR)/%.cc: $(CCDIR)/%.l
+ $(FLEX) -t $< > $@
+# Makefile
+# top level makefile of LilyPond
+
include Variables.make
.SUFFIXES:
$(STRIPDEBUG) $(STABLEOBS)
$(LINKER) -o $@ $^ $(LOADLIBES)
+$(m2m): $(m2mobs)
+ $(LINKER) -o $@ $^ $(LOADLIBES)
.PHONY: clean docxx
clean:
- rm -f $(exe) $(DOCDIR)/* core $(obs) $(ALLDEPS)
+ rm -f $(allexe) $(DOCDIR)/* core $(allobs) $(ALLDEPS)
for SUBDIR in $(SUBDIRS); \
do \
$(MAKE) SUBDIR=$$SUBDIR -C $$SUBDIR clean;\
distclean: clean
rm -f version.hh $(gencc) .GENERATE *~ $(ALLDEPS)
-all: kompijl doc
+all: $(exe) $(m2m) doc
# value of $(OSTYPE) on windhoos; "make $OSTYPE" if u use bash :-)
win32:
+*******
+pl 34
+ - better midi syntax.
+ - --midi,-M option.
+ - preliminary midi2mudela (/mudela2midi) converter: m2m (JCN)
+Internal
+ - m2m sources: midi-*; (JCN)
+ - new Midi_walker, fixes several MIDI bugs.
+ - junked Midi_staff, Staff_column children, Midi_walker
+ - Midi_output
+
*******
pl33
Examples
- Swedish notenames (MB)
+
+pl pre33-2
+
+Bugfix
+ - midi pitch
+
Features
- Jan's patches, see below
Bugfix
-# -*- Makefile-*-
+# Sources.make
# sourcefiles to be shipped. Also used for dependencies
hdr= bar.hh barreg.hh beam.hh boxes.hh break.hh clefreg.hh clefitem.hh\
- colhpos.hh commandrequest.hh complexcolumn.hh \
+ colhpos.hh commandrequest.hh \
complexwalker.hh complexstaff.hh\
const.hh debug.hh dimen.hh directionalspanner.hh\
glob.hh grouping.hh headreg.hh idealspacing.hh\
identifier.hh identparent.hh \
- inputmusic.hh inputscore.hh inputstaff.hh item.hh key.hh keyitem.hh\
+ inputmusic.hh inputscore.hh inputstaff.hh\
+ inputfile.hh\
+ item.hh key.hh keyitem.hh\
keyreg.hh\
keyword.hh leastsquares.hh lexer.hh linespace.hh \
localkeyitem.hh localkeyreg.hh lookup.hh \
- lyriccolumn.hh lyricitem.hh lyricstaff.hh lyricwalker.hh\
+ lyricitem.hh lyricstaff.hh lyricwalker.hh\
main.hh meter.hh meterreg.hh\
- midicolumn.hh mididef.hh midiitem.hh midistaff.hh midistream.hh\
- midiwalker.hh midiscorewalker.hh\
+ mididef.hh midiitem.hh midioutput.hh midistream.hh\
+ midiwalker.hh\
misc.hh\
molecule.hh moment.hh musicalrequest.hh\
notehead.hh notename.hh offset.hh paperdef.hh\
- parseconstruct.hh pcol.hh proto.hh pscore.hh pstaff.hh qlp.hh\
+ parseconstruct.hh pcol.hh proto.hh\
+ pscore.hh pstaff.hh qlp.hh\
qlpsolve.hh register.hh reqtodo.hh request.hh rest.hh \
sccol.hh score.hh\
scoreline.hh scorewalker.hh script.hh scriptdef.hh scriptreg.hh \
mycc=bar.cc barreg.cc beam.cc boxes.cc break.cc calcideal.cc clefreg.cc\
clefitem.cc colhpos.cc commandrequest.cc\
- complexcolumn.cc complexstaff.cc complexwalker.cc \
+ complexstaff.cc complexwalker.cc \
debug.cc dimen.cc\
directionalspanner.cc\
- grouping.cc groupregs.cc headreg.cc\
+ grouping.cc groupregs.cc headreg.cc\
idealspacing.cc identifier.cc\
- inputmusic.cc inputscore.cc\
- inputstaff.cc item.cc key.cc keyitem.cc \
+ inputmusic.cc inputscore.cc\
+ inputstaff.cc\
+ inputfile.cc\
+ item.cc key.cc keyitem.cc \
keyreg.cc keyword.cc\
leastsquares.cc lexerinit.cc linespace.cc \
localkeyitem.cc localkeyreg.cc lookup.cc\
- lyriccolumn.cc lyricitem.cc lyricstaff.cc lyricwalker.cc\
+ lyricitem.cc lyricstaff.cc lyricwalker.cc\
main.cc meter.cc meterreg.cc\
- mididef.cc midicolumn.cc midiitem.cc midistaff.cc midistream.cc\
- midiwalker.cc midiscorewalker.cc\
- misc.cc molecule.cc mylexer.cc note.cc notehead.cc notename.cc\
- paperdef.cc pcol.cc pscore.cc pstaff.cc qlp.cc qlpsolve.cc\
+ mididef.cc midiitem.cc midioutput.cc midistream.cc\
+ midiwalker.cc misc.cc molecule.cc mylexer.cc note.cc\
+ notehead.cc notename.cc\
+ paperdef.cc pcol.cc pscore.cc pstaff.cc qlp.cc qlpsolve.cc\
register.cc request.cc rest.cc sccol.cc score.cc\
scoreline.cc scores.cc scorewalker.cc script.cc\
scriptdef.cc scriptreg.cc slur.cc\
# a bit of a hack to keep exec size under control.
stablecc=request.cc bar.cc boxes.cc break.cc \
item.cc keyword.cc leastsquares.cc \
- lookup.cc molecule.cc meter.cc\
+ lookup.cc molecule.cc meter.cc\
paperdef.cc parser.cc lexer.cc pstaff.cc qlp.cc qlpsolve.cc\
template1.cc template2.cc template3.cc template4.cc\
template5.cc template6.cc version.cc tstream.cc tex.cc\
voice.cc wordwrap.cc spanner.cc
+
+
+# m2m headers
+#
+mym2mhh=\
+ midi-event.hh\
+ midi-main.hh\
+ midi-score.hh\
+ midi-track.hh\
+ my-midi-lexer.hh\
+ my-midi-parser.hh\
+
+#
+
+# m2m source
+#
+mym2mcc=\
+ midi-event.cc\
+ midi-main.cc\
+ midi-score.cc\
+ midi-template.cc\
+ midi-track.cc\
+ my-midi-lexer.cc\
+ my-midi-parser.cc\
+
+#
+
+# m2m shared source
+#
+mym2msharedcc=\
+ inputfile.cc\
+ sourcefile.cc\
+ source.cc\
+
+
+#
before 0.1
- * Register_groups as a baseclass.
- * Junk Staff/Staff_col children.
+ * create libmudela, libmidi, or liblily_frontend
+
+ * Register_groups as a baseclass.
* pushgroup, popgroup.
* basic dynamics
- * MIDI syntax.
-
* decent TeX page layout
* < .. > vs. { .. } syntax? !
BUGS
* key undo
+ * c8. c32 c32
+
* key print if clef change.
* $cis ( | ) cis$
# version info
MAJVER=0
MINVER=0
-PATCHLEVEL=33
+PATCHLEVEL=34
# CXX=g++
# turn off -pipe if linker doesn't support it
-EXTRACXXFLAGS=-pipe -Wall -W -Wmissing-prototypes
+EXTRACXXFLAGS=-pipe -Wall -W -Wmissing-prototypes -DSTRING_UTILS_INLINED
#
# -lefence = ElectricFence.
#
#
include Sources.make
+
+# UGH, this sux!
gencc=parser.cc lexer.cc
cc=$(mycc) $(gencc)
+mym2mgencc=midi-parser.cc midi-lexer.cc
+m2mcc=$(mym2mcc) $(mym2mgencc) $(mym2msharedcc)
MY_CCSOURCE=$(addprefix $(CCDIR)/, $(mycc))
CCSOURCE=$(addprefix $(CCDIR)/, $(cc))
obs=$(addprefix $(OBJECTDIR)/,$(cc:.cc=.o))
+m2mobs=$(addprefix $(OBJECTDIR)/,$(m2mcc:.cc=.o))
+allcc=$(mycc) $(mym2mcc)
+allobs=$(obs) $(m2mobs)
+allexe=$(exe) $(m2m)
+M2MCCSOURCE=$(addprefix $(CCDIR)/, $(m2mcc))
ALLDEPS=$(addprefix $(DEPDIR)/,$(cc:.cc=.dep))
STABLEOBS=$(addprefix $(OBJECTDIR)/,$(stablecc:.cc=.o))
-HEADERS=$(addprefix $(HEADERDIR)/,$(hdr))
+allhdr=$(hdr) $(mym2mhh)
+HEADERS=$(addprefix $(HEADERDIR)/,$(allhdr))
progdocs=$(HEADERS) $(MY_CCSOURCE)
#dist
PACKAGENAME=lilypond
DNAME=$(PACKAGENAME)-$(VERSION)
+M2MNAME=m2m
# distribution files.
-othersrc=lexer.l parser.y
+othersrc=lexer.l parser.y midi-lexer.l midi-parser.y
SCRIPTS=make_version make_patch genheader clearlily
MAKFILES=Makefile Variables.make Sources.make Initial.make Generate.make \
configure
FLEX=flex
BISON=bison
exe=$(PACKAGENAME)
+m2m=$(M2MNAME)
OUTPUT_OPTION=$< -o $@
DDIR=$(TOPDIR)/$(DNAME)
SUBDIRS=Documentation $(OBJECTDIR) $(CCDIR) $(HEADERDIR) $(INITDIR) $(DEPDIR) \
MAKE=${MAKE:-make}
PREFIX=${PREFIX:-.}
-NEEDFLOWERVER=1.1.1
+NEEDFLOWERVER=1.1.2
echo using PREFIX=$PREFIX
echo I need Flower version $NEEDFLOWERVER
include depend
depend: Sources.make
- $(CXX) -MM $(cc) > depend
+ $(CXX) $(CXXFLAGS) -MM $(cc) > depend
clean:
rm -f $(obs) $(staticlib) fversion.hh
-1.1:
+pl 1.1.1
+ - separated StringHandle and StringData
+(JCN pl 27-3)
+ - debug memmove code
+ - StringData bugfix
+ - old String::String( char, int ) bugfix
+
+1.1.0:
------------------
templatecc=cursor.tcc list.tcc plist.tcc interval.tcc\
pcursor.tcc
-inl=link.inl list.inl cursor.inl plist.inl
+inl=link.inl list.inl cursor.inl plist.inl stringdata.inl stringhandle.inl
+
hh=assoc.hh associter.hh choleski.hh compare.hh cursor.hh dstream.hh\
fproto.hh handle.hh interval.hh iterate.hh lgetopt.hh link.hh list.hh\
matrix.hh path.hh pcursor.hh plist.hh rational.hh real.hh scalar.hh\
-smat.hh string.hh stringconversion.hh stringutil.hh \
+smat.hh string.hh stringconversion.hh stringhandle.hh stringdata.hh\
textdb.hh textstream.hh unionfind.hh\
varray.hh vector.hh vsmat.hh datafile.hh
MAJVER=1
MINVER=1
-PATCHLEVEL=0
+PATCHLEVEL=1
PACKAGENAME=flower
#PROFILEFLAG=-pg
-DEBUGFLAG= -g
+#DEBUGFLAG= -g
OPTIFLAG= -DNPRINT -O2 -DSTRING_UTILS_INLINED -DNDEBUG
#########################################
struct long_option_init ;
struct Getopt_long ;
struct Matrix ;
-struct StringData ;
+struct String_data ;
struct String_handle ;
struct String;
struct virtual_smat ;
class Data_file ;
struct Text_db;
struct Scalar;
+typedef unsigned char Byte;
#endif // FPROTO_HH
Rehacked by HWN 3/nov/95
removed String &
- introduced Class String_handle
+ introduced class String_handle
*/
#include <string.h>
#include "string.hh"
+#ifdef STRING_DEBUG
+void* mymemmove( void* dest, void* src, size_t n );
+#define memmove mymemmove
+#endif
static char*
strlwr( char* s )
// return array, alloced with new.
Byte*
-String::copy_by_p() const
+String::copy_byte_p() const
{
- Byte const* src = strh_.by_c_l();
+ Byte const* src = strh_.byte_c_l();
Byte* dest = new Byte[strh_.length_i() + 1];
memmove( dest, src, strh_.length_i() + 1 );
return dest;
strh_ = source;
}
-String::String( Byte const* by_l, int length_i )
+String::String( Byte const* byte_l, int length_i )
{
- assert( !length_i || by_l );
- strh_.set( by_l, length_i );
+ assert( !length_i || byte_l );
+ strh_.set( byte_l, length_i );
}
void
String::operator +=(String s)
{
- strh_.append( s.by_c_l(), s.length_i() );
+ strh_.append( s.byte_c_l(), s.length_i() );
}
int
return strh_.length_i();
}
-String::String(char c, int n)
+// will go away, fixed anyway
+String::String( char c, int n )
{
- int l = n;
- assert(n >= 0 && n <= 80); // what the fuck is 80?
-//min(max( n, 0 ), 80);
- char s[81];
- memset(s, c, l);
- s[l] = 0;
-// strh_ = s;
- strh_.set( (Byte*)s, n );
+ n = n >= 0 ? n : 0;
+ char* ch_p = new char[ n ];
+ memset( ch_p, c, n );
+ strh_.set( (Byte*)ch_p, n );
+ delete ch_p;
}
String::String(int i)
String v( i );
String str = String( fillChar, n - v.length_i() ) + String( v );
- strh_.set( str.by_c_l(), str.length_i() );
+ strh_.set( str.byte_c_l(), str.length_i() );
}
Byte const*
-String::by_c_l() const
+String::byte_c_l() const
{
- return strh_.by_c_l();
+ return strh_.byte_c_l();
}
char const*
}
Byte*
-String::by_l()
+String::byte_l()
{
- return strh_.by_l();
+ return strh_.byte_l();
}
char*
int
String::compare(String const& s1, String const& s2 )
{
- Byte const* p1 = s1.by_c_l();
- Byte const* p2 = s2.by_c_l();
+ Byte const* p1 = s1.byte_c_l();
+ Byte const* p2 = s2.byte_c_l();
if ( p1 == p2 )
return 0;
int i2 = s2.length_i();
int i = i1 <? i2;
- if (! i )
- return 0;
-
- int result = memcmp( p1, p2, i );
-
- return (result)? result : i1 - i2;
+ int result= memcmp( p1, p2, i );
+ return result ? result : i1-i2;
}
if ( n < 1)
String();
- return String( strh_.by_c_l() + length_i() - n, n );
+ return String( strh_.byte_c_l() + length_i() - n, n );
}
if ( ( n > length_i() ) || ( pos + n - 1 > length_i() ) )
n = length_i() - pos + 1;
- return String( by_c_l() + pos -1, n );
+ return String( byte_c_l() + pos -1, n );
}
{
// not binary safe
assert( length_i() == strlen( ch_c_l() ) );
- char *s = strh_.by_l();
+ char *s = strh_.byte_l();
strupr( s );
return *this;
}
{
// not binary safe
assert( length_i() == strlen( ch_c_l() ) );
- char* s = strh_.by_l();
+ char* s = strh_.byte_l();
strlwr(s);
return *this;
}
Byte*
-strrev( Byte* by_l, int length_i )
+strrev( Byte* byte_l, int length_i )
{
Byte by;
- Byte* left_by_l = by_l;
- Byte* right_by_l = by_l + length_i;
+ Byte* left_byte_l = byte_l;
+ Byte* right_byte_l = byte_l + length_i;
- while ( right_by_l > left_by_l ) {
- by = *left_by_l;
- *left_by_l++ = *right_by_l;
- *right_by_l-- = by;
+ while ( right_byte_l > left_byte_l ) {
+ by = *left_byte_l;
+ *left_byte_l++ = *right_byte_l;
+ *right_byte_l-- = by;
}
- return by_l;
+ return byte_l;
}
String::reversed() const
{
String str = *this;
- strrev( str.by_l(), str.length_i() );
+ strrev( str.byte_l(), str.length_i() );
return str;
}
/*
- FILE : string.hh -- implement String inline helper classes,
- and declare stringclass.
-
+ FILE : string.hh -- declare String
Rehacked by HWN 3/nov/95
removed String & 's
#include <iostream.h>
#include <Rational.h>
-#include "stringutil.hh"
+#include "stringhandle.hh"
/**
/// String s = "abc";
String( const char* source );
- String( Byte const* l_by_c, int length_i );
+ String( Byte const* l_byte_c, int length_i );
/// "ccccc"
String( char c, int n = 1 );
String( int i, int n, char c = ' ' );
/// return a "new"-ed copy of contents
- Byte* copy_by_p() const; // return a "new"-ed copy of contents
+ Byte* copy_byte_p() const; // return a "new"-ed copy of contents
char const* ch_c_l() const;
- Byte const* by_c_l() const;
+ Byte const* byte_c_l() const;
char* ch_l();
- Byte* by_l();
+ Byte* byte_l();
/// deprecated; use ch_c_l()
operator const char *() const { return ch_c_l(); }
StringConversion::bin2hex_str( String bin_str )
{
String str;
- Byte const* by_c_l = bin_str.by_c_l();
+ Byte const* byte_c_l = bin_str.byte_c_l();
for ( int i = 0; i < bin_str.length_i(); i++ ) {
- str += (char)nibble2hex_by( *by_c_l >> 4 );
- str += (char)nibble2hex_by( *by_c_l++ );
+ str += (char)nibble2hex_by( *byte_c_l >> 4 );
+ str += (char)nibble2hex_by( *byte_c_l++ );
}
return str;
}
hex_str = "0" + hex_str;
bin_str_r = "";
- Byte const* by_c_l= hex_str.by_c_l();
+ Byte const* byte_c_l= hex_str.byte_c_l();
int i = 0;
while ( i < hex_str.length_i() ) {
- int high_i = hex2nibble_i( *by_c_l++ );
- int low_i = hex2nibble_i( *by_c_l++ );
+ int high_i = hex2nibble_i( *byte_c_l++ );
+ int low_i = hex2nibble_i( *byte_c_l++ );
if ( high_i < 0 || low_i < 0 )
return 1; // illegal char
bin_str_r += String( (char)( high_i << 4 | low_i ), 1 );
*/
-#ifndef __STRING_CONVERSION_HH
-#define __STRING_CONVERSION_HH
+#ifndef STRING_CONVERSION_HH
+#define STRING_CONVERSION_HH
/**
all conversions from/to String go in here.( some time, anyway )
- Quite empty
+ The class is quite empty from data view.
*/
class StringConversion {
static int hex2bin_i( String hex_str, String& bin_str_r );
--- /dev/null
+/*
+ stringdata.hh -- declare String_data
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef STRINGDATA_HH
+#define STRINGDATA_HH
+
+
+/**Internal String struct.
+ the data itself. Handles simple tasks (resizing, resetting)
+ */
+class String_data {
+ // GNU malloc: storage overhead is 8 bytes anyway.
+
+friend class String_handle;
+ int maxlen; // maxlen is arraysize-1
+
+ int length_i_;
+ Byte* data_byte_p_;
+ int references;
+
+ /// init to ""
+ String_data();
+
+ /// init from src. Conservative allocation.
+ String_data(String_data const &src);
+
+ ~String_data();
+
+ /** POST: maxlen >= j.
+ @param j, maximum stringlength_i_.
+ contents thrown away.
+ */
+ void setmax(int j);
+
+ /** POST: maxlen >= j.
+ @param j, maximum stringlength_i_.
+ contents are kept if it grows.
+ */
+ void remax(int j);
+
+ /// check if writeable.
+ void OKW();
+
+ /// check state.
+ void OK();
+
+ /// reduce memory usage.
+ void tighten();
+
+ // assignment.
+ void set( Byte const* byte_c_l, int length_i );
+
+ void set( char const* ch_c_l );
+
+ /// concatenation.
+ void append( Byte const* byte_c_l, int length_i );
+
+ void operator += ( char const* ch_c_l );
+
+ char const* ch_c_l() const;
+
+ char* ch_l();
+
+ Byte const* byte_c_l() const;
+
+ // idem, non const
+ Byte* byte_l();
+
+ void trunc(int j);
+
+ /** access element. not really safe. Can alter length_i_ without
+ #String_data# knowing it. */
+ Byte &operator [](int j);
+ Byte operator [](int j) const;
+};
+
+
+
+#ifdef STRING_UTILS_INLINED
+#ifndef INLINE
+#define INLINE inline
+#endif
+#include "stringdata.inl"
+
+#endif
+
+
+#endif // STRING_DATA_HH
--- /dev/null
+/* -*-C++-*-
+ String_data.inl -- implement String_data
+
+ source file of Flower lib
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#ifndef STRINGDATA_INL
+#define STRINGDATA_INL
+
+#include <assert.h>
+#include <memory.h>
+
+#include "stringdata.hh"
+const int INITIALMAX=8;
+
+#ifdef STRING_DEBUG
+
+INLINE void* mymemmove( void* dest, void* src, size_t n )
+{
+ return memcpy( dest, src, n ); // wohltempererit: 69006
+}
+#define memmove mymemmove
+#endif
+
+INLINE void
+String_data::OKW()
+{
+ assert (references == 1);
+}
+
+INLINE void
+String_data::OK()
+{
+ assert(maxlen >= length_i_);
+ assert(bool(data_byte_p_));
+ assert(references >= 1);
+}
+
+
+INLINE
+String_data::String_data()
+{
+ references=0;
+ maxlen = INITIALMAX;
+ data_byte_p_ = new Byte[maxlen + 1];
+ data_byte_p_[0] = 0;
+ length_i_ = 0;
+}
+
+INLINE
+String_data::String_data(String_data const &src)
+{
+ references=0;
+ maxlen = length_i_ = src.length_i_;
+ data_byte_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead.
+ memmove( data_byte_p_, src.data_byte_p_, length_i_ + 1 );
+}
+
+INLINE
+String_data::~String_data()
+{
+ assert(references == 0);
+ delete[] data_byte_p_;
+}
+
+INLINE void
+String_data::setmax(int j)
+{
+ OKW();
+ if (j > maxlen) {
+ delete data_byte_p_;
+ maxlen = j;
+ data_byte_p_ = new Byte[maxlen + 1];
+
+ data_byte_p_[0] = 0;
+ length_i_ = 0;
+ }
+}
+
+/* this is all quite hairy:
+ update of length_i_
+ update of maxlen
+ alloc of buffer
+ copying of buffer
+ needs blondification:
+ split tasks
+ define change authority
+*/
+INLINE void
+String_data::remax(int j)
+{
+ OKW();
+ if (j > maxlen) {
+// maxlen = j; oeps
+// Byte *p = new Byte[maxlen + 1];
+ Byte *p = new Byte[j + 1];
+ memmove( p, data_byte_p_, ( maxlen <? length_i_ ) + 1 );
+ maxlen = j;
+ delete[] data_byte_p_;
+ data_byte_p_ = p;
+ }
+}
+
+INLINE void
+String_data::tighten()
+{ // should be dec'd const
+ maxlen = length_i_;
+ Byte *p = new Byte[maxlen + 1];
+ memmove( p, data_byte_p_, length_i_ + 1 );
+ delete[] data_byte_p_;
+ data_byte_p_ = p;
+}
+// assignment.
+INLINE void
+String_data::set( Byte const* byte_c_l, int length_i )
+{
+ OKW();
+
+ assert( byte_c_l && byte_c_l != data_byte_p_);
+
+ length_i_ = length_i;
+ remax( length_i_ ); // copies too
+ memmove( data_byte_p_, byte_c_l, length_i_ );
+ data_byte_p_[ length_i_ ] = 0;
+}
+
+INLINE
+void
+String_data::set( char const* ch_c_l )
+{
+ set( (Byte const*)ch_c_l, strlen( ch_c_l ) );
+}
+
+
+/// concatenation.
+INLINE void
+String_data::append( Byte const* byte_c_l, int length_i )
+{
+ OK();
+ OKW();
+ int old_i = length_i_;
+
+ length_i_ += length_i;
+ remax( length_i_ );
+ memmove( data_byte_p_ + old_i, byte_c_l, length_i );
+ data_byte_p_[ length_i_ ] = 0;
+}
+
+INLINE
+void
+String_data::operator += ( char const* ch_c_l )
+{
+ append( (Byte const*)ch_c_l, strlen( ch_c_l ) );
+}
+
+
+
+INLINE
+char const*
+String_data::ch_c_l() const
+{
+ return (char const*)data_byte_p_;
+}
+INLINE char*
+String_data::ch_l()
+{
+ return (char*)data_byte_p_;
+}
+
+INLINE Byte const*
+String_data::byte_c_l() const
+{
+ return data_byte_p_;
+}
+
+INLINE Byte*
+String_data::byte_l()
+{
+ OKW();
+ return data_byte_p_;
+}
+
+INLINE
+void
+String_data::trunc(int j)
+{
+ OKW();
+ assert(j >= 0 && j <= length_i_);
+ data_byte_p_[j] = 0;
+ length_i_ = j;
+}
+
+INLINE Byte&
+String_data::operator [](int j)
+{
+ assert(j >= 0 && j <= length_i_);
+ return data_byte_p_[j] ;
+}
+
+INLINE Byte
+String_data::operator [](int j) const
+{
+ assert(j >= 0 && j <= length_i_);
+ return data_byte_p_[j];
+}
+
+
+
+
+#endif // __STRING_UTIL_CC //
--- /dev/null
+/*
+ stringhandle.hh -- declare String_handle
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef STRINGHANDLE_HH
+#define STRINGHANDLE_HH
+#include "fproto.hh"
+
+
+/**
+ Reference counting for strings.
+
+ handles ref. counting, and provides a very thin interface using
+ Byte *
+
+ */
+class String_handle {
+ String_data* data;
+
+ /// decrease ref count. Named kind of like a Tanenbaum semafore
+ void down();
+
+ /// increase ref count
+ void up(String_data *d);
+
+ /** make sure data has only one reference.
+ POST: data->references == 1
+ */
+ void copy();
+
+public:
+ String_handle();
+ ~String_handle();
+ String_handle(String_handle const & src);
+
+ Byte const* byte_c_l() const;
+ char const* ch_c_l() const;
+ Byte* byte_l();
+ char* ch_l();
+
+ void operator =(String_handle const &src);
+ void operator += (char const *s);
+ Byte operator[](int j) const;
+
+ /** Access elements. WARNING: NOT SAFE
+ don't use this for loops. Use byte_c_l()
+ */
+ Byte &operator[](int j);
+ void append( Byte const* byte_c_l, int length_i );
+ void set( Byte const* byte_c_l, int length_i );
+ void operator = (char const *p);
+ void trunc(int j);
+ int length_i() const;
+};
+
+#ifdef STRING_UTILS_INLINED
+#ifndef INLINE
+#define INLINE inline
+#endif
+#include "stringhandle.inl"
+/* we should be resetting INLINE. oh well. */
+#endif
+
+
+#endif // STRINGHANDLE_HH
--- /dev/null
+/* -*-c++-*-
+
+ stringhandle.inl -- implement String_handle
+
+ source file of Flower lib
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#ifndef STRINGHANDLE_INL
+#define STRINGHANDLE_INL
+
+#include <assert.h>
+#include <memory.h>
+
+#include "stringdata.hh"
+#include "stringhandle.hh"
+
+INLINE void
+String_handle::down()
+{
+ if (!(--data->references)) delete data; data = 0;
+}
+
+/// increase ref count
+INLINE void
+String_handle::up(String_data *d)
+{
+ data=d; data->references ++;
+}
+
+INLINE void
+String_handle::copy()
+{
+ if (data->references !=1){
+ String_data *newdata = new String_data(*data);
+ down();
+ up(newdata);
+ }
+}
+
+INLINE
+String_handle::String_handle()
+{
+ up(new String_data);
+}
+
+INLINE
+String_handle::~String_handle()
+{
+ down();
+}
+
+INLINE
+String_handle::String_handle(String_handle const & src)
+{
+ up(src.data);
+}
+
+INLINE Byte*
+String_handle::byte_l()
+{
+ copy();
+ return data->byte_l();
+}
+
+INLINE char*
+String_handle::ch_l()
+{
+ copy();
+ return (char*)data->byte_l();
+}
+
+INLINE Byte
+const* String_handle::byte_c_l() const
+{
+ return data->byte_c_l();
+}
+
+INLINE char const*
+String_handle::ch_c_l() const
+{
+ return (char const*)data->byte_c_l();
+}
+
+INLINE void
+String_handle::operator =(String_handle const &src)
+{
+ if (this == &src)
+ return;
+ down();
+ up(src.data);
+}
+
+INLINE void
+String_handle::operator += (char const *s)
+{
+ copy();
+ *data += s;
+}
+
+
+INLINE Byte
+String_handle::operator[](int j) const
+{
+ return (*data)[j];
+}
+
+// !NOT SAFE!
+// don't use this for loops. Use byte_c_l()
+INLINE Byte &
+String_handle::operator[](int j)
+{
+ copy(); // hmm. Not efficient
+ return data->byte_l()[j];
+}
+
+INLINE void
+String_handle::append( Byte const* byte_c_l, int length_i )
+{
+ copy();
+ data->append( byte_c_l, length_i );
+}
+
+INLINE void
+String_handle::set( Byte const* byte_c_l, int length_i )
+{
+ copy();
+ data->set( byte_c_l, length_i );
+}
+
+INLINE void
+String_handle::operator = (char const *p)
+{
+ copy();
+ data->set( p );
+}
+
+INLINE void
+String_handle::trunc(int j)
+{
+ copy(); data->trunc(j);
+}
+
+INLINE int
+String_handle::length_i() const
+{
+ return data->length_i_;
+}
+
+#endif
-// stringutil.cc
-#ifndef __STRING_UTIL_CC
-#define __STRING_UTIL_CC
+/*
+ stringutil.cc -- generate non-inline members.
-// include only when
-// * reading stringutil.hh, or
-// * string util stuff not inlined
-#if !defined STRING_UTILS_INLINED
+ source file of the LilyPond music typesetter
-#include <assert.h>
-#include <memory.h>
-#include "stringutil.hh"
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
-// namespace StringData { namespaces are broken in this version of g++
-// gcc version 2.7.2.1
+#ifdef STRING_UTILS_INLINED
+#undef STRING_UTILS_INLINED
+#endif
+#ifdef INLINE
+#undef INLINE
+#endif
-StringData::StringData()
-{
- references=0;
- maxlen = INITIALMAX;
- data_by_p_ = new Byte[maxlen + 1];
- data_by_p_[0] = 0;
- length_i_ = 0;
-}
+#define INLINE
-StringData::StringData(StringData const &src)
-{
- references=0;
- maxlen = length_i_ = src.length_i_;
- data_by_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead.
- memmove( data_by_p_, src.data_by_p_, length_i_ + 1 );
-}
-
-
-StringData::~StringData()
-{
- assert(references == 0);
- delete[] data_by_p_;
-}
-
-void
-StringData::setmax(int j)
-{
- OKW();
- if (j > maxlen) {
- delete data_by_p_;
- maxlen = j;
- data_by_p_ = new Byte[maxlen + 1];
-
- data_by_p_[0] = 0;
- length_i_ = 0;
- }
-}
-
-
-void
-StringData::remax(int j)
-{
- OKW();
- if (j > maxlen) {
- maxlen = j;
- Byte *p = new Byte[maxlen + 1];
- memmove( p, data_by_p_, length_i_ + 1 );
- delete[] data_by_p_;
- data_by_p_ = p;
- // length_i_ = strlength_i(data_by_p_);
- }
-}
-
-
-void
-StringData::OKW()
-{
- assert (references == 1);
-}
-
-void
-StringData::OK()
-{
-// can-t do this with binary data
-// assert(strlen(data_by_p_) == size_t(length_i_));
- assert(maxlen >= length_i_);
- assert(bool(data_by_p_));
- assert(references >= 1);
-}
-
-// // needed?
-// well, we can't -> depreciated
-// void update() {
-// length_i_ = strlen (data_by_p_);
-// }
-
-
-void
-StringData::tighten()
-{ // should be dec'd const
- maxlen = length_i_;
- Byte *p = new Byte[maxlen + 1];
- memmove( p, data_by_p_, length_i_ + 1 );
- delete[] data_by_p_;
- data_by_p_ = p;
-}
-
-// assignment.
-void
-StringData::set( Byte const* by_c_l, int length_i )
-{
- OKW();
-
- assert( by_c_l && by_c_l != data_by_p_);
-
- length_i_ = length_i;
- remax( length_i_ );
- memmove( data_by_p_, by_c_l, length_i_ );
- data_by_p_[ length_i_ ] = 0;
-}
-
-
-void
-StringData::set( char const* ch_c_l )
-{
- set( (Byte const*)ch_c_l, strlen( ch_c_l ) );
-}
-
-
-/// concatenation.
-void
-StringData::append( Byte const* by_c_l, int length_i )
-{
- OK();
- OKW();
- int old_i = length_i_;
-
- length_i_ += length_i;
- remax( length_i_ );
- memmove( data_by_p_ + old_i, by_c_l, length_i );
- data_by_p_[ length_i_ ] = 0;
-}
-
-
-void
-StringData::operator += ( char const* ch_c_l )
-{
- append( (Byte const*)ch_c_l, strlen( ch_c_l ) );
-}
-
-char const*
-StringData::ch_c_l() const
-{
- return (char const*)data_by_p_;
-}
-
-char*
-StringData::ch_l()
-{
- return (char*)data_by_p_;
-}
-
-Byte const*
-StringData::by_c_l() const
-{
- return data_by_p_;
-}
-
-// idem, non const
-Byte*
-StringData::by_l()
-{
- OKW();
- return data_by_p_;
-}
-
-void
-StringData::trunc(int j)
-{
- OKW();
- assert(j >= 0 && j <= length_i_);
- data_by_p_[j] = 0;
- length_i_ = j;
-}
-
-Byte&
-StringData::operator [](int j)
-{
- assert(j >= 0 && j <= length_i_);
- return data_by_p_[j] ;
-}
-
-Byte
-StringData::operator [](int j) const
-{
- assert(j >= 0 && j <= length_i_);
- return data_by_p_[j];
-}
-
-
-// } namespace broken
-
-
-
-
-// namespace String_handle {
-
-
-void
-String_handle::down()
-{
- if (!(--data->references)) delete data; data = 0;
-}
-
-/// increase ref count
-void
-String_handle::up(StringData *d)
-{
- data=d; data->references ++;
-}
-
-void
-String_handle::copy()
-{
- if (data->references !=1){
- StringData *newdata = new StringData(*data);
- down();
- up(newdata);
- }
-}
-
-String_handle::String_handle()
-{
- up(new StringData);
-}
-String_handle::~String_handle()
-{
- down();
-}
-String_handle::String_handle(String_handle const & src)
-{
- up(src.data);
-}
-
-Byte*
-String_handle::by_l()
-{
- copy();
- return data->by_l();
-}
-
-char*
-String_handle::ch_l()
-{
- copy();
- return (char*)data->by_l();
-}
-
-Byte
-const* String_handle::by_c_l() const
-{
- return data->by_c_l();
-}
-
-char const*
-String_handle::ch_c_l() const
-{
- return (char const*)data->by_c_l();
-}
-
-void
-String_handle::operator =(String_handle const &src)
-{
- if (this == &src)
- return;
- down();
- up(src.data);
-}
-
-void
-String_handle::operator += (char const *s)
-{
- copy();
- *data += s;
-}
-
-
-Byte
-String_handle::operator[](int j) const
-{
- return (*data)[j];
-}
-
-// !NOT SAFE!
-// don't use this for loops. Use by_c_l()
-Byte &
-String_handle::operator[](int j)
-{
- copy(); // hmm. Not efficient
- return data->by_l()[j];
-}
-
-void
-String_handle::append( Byte const* by_c_l, int length_i )
-{
- copy();
- data->append( by_c_l, length_i );
-}
-
-void
-String_handle::set( Byte const* by_c_l, int length_i )
-{
- copy();
- data->set( by_c_l, length_i );
-}
-
-void
-String_handle::operator = (char const *p)
-{
- copy();
- data->set( p );
-}
-
-void
-String_handle::trunc(int j)
-{
- copy(); data->trunc(j);
-}
-
-int
-String_handle::length_i() const
-{
- return data->length_i_;
-}
-
-
-// } namespaces broken
-
-
-#endif // not STRING_UTILS_INLINED //
-
-#endif // __STRING_UTIL_CC //
+#include "stringhandle.hh"
+#include "stringdata.hh"
+#include "stringdata.inl"
+#include "stringhandle.inl"
+++ /dev/null
-#ifndef __STRING_UTIL_HH
-#define __STRING_UTIL_HH
-#if 0
-#if !defined(NDEBUG)
-#define NDEBUG BLONDE
-#endif
-#endif
-const INITIALMAX=8;
-class String_handle;
-
-
-typedef unsigned char Byte;
-
-#ifdef STRING_UTILS_INLINED
-#define INLINE inline
-#else
-#define INLINE
-#endif
-
-/**Internal String struct.
- the data itself. Handles simple tasks (resizing, resetting)
- */
-class StringData {
- // GNU malloc: storage overhead is 8 bytes anyway.
-
-friend class String_handle;
- int maxlen; // maxlen is arraysize-1
-
- int length_i_;
- Byte* data_by_p_;
- int references;
-
- /// init to ""
- INLINE StringData();
-
- /// init from src. Conservative allocation.
- INLINE StringData(StringData const &src);
-
- ~StringData();
-
- /** POST: maxlen >= j.
- IN: j, maximum stringlength_i_.
- contents thrown away.
- */
- INLINE void setmax(int j);
-
- /** POST: maxlen >= j.
- IN: j, maximum stringlength_i_.
- contents are kept if it grows.
- */
- INLINE void remax(int j);
-
- /// check if writeable.
- INLINE void OKW();
-
- /// check state.
- INLINE void OK();
-
- /// reduce memory usage.
- INLINE void tighten();
-
- // assignment.
- INLINE void set( Byte const* by_c_l, int length_i );
-
- INLINE void set( char const* ch_c_l );
-
- /// concatenation.
- INLINE void append( Byte const* by_c_l, int length_i );
-
- INLINE void operator += ( char const* ch_c_l );
-
- INLINE char const* ch_c_l() const;
-
- INLINE char* ch_l();
-
- INLINE Byte const* by_c_l() const;
-
- // idem, non const
- INLINE Byte* by_l();
-
- INLINE void trunc(int j);
-
- /** not really safe. Can alter length_i_ without StringData knowing it.
- */
- INLINE Byte &operator [](int j);
- INLINE Byte operator [](int j) const;
-};
-
-
-
-
-/**
- Reference counting for strings.
-
- handles ref. counting, and provides a very thin interface using
- Byte *
-
- */
-class String_handle {
- StringData* data;
-
- /// decrease ref count. Named kind of like a Tanenbaum semafore
- INLINE void down();
-
- /// increase ref count
- INLINE void up(StringData *d);
-
- /** make sure data has only one reference.
- POST: data->references == 1
- */
- INLINE void copy();
-
-public:
- INLINE String_handle();
- INLINE ~String_handle();
- INLINE String_handle(String_handle const & src);
-
- INLINE Byte const* by_c_l() const;
- INLINE char const* ch_c_l() const;
- INLINE Byte* by_l();
- INLINE char* ch_l();
-
- INLINE void operator =(String_handle const &src);
- INLINE void operator += (char const *s);
- INLINE Byte operator[](int j) const;
-
- /** Access elements. WARNING: NOT SAFE
- don't use this for loops. Use by_c_l()
- */
- INLINE Byte &operator[](int j);
- INLINE void append( Byte const* by_c_l, int length_i );
- INLINE void set( Byte const* by_c_l, int length_i );
- INLINE void operator = (char const *p);
- INLINE void trunc(int j);
- INLINE int length_i() const;
-};
-
-#if 0
-#ifdef NDEBUG
-#if (NDEBUG == BLONDE)
-#undef NDEBUG
-#endif
-#endif
-#endif
-
-#ifdef STRING_UTILS_INLINED
-#include "stringutil.cc"
-#endif
-
-#endif // __STRING_UTIL_HH //
default:
$(MAKE) -C ..
-DISTFILES=Makefile $(hdr)
+DISTFILES=Makefile $(allhdr)
dist:
ln $(DISTFILES) $(DDIR)/$(SUBDIR)
clean:
rm -f parser.hh
+ rm -f midi-parser.hh
+++ /dev/null
-/*
- complexcolumn.hh -- declare Complex_column
-
- source file of the LilyPond music typesetter
-
- (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
-*/
-
-
-#ifndef COMPLEXCOLUMN_HH
-#define COMPLEXCOLUMN_HH
-
-#include "stcol.hh"
-
-/// column of Complex_staff: store one request
-struct Complex_column : Staff_column {
-
- Array<Request*> first_l_arr_;
- Array<Request*> second_l_arr_;
-
- Complex_staff* staff_l_;
-
- /* *************** */
-
- Slur_req *find_slur(Voice *);
-
- void typeset_musical_item(Item *);
- void typeset_breakable_items(Array<Item *> &pre_p_arr,
- Array<Item *> &nobreak_p_arr,
- Array<Item *> &post_p_arr);
- virtual void setup_one_request(Request*);
-
- Complex_column(Complex_staff*rs);
-};
-
-#endif // COMPLEXCOLUMN_HH
#include "stcol.hh"
#include "staff.hh"
#include "staffwalker.hh"
-#include "complexcolumn.hh"
-
-/// Complex staff: one voicegroup at a time
+///
struct Complex_staff : Staff {
- /// indirection to the PStaff.
- PStaff *pstaff_l_;
/* *************** */
- Staff_column*create_col();
+
virtual void set_output(PScore *);
virtual Staff_walker *get_walker_p();
- Complex_staff();
};
#endif // COMPLEXSTAF_HH
Complex_walker(Complex_staff*);
~Complex_walker();
- Complex_column *col();
Complex_staff *staff();
private:
};
--- /dev/null
+/*
+ inputfile.hh -- declare Input_file
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#ifndef INPUT_FILE_HH
+#define INPUT_FILE_HH
+#include <FlexLexer.h>
+#include "proto.hh"
+#include "fproto.hh"
+#include "varray.hh"
+#include "string.hh"
+
+struct Input_file {
+ istream* is;
+ char const* defined_ch_c_l_;
+ Source_file* sourcefile_l_;
+ int line;
+ String name;
+
+ Input_file(String);
+ ~Input_file();
+};
+
+#endif // INPUT_FILE_HH
/// paper_, staffs_ and commands_ form the problem definition.
Paperdef *paper_p_;
- Mididef* midi_p_;
+ Midi_def* midi_p_;
IPointerList<Input_staff*> staffs_;
Input_music * score_wide_music_p_;
~Input_score();
/// construction
void set(Paperdef*);
- void set(Mididef* midi_p);
+ void set(Midi_def* midi_p);
void print() const;
Score*parse();
void set(Input_music*);
+/*
+ lexer.hh -- declare My_flex_lexer
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
#ifndef LEXER_HH
#define LEXER_HH
#include <FlexLexer.h>
void kill_lexer();
void set_lexer();
-struct Input_file {
- istream* is;
- char const* defined_ch_c_l_;
- Source_file* sourcefile_l_;
- int line;
- String name;
-
- Input_file(String);
- ~Input_file();
-};
-
-
/// lexer with provisions for include files.
struct My_flex_lexer : yyFlexLexer {
+++ /dev/null
-//
-// lyriccolumn.hh -- declare Lyric_column
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-
-#ifndef LYRIC_COLUMN_HH
-#define LYRIC_COLUMN_HH
-
-#include "key.hh"
-#include "stcol.hh"
-#include "staff.hh"
-
-/// (lcol)
-struct Lyric_column : Staff_column {
-
- Array<Lyric_req*> lreq_l_array_;
- Lyric_staff* lstaff_l_;
-
- void typeset_item(Item *);
- virtual void setup_one_request(Request*);
-
- Lyric_column(Lyric_staff*rs);
-};
-
-#endif // LYRIC_COLUMN_HH
-
-
-
-
Hungarian prefix lstaff
*/
struct Lyric_staff : Staff {
- PStaff* pstaff_l_;
-
- Staff_column* create_col();
virtual void set_output(PScore *);
virtual Staff_walker *get_walker_p();
- Lyric_staff();
};
#endif // LYRICSTAFF_HH
#include "proto.hh"
#include "grouping.hh"
#include "staffwalker.hh"
-#include "lyriccolumn.hh"
/// a simple walker which collects words, and then print them, first on top
struct Lyric_walker: Staff_walker {
virtual void process_requests();
Lyric_walker(Lyric_staff* lstaff_l);
- Lyric_column* lcol_l();
Lyric_staff* lstaff_l();
};
Input_score* current_iscore_l();
String find_file(String);
const char *get_version();
-extern Source* source_global_l;
+extern Source* source_l_g;
+extern bool only_midi;
+
+extern String default_out_fn;
#endif
+++ /dev/null
-//
-// midicolumn.hh -- declare Midi_column
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-
-#ifndef MIDI_COLUMN_HH
-#define MIDI_COLUMN_HH
-
-#include "key.hh"
-#include "stcol.hh"
-#include "staff.hh"
-
-/// (mcol)
-struct Midi_column : Staff_column {
-
- Array<Melodic_req*> melreq_l_array_;
- Midi_staff* mstaff_l_;
-
- void note_on( Midi_track* midi_track_l );
- void note_off( Midi_track* midi_track_l, Moment next );
- virtual void setup_one_request(Request*);
-
- Midi_column(Midi_staff*rs);
-};
-
-#endif // MIDI_COLUMN_HH
-
/**
*/
-struct Mididef {
+struct Midi_def {
/// output file name
String outfile_str_;
/// duration of whole note
Real whole_seconds_f_;
- Mididef();
- Mididef(Mididef const& midi_c_r);
- ~Mididef();
+ Midi_def();
+ Midi_def(Midi_def const& midi_c_r);
+ ~Midi_def();
Real duration_to_seconds_f(Moment);
int get_tempo_i( Moment moment );
#ifndef MIDI_ITEM_HH
#define MIDI_ITEM_HH
+#include "string.hh"
+#include "proto.hh"
struct Midi_item {
- /* *************** */
- static String int2varlength_str( int i );
- virtual void output_midi( Midi_stream& midi_stream_r );
- virtual String str() = 0;
+ /* *************** */
+ static String int2varlength_str( int i );
+ virtual void output_midi( Midi_stream& midi_stream_r );
+ virtual String str() = 0;
};
struct Midi_note : public Midi_item {
- /* *************** */
- int const c0_pitch_i_c_ = 60;
- Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo );
+ /* *************** */
+ int const c0_pitch_i_c_ = 60;
+ Byte dynamic_byte_;
+
+ /**
+ Generate a note-event on a channel pitch.
+
+ @param #melreq_l# the pitch. If null, then output a silent C
+ #on_b# turn on?
+ */
+ Midi_note( Melodic_req* melreq_l, int channel_i, bool on_b );
- virtual String str();
+ virtual String str();
- int channel_i_;
- int on_bo_;
- int pitch_i_;
+ int channel_i_;
+ int on_b_;
+ int pitch_i_;
};
struct Midi_duration : public Midi_item {
- /* *************** */
- Midi_duration( Real seconds_f );
+ /* *************** */
+ Midi_duration( Real seconds_f );
- virtual String str();
+ virtual String str();
- Real seconds_f_;
+ Real seconds_f_;
};
struct Midi_chunk : Midi_item {
- /* *************** */
- Midi_chunk();
+ /* *************** */
+ Midi_chunk();
- void add( String str );
- void set( String header_str, String data_str, String footer_str );
- virtual String str();
+ void add( String str );
+ void set( String header_str, String data_str, String footer_str );
+ virtual String str();
private:
- String data_str_;
- String footer_str_;
- String header_str_;
+ String data_str_;
+ String footer_str_;
+ String header_str_;
};
struct Midi_header : Midi_chunk {
- /* *************** */
- Midi_header( int format_i, int tracks_i, int tempo_i );
+ /* *************** */
+ Midi_header( int format_i, int tracks_i, int tempo_i );
};
struct Midi_track : Midi_chunk {
- /* *************** */
- int number_i_;
- Midi_track( int number_i );
+ /* *************** */
+ int number_i_;
+ Midi_track( int number_i );
- void add( int delta_time_i, String event );
+ void add( int delta_time_i, String event );
// void add( Moment delta_time_moment, Midi_item& mitem_r );
- void add( Moment delta_time_moment, Midi_item* mitem_l );
+ void add( Moment delta_time_moment, Midi_item* mitem_l );
};
#endif // MIDI_ITEM_HH //
--- /dev/null
+/*
+ midioutput.hh -- declare Midi_output
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef MIDIOUTPUT_HH
+#define MIDIOUTPUT_HH
+#include "pscore.hh"
+
+struct Midi_output {
+ Midi_stream* midi_stream_l_;
+ Midi_output(Score* score_l, Midi_def* );
+ void do_staff(Staff*st_l, int count);
+};
+#endif // MIDIOUTPUT_HH
+++ /dev/null
-//
-// midiscorewalker.hh -- declare Midi_score_walker
-//
-// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen <jan@digicash.com>
-//
-
-#ifndef MIDI_SCORE_WALKER_HH
-#define MIDI_SCORE_WALKER_HH
-
-#include "proto.hh"
-#include "grouping.hh"
-#include "scorewalker.hh"
-#include "midiitem.hh"
-
-/// a simple walker which collects midi stuff, and then outputs
-struct Midi_score_walker : Score_walker {
- Midi_stream* midi_stream_l_;
-
- /* *************** */
- virtual void process();
-
- Midi_score_walker( Score* score_l, Midi_stream* midi_stream_l );
-};
-
-
-#endif // MIDI_SCORE_WALKER_HH
-
-
+++ /dev/null
-/*
- midistaff.hh -- part of LilyPond
-
- copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
- */
-
-#ifndef MIDI_STAFF_HH
-#define MIDI_STAFF_HH
-
-#include "staff.hh"
-
-///(mstaff)
-struct Midi_staff : Staff {
-// PStaff* pstaff_l_;
-
- Staff_column* create_col();
- virtual void set_output(PScore *);
- void midi( Midi_stream* midi_stream_l, int track_i );
- virtual Staff_walker *get_walker_p();
- Midi_staff();
-};
-
-#endif // MIDI_STAFF_HH
-
-
-
-
-
-//
-// midiwalker.hh -- declare Midi_walker
-//
-// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen <jan@digicash.com>
-//
+/*
+ midiwalker.hh -- declare Midi_walker
+
+ (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen <jan@digicash.com>
+ */
#ifndef MIDIWALKER_HH
#define MIDIWALKER_HH
#include "proto.hh"
#include "grouping.hh"
#include "staffwalker.hh"
+#include "pcursor.hh"
+#include "pqueue.hh"
+
+
+/**
+ a simple walker which collects midi stuff, and then outputs.
+
+ Should derive from Staff_walker
+ */
+class Midi_walker : public PCursor<Staff_column*> {
+ Midi_track *track_l_;
+ PQueue<Melodic_req*, Moment> stop_notes;
+ Moment last_moment_;
-/// a simple walker which collects midi stuff, and then outputs
-struct Midi_walker: Staff_walker {
-// Midi_stream* midi_stream_l_;
/* *************** */
- virtual void process_requests();
- Midi_walker( Midi_staff* mstaff_l );
- Midi_column* mcol_l();
- Midi_staff* mstaff_l();
+ /// output notestop events
+ void do_stop_notes(Moment);
+public:
+
+ Midi_walker(Staff*, Midi_track*);
+ void process_requests();
+ ~Midi_walker();
};
/// which one (left =0)
int rank() const;
- /// does this column have items, does it have spacings attached?
- bool used() const;
+ /// does this column have items
+ bool used_b() const;
void add(Item *i);
PCol(PCol * parent);
/**
- which col comes first?.
- signed compare on columns.
+ which col comes first?.
+ signed compare on columns.
- @return < 0 if c1 < c2.
+ @return < 0 if c1 < c2.
*/static int compare(const PCol &c1, const PCol &c2);
struct Clef_item;
struct Col_hpositions;
struct Colinfo;
-struct Complex_column;
struct Complex_music;
struct Complex_staff;
struct Complex_walker;
struct Meter_change_req;
struct Meter;
struct Meter_register;
-struct Midi_column;
-struct Mididef;
+struct Midi_def;
struct Midi_duration;
struct Midi_header;
struct Midi_item;
+struct Midi_output;
struct Midi_pitch;
struct Midi_staff;
struct Midi_stream;
struct Midi_track;
struct Midi_walker;
struct Mixed_qp;
+class My_midi_lexer;
+class My_midi_parser;
+class Midi_event;
+class Midi_score;
+class Midi_track;
struct Molecule;
struct Musical_req;
struct Music_general_chord;
void preprocess();
bool breakable_b();
bool musical_b() { return musical_b_; }
- bool used();
+ bool used_b();
void print() const;
struct Score {
/// paper_, staffs_ and commands_ form the problem definition.
Paperdef *paper_p_;
- Mididef *midi_p_;
+ Midi_def *midi_p_;
IPointerList<Staff*> staffs_;
/// "runtime" fields for setting up spacing
/* *************************************************************** */
/// construction
- Score(Paperdef*);
+ Score();
~Score();
void add(Staff*);
/// output to file
void output(String fn);
- /// do midi stuff
- void midi();
-
+
+ ///
+ void set(Midi_def* midi_p);
///
- void set(Mididef* midi_p);
+ void set(Paperdef* midi_p);
// standard
void OK() const;
Moment last() const;
private:
+ void paper_output();
void setup_music();
void process_music();
+ /// do midi stuff
+ void midi();
+
+ /// do paper stuff
+ void paper();
+
// utils:
PCursor<Score_column*> create_cols(Moment);
*/
class Score_walker : public PCursor<Score_column *>
{
+ Score* score_l_;
/// walkers for the individual staves.
Array<Staff_walker *> walker_p_arr_;
Array<Staff_walker *> disallow_break_walk_l_arr;
IPointerList<Source_file*> sourcefile_p_iplist_;
};
+
+// ugh
+extern Source* source_l_g;
+
#endif // SOURCE_HH //
/// base class for a collection of voices.
class Staff {
- Staff_column *get_col(Moment, PCursor<Staff_column*> * last= 0);
Staff(const Staff&src);
/// synchronous horizontal stuff
IPointerList<Voice*> voice_list_;
+ Staff_column *get_col(Moment, PCursor<Staff_column*> * last= 0);
public:
/// runtime field
- IPointerList<Staff_column*> cols;
+ IPointerList<Staff_column*> cols_;
Score *score_l_;
PScore *pscore_l_;
-
+ PStaff *pstaff_l_;
+
/* *************************************************************** */
void add(const PointerList<Voice*> &s);
virtual Staff_walker *get_walker_p()=0;
virtual ~Staff() { }
protected:
- virtual Staff_column * create_col()=0;
+
};
#endif
/// store simultaneous requests
class Staff_column {
+
Staff_column(Staff_column const&);
+
public:
+ Array<Request*> musicalreq_l_arr_;
+ Array<Request*> commandreq_l_arr_;
+ Staff * staff_l_;
+
/// fields to collect timing data vertically.
Array<Timing_req*> timing_req_l_arr_;
Score_column *musical_column_l_, *command_column_l_;
void set_cols(Score_column *c1, Score_column *c2);
void add(Voice_element*ve);
void OK() const;
- virtual ~Staff_column();
-
-
+ ~Staff_column();
+ void typeset_breakable_items(Array<Item *> &pre_p_arr,
+ Array<Item *> &nobreak_p_arr,
+ Array<Item *> &post_p_arr);
+ void typeset_musical_item(Item *i);
protected:
- virtual void setup_one_request(Request*)=0;
-
+ void setup_one_request(Request*);
};
cadenza {1}
grouping{1*4}
}
+ paper {}
midi { tempo 4:80 }
- staff { midi music { cad } }
}
\ No newline at end of file
[ a8 a8 a8 a8 a8 ] %
[ a8 ] %
% segfault
-% { \music{ [ bes^"1"( )a bes-. g-. ] a4-.^"4" } \music{ [ e ] } \music{ [ c ] } } |
+ { \music{ [ bes^"1"( )a bes-. g-. ] a4-.^"4" } \music{ [ e ] } \music{ [ c ] } } |
a ) b ] c % warning
& % ok; error
a b ) ] % ok; error
geometric 1.4
unitspace 3.0 cm
}
-% staff { ritme }%broken for now
+% staff { ritme } % broken for now
staff { melody }
commands {
meter {4* 4}
- partial 8
- skip 3*2
+ partial {8}
+ skip {1*8}
+ skip {3*2 }
bar ":|:"
- skip 2*1
+ skip {1*2}
meter {2*4}
}
commands {
meter {2*4}
% key $fis$
- skip 56*2
+ skip {56*2}
% key $bes es as$
- skip 8*2
+ skip {8*2}
meter {6*8}
- skip 48*8
+ skip{ 48*8}
meter {2*4}
- skip 16*2
+ skip {16*2}
% key $fis$
}
paper {
-% unitspace 16mm
unitspace 24mm
width 195mm
output "martien.out"
}
- staff {
- midi_track
- music { alto }
- }
- staff {
- midi_track
- music { violin1 }
- }
- staff {
- midi_track
- music { violin2 }
- }
- staff {
- midi_track
- music { cello }
- }
midi {
tempo 4:80
}
% midi.ly
% test source for lilypond-s midi output
-
-% BUG: 2e noot van begeleiding bij g2 niet gespeeld.
-% BUG: rust (5e maat) niet gespeeld.
melodie = music {
$\clef\violin
- c c | g g | a a | g2 | r2
+ c c | g g | a a | g2
f f | e e | d d8.( e16 | )c2 | % :|
$
}
$
\clef \bass
\octave{`}
- c 'c | 'e 'c | 'f 'c | 'e 'c | r2
+ c 'c | 'e 'c | 'f 'c | 'e 'c
'd b | 'c a | f g | c2 |
$
}
}
score {
-% staff { mstaf }
-% staff { bass_staf }
-% paper { unitspace 2.5cm }
- % in own audio { } block iso score { } ?
- % allow no score { } block ?
-
- staff { midi music { melodie } }
- staff { midi music { begeleiding } }
-% staff { midi music { bla } }
+ staff { mstaf }
+ staff { bass_staf }
midi {
tempo 4:120
}
bar "||"
}
midi { tempo 4:70 }
- staff { midi music { horn } }
}
paper {
symboltables { table_sixteen }
width 195mm
-% unitspace 12mm % this should do, really
unitspace 9mm % to get lily to use only three lines
geometric 1.4
output "scsii-menuetto.out"
}
- staff {
- midi music { ii_menuetto }
- }
midi {
tempo 4:120
output "scsii-menuetto.midi"
%%6
{ \multivoice \music{ \stem{ 1 } [ `d `e `g `e `g `e ] } \music { \stem{ -1 } ``bes2 r4 } } |
%%7
-% this (one note missing) fails with assertion:
-% lilypond: src/beam.cc:144: void Beam::set_grouping(struct Rhythmic_grouping, struct Rhythmic_grouping): Assertion `cur.children.size() == stems.size()' failed.
-% { \multivoice \music{ \stem{ 1 } [ `cis `e `g `e `g ] } \music { \stem{ -1 } ``a2 r4 } } |
{ \multivoice \music{ \stem{ 1 } [ `cis `e `g `e `g e ] } \music { \stem{ -1 } ``a2 r4 } } |
%%8
{ \multivoice \music{ \stem{ 1 } [ `d `a d `a d `a ] } \music { \stem{ -1 } `d2 r4 } } |
}
score {
-% staff {
-% lyric
- % music { tekst1 }
- % music { tekst2 }
-% }
-% staff {
-% melodic
-% music { melodie }
-% }
-% staff {
-% melodic
-% music { begeleiding }
-% }
+ staff {
+ lyric
+ music { tekst1 }
+ music { tekst2 }
+ }
+ staff {
+ melodic
+ music { melodie }
+ }
+ staff {
+ melodic
+ music { begeleiding }
+ }
commands {
meter {3*4}
}
width 195mm
% on two pages...
-% unitspace 10mm
-% geometric 1.2
unitspace 9mm
geometric 1.2
output "standchen.out"
}
- staff { midi music { melodie } }
- staff { midi music { begeleiding } }
midi {
tempo 4:50
}
}
commands {
meter {2 * 4}
-% skip 24*2
+ skip {24*2}
% bar "||"
}
- staff { midi_track music { melodie } }
- staff { midi_track music { begeleiding } }
midi {
tempo 4:120
}
r |
r |
r |
- r |
+ r1 |
r8 [c16 B] [c8 G] [As c16 B] [c8 d] |
[G c16 B] [c8 d] [F16 G] As4 [G16 F] |
$}
-basstaf = staff { melodic
- music { bassdux }
-}
-
-score {
- staff { melodic
+trebstaf = staff { melodic
% every "music {} " in a staff has its own "voicegroup"
music { dux }
music { comes }
}
+
+basstaf = staff { melodic
+ music { bassdux }
+}
+
+score {
staff { basstaf }
+ staff { trebstaf }
+
commands {
meter {4*4}
grouping {2*2}
key {$bes es as$}
}
- staff { midi music { dux } }
- staff { midi music { comes } }
- staff { midi music { bassdux } }
+ paper {}
midi {
tempo 4:80
}
win32:
$(MAKE) -C .. Windows_NT
-DISTFILES=Makefile $(mycc) $(othersrc)
+DISTFILES=Makefile $(allcc) $(othersrc)
dist:
ln $(DISTFILES) $(DDIR)/$(SUBDIR)
-TAGS: $(mycc)
- etags -CT $(mycc)
+TAGS: $(allcc)
+ etags -CT $(allcc)
clean:
rm -f $(gencc)
#include "bar.hh"
#include "commandrequest.hh"
#include "complexwalker.hh"
-#include "complexcolumn.hh"
#include "sccol.hh"
iter_top(cols_,i);
for (; i.ok(); i++) {
- assert(i->used());
+ assert(i->used_b());
PCursor<Score_column*> j(i+1);
if (i->musical_b()) {
assert(j.ok());
+++ /dev/null
-/*
- complexcolumn.cc -- implement Complex_column
-
- source file of the LilyPond music typesetter
-
- (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
-*/
-#include "voice.hh"
-#include "debug.hh"
-#include "complexcolumn.hh"
-#include "pscore.hh"
-#include "request.hh"
-#include "pscore.hh"
-#include "sccol.hh"
-#include "complexstaff.hh"
-#include "misc.hh"
-
-void
-Complex_column::typeset_musical_item(Item *i)
-{
- assert(i);
- Score_column * sccol_l = musical_column_l_;
- staff_l_->pscore_l_->typeset_item(i, sccol_l->pcol_l_,
- staff_l_->pstaff_l_);
-}
-
-Complex_column::Complex_column(Complex_staff *staff_l)
-{
- staff_l_ = staff_l;
-}
-
-void
-Complex_column::setup_one_request(Request * j)
-{
- if (j->nonmus()) // ugh
- first_l_arr_.push(j);
- else if (j->musical())
- second_l_arr_.push(j);
-}
-
-/**
- align items in #item_l_arr#, return the width.
- */
-Interval
-align_items(Array<Item*> item_l_arr)
-{
- Interval wid(0,0);
- for (int i =0; i < item_l_arr.size(); i++) {
- Interval item_width= item_l_arr[i]->width();
- item_l_arr[i]->translate(Offset( wid.right - item_width.left ,0));
- wid.unite(item_width);
- }
- return wid;
-}
-
-void
-translate_items(Real x, Array<Item*> item_l_arr)
-{
- for (int i =0; i < item_l_arr.size(); i++)
- item_l_arr[i]->translate(Offset(x, 0));
-}
-/*
- UGR
- This still sux
- */
-void
-Complex_column::typeset_breakable_items(Array<Item *> &pre_p_arr,
- Array<Item *> &nobreak_p_arr,
- Array<Item *> &post_p_arr)
-{
- PCol * c= command_column_l_->pcol_l_;
- PScore *ps_l=staff_l_->pscore_l_;
- if (!c->breakable_b()) {
- for (int i =0; i < pre_p_arr.size(); i++)
- delete pre_p_arr[i];
- pre_p_arr.set_size(0);
- for (int i =0; i < post_p_arr.size(); i++)
- delete post_p_arr[i];
- post_p_arr.set_size(0);
- }
-
-
- for (int i =0; i < pre_p_arr.size(); i++) {
- ps_l->typeset_item(pre_p_arr[i], c, staff_l_->pstaff_l_,0);
- }
- for (int i =0; i < nobreak_p_arr.size(); i++) {
- ps_l->typeset_item(nobreak_p_arr[i], c, staff_l_->pstaff_l_,1);
- }
- for (int i =0; i < post_p_arr.size(); i++) {
- ps_l->typeset_item(post_p_arr[i], c, staff_l_->pstaff_l_,2);
- }
-
- Interval pre_wid= align_items(pre_p_arr);
- translate_items( -pre_wid.right, pre_p_arr);
- align_items(nobreak_p_arr);
- Interval post_wid =align_items(post_p_arr);
- translate_items (-post_wid.left , post_p_arr);
-
- pre_p_arr.set_size(0);
- post_p_arr.set_size(0);
- nobreak_p_arr.set_size(0);
-}
#include "debug.hh"
#include "complexstaff.hh"
#include "complexwalker.hh"
-#include "complexcolumn.hh"
#include "score.hh"
#include "pscore.hh"
#include "staffsym.hh"
pscore_l_ = pscore_l;
pscore_l_->add(pstaff_l_);
-
-
- Staff_symbol *span_p = new Staff_symbol(5);
-
+ Staff_symbol *span_p = new Staff_symbol(NO_LINES);
Score_column* col_last
=score_l_->find_col(score_l_->last(), false);
pscore_l_->typeset_spanner(span_p, pstaff_l_);
}
-Complex_staff::Complex_staff()
-{
- pstaff_l_ = 0;
-}
-
-Staff_column*
-Complex_staff::create_col()
-{
- return new Complex_column(this);
-}
Staff_walker *
Complex_staff::get_walker_p()
void
Complex_walker::process_requests()
{
- Complex_column*c = col();
+ Staff_column*c =ptr();
- for (int i=0; i < c->first_l_arr_.size(); i++) {
- try_request(c->first_l_arr_[i]);
+ for (int i=0; i < c->commandreq_l_arr_.size(); i++) {
+ try_request(c->commandreq_l_arr_[i]);
}
- for (int i=0; i < c->second_l_arr_.size(); i++) {
- try_request(c->second_l_arr_[i]);
+ for (int i=0; i < c->musicalreq_l_arr_.size(); i++) {
+ try_request(c->musicalreq_l_arr_[i]);
}
regs_process_requests();
if (elem_p->spanner())
pscore_l_->typeset_spanner(elem_p->spanner(), staff()->pstaff_l_);
else
- col()->typeset_musical_item(elem_p->item());
+ ptr()->typeset_musical_item(elem_p->item());
}
Complex_walker::Complex_walker(Complex_staff*s)
return (Complex_staff*) staff_l_;
}
-Complex_column*
-Complex_walker::col()
-{
- return (Complex_column*) *(*this);
-}
void
Complex_walker::do_pre_move()
key_reg_p_->pre_move_processing();
meter_reg_p_->pre_move_processing();
- col()->typeset_breakable_items(prebreak_item_p_arr_,
+ ptr()->typeset_breakable_items(prebreak_item_p_arr_,
nobreak_item_p_arr_,
postbreak_item_p_arr_);
}
}
void
-Input_score::set(Mididef* midi_p)
+Input_score::set(Midi_def* midi_p)
{
delete midi_p_;
midi_p_ = midi_p;
Input_score::Input_score(Input_score const&s)
{
paper_p_ = (s.paper_p_)? new Paperdef(*s.paper_p_) :0;
+ midi_p_ = (s.midi_p_)? new Midi_def(*s.midi_p_) : 0;
defined_ch_c_l_ = s.defined_ch_c_l_;
errorlevel_i_ = s.errorlevel_i_;
score_wide_music_p_ = (s.score_wide_music_p_) ?
Score*
Input_score::parse()
{
- Paperdef* paper_p=new Paperdef(*paper_p_);
- Score *s_p = new Score(paper_p);
+ Score *s_p = new Score;
s_p->defined_ch_c_l_= defined_ch_c_l_;
s_p->errorlevel_i_ = errorlevel_i_;
- s_p->set(midi_p_);
- midi_p_ = 0;
+ if (midi_p_)
+ s_p->set(new Midi_def(*midi_p_));
+ if (paper_p_)
+ s_p->set( new Paperdef(*paper_p_));
for (iter_top(staffs_,i); i.ok(); i++) {
Staff* staf_p=i->parse(s_p, score_wide_music_p_);
#include "staff.hh"
#include "complexstaff.hh"
#include "lyricstaff.hh"
-#include "midistaff.hh"
+
#include "lexer.hh"
p = new Complex_staff;
else if (type == "lyric")
p = new Lyric_staff;
- else if (type == "midi")
- p = new Midi_staff;
else {
error( "Unknown staff-type `" + type +"\'", defined_ch_c_l_ );
exit( 1 );
+/*
+ lexerinit.cc -- implement some stuff
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
#include <iostream.h>
#include <strstream.h>
#include "proto.hh"
{
return lexer;
}
-
-Input_file::Input_file(String s)
-{
- name = s;
- line = 1;
- String pf(s);
- if (pf=="") {
- is = &cin;
- defined_ch_c_l_ = 0;
- sourcefile_l_ = 0;
- }
- else {
- Source_file* sourcefile_p = new Source_file( pf );
- source_global_l->add( sourcefile_p );
- sourcefile_l_ = sourcefile_p;
- is = sourcefile_l_->istream_l();
- defined_ch_c_l_ = sourcefile_l_->ch_c_l();
- }
- cout << "["<<pf<<flush;
-}
-
-Input_file::~Input_file()
-{
- cout << "]" << flush;
-}
+++ /dev/null
-#include "musicalrequest.hh"
-#include "voice.hh"
-#include "staffwalker.hh"
-#include "debug.hh"
-#include "staff.hh"
-#include "lyricstaff.hh"
-#include "lyriccolumn.hh"
-#include "sccol.hh"
-#include "pscore.hh"
-#include "main.hh"
-
-Lyric_column::Lyric_column(Lyric_staff* lstaff_l)
-{
- lstaff_l_ = lstaff_l;
-}
-
-void
-Lyric_column::setup_one_request(Request*req_l)
-{
- if (req_l->lreq_l())
- lreq_l_array_.push(req_l->lreq_l());
-}
-
-void
-Lyric_column::typeset_item(Item *i)
-{
- lstaff_l_->pscore_l_->typeset_item(i, musical_column_l_->pcol_l_,
- lstaff_l_->pstaff_l_);
-}
#include "debug.hh"
#include "staff.hh"
#include "lyricstaff.hh"
-#include "lyriccolumn.hh"
#include "lyricwalker.hh"
#include "pscore.hh"
-Lyric_staff::Lyric_staff()
-{
- pstaff_l_=0;
-}
-
-Staff_column*
-Lyric_staff::create_col()
-{
- return new Lyric_column(this);
-}
-
void
Lyric_staff::set_output(PScore*pscore_l)
{
#include "lyricwalker.hh"
#include "debug.hh"
#include "lyricitem.hh"
+#include "stcol.hh"
void
Lyric_walker::process_requests()
{
allow_break();
- for (int i = 0; i < lcol_l()->lreq_l_array_.size(); i++) {
- lcol_l()->typeset_item(
- new Lyric_item(lcol_l()->lreq_l_array_[i],i)
- );
+
+ int req_count=0;
+ for (int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++) {
+ Lyric_req * lreq_l = ptr()->musicalreq_l_arr_[i]->lreq_l();
+ if (!lreq_l)
+ continue;
+ Item *lp = new Lyric_item(lreq_l,req_count++);
+ ptr()->typeset_musical_item( lp);
}
}
}
-
-Lyric_staff*
-Lyric_walker::lstaff_l()
-{
- return (Lyric_staff*)staff_l_;
-}
-
-Lyric_column*
-Lyric_walker::lcol_l()
-{
- return (Lyric_column*) *(*this);
-}
#include "source.hh"
Source source;
-Source* source_global_l = &source;
-
+Source* source_l_g = &source;
+bool only_midi = false;
extern void parse_file(String,String);
0, "debug", 'd',
1, "init", 'i',
1, "include", 'I',
+ 0, "midi", 'M',
0,0,0
};
"--debug, -d enable debug output\n"
"--init, -i set init file\n"
"--include, -I add to file search path.\n"
+ "--midi, -M midi output only\n"
;
}
-void notice()
+void
+notice()
{
cout <<
"\n"
case 'd':
set_debug(true);
break;
+ case 'M':
+ only_midi = true;
+ break;
default:
assert(false);
break;
--- /dev/null
+%{
+// midi-lexer.l
+
+#include <stdio.h>
+
+#include "string.hh"
+#include "proto.hh"
+#include "my-midi-lexer.hh"
+#include "midi-parser.hh"
+
+#ifndef MIDI_LEX_DEBUG
+#define puts( x )
+#endif
+
+%}
+
+%option c++
+%option noyywrap
+%option nodefault
+%option yylineno
+%option debug
+%option yyclass="My_midi_lexer"
+%option stack
+
+%x data
+%x event
+%x int8
+%x int16
+%x int32
+%x meta_event
+%x track
+
+INT8 [\x00-\xff]
+INT16 {INT8}{INT8}
+INT32 {INT16}{INT16}
+INT7_8UNSET [\x00-\x7f]
+INT7_8SET [\x80-\xff]
+VARINT {INT7_8SET}{0,3}{INT7_8UNSET}
+
+HEADER MThd
+TRACK MTrk
+
+RUNNING_STATUS [\x30-\x4f]
+NOTE_OFF [\x80-\x8f]
+NOTE_ON [\x90-\x9f]
+PROGRAM_CHANGE [\xc0-\xcf]
+
+SYSEX_EVENT1 [\xf0]
+SYSEX_EVENT2 [\xf7]
+
+META_EVENT [\xff]
+
+SEQUENCE [\x00][\x02]
+TEXT [\x01]
+COPYRIGHT [\x02]
+TRACK_NAME [\x03]
+INSTRUMENT_NAME [\x04]
+LYRIC [\x05]
+MARKER [\x06]
+CUE_POINT [\x07]
+
+END_OF_TRACK [\x2f][\x00]
+TEMPO [\x51][\x03]
+SMPTE_OFFSET [\x54][\x05]
+TIME [\x58][\x04]
+KEY [\x59][\x02]
+SSME [\0x7f][\x03]
+
+%%
+
+{HEADER}/{INT32} { // using /{INT32}; longer match than {INT32}
+ puts( "lex: header" );
+ yy_push_state( int16 );
+ yy_push_state( int16 );
+ yy_push_state( int16 );
+ yy_push_state( int32 );
+ return HEADER;
+}
+
+{TRACK}/{INT32} { // using /{INT32}; longer match than {INT32}
+ puts( "lex: track" );
+ yy_push_state( track );
+ yy_push_state( int32 );
+ return TRACK;
+}
+
+<int32>{INT32} {
+ puts( "lex: int32" );
+ assert( YYLeng() == 4 );
+ String str( (Byte const*)YYText(), YYLeng() );
+ yylval.i = StringConversion::bin2int_i( str );
+ yy_pop_state();
+ return INT32;
+}
+<int16>{INT16} {
+ puts( "lex: int16" );
+ assert( YYLeng() == 2 );
+ String str( (Byte const*)YYText(), YYLeng() );
+ yylval.i = StringConversion::bin2int_i( str );
+ yy_pop_state();
+ return INT16;
+}
+<int8>{INT8} {
+ puts( "lex: int8" );
+ assert( YYLeng() == 1 );
+// yylval.byte = *(Byte*)YYText();
+ yylval.i = *(Byte*)YYText();
+ yy_pop_state();
+ return INT8;
+}
+
+<track>{VARINT} {
+ puts( "lex: track: varint" );
+ String str( (Byte const*)YYText(), YYLeng() );
+ yylval.i = My_midi_lexer::varint2int_i( str );
+ yy_push_state( event );
+ return VARINT;
+}
+
+<event>{RUNNING_STATUS} {
+ yylval.byte = *(Byte*)YYText();
+ yy_pop_state();
+ yy_push_state( int8 );
+ return RUNNING_STATUS;
+}
+<event>{NOTE_OFF} {
+ puts( "lex: note off" );
+ yylval.byte = *(Byte*)YYText();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return NOTE_OFF;
+}
+<event>{NOTE_ON} {
+ puts( "lex: note on" );
+ yylval.byte = *(Byte*)YYText();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return NOTE_ON;
+}
+<event>{PROGRAM_CHANGE} {
+ yylval.byte = *(Byte*)YYText();
+ yy_pop_state();
+ yy_push_state( int8 );
+ return PROGRAM_CHANGE;
+}
+<event>{META_EVENT} {
+ yy_push_state( meta_event );
+ return META_EVENT;
+}
+
+<meta_event>{SEQUENCE} { // ssss sequence number
+ yy_push_state( int16 );
+ return SEQUENCE;
+}
+<meta_event>{TEXT} { // len data
+ yy_push_state( data );
+ return TEXT;
+}
+<meta_event>{COPYRIGHT} {
+ yy_push_state( data );
+ return COPYRIGHT;
+}
+<meta_event>{TRACK_NAME} {
+ yy_push_state( data );
+ return TRACK_NAME;
+}
+<meta_event>{INSTRUMENT_NAME} {
+ yy_push_state( data );
+ return INSTRUMENT_NAME;
+}
+<meta_event>{LYRIC} {
+ yy_push_state( data );
+ return LYRIC;
+}
+<meta_event>{MARKER} {
+ yy_push_state( data );
+ return MARKER;
+}
+<meta_event>{CUE_POINT} {
+ yy_push_state( data );
+ return CUE_POINT;
+}
+<meta_event>{TEMPO} { // tttttt usec
+ puts( "lex: tempo" );
+ yy_pop_state();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return TEMPO;
+}
+<meta_event>{SMPTE_OFFSET} { // hr mn se fr ff
+ yy_pop_state();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return SMPTE_OFFSET;
+}
+<meta_event>{TIME} { // nn dd cc bb
+ puts( "lex: time" );
+ yy_pop_state();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return TIME;
+}
+<meta_event>{KEY} { // sf mi
+ puts( "lex: key" );
+ yy_pop_state();
+ yy_pop_state();
+ yy_push_state( int8 );
+ yy_push_state( int8 );
+ return KEY;
+}
+<meta_event>{SSME} { // len data
+ yy_pop_state();
+ yy_pop_state();
+ yy_push_state( data );
+ return SSME;
+}
+<meta_event>{END_OF_TRACK} {
+ puts( "lex: end of track" );
+ yy_pop_state();
+ yy_pop_state();
+ yy_pop_state();
+ return END_OF_TRACK;
+}
+<meta_event>{INT8} {
+ yylval.byte = *(Byte*)YYText();
+ return INT8;
+}
+
+<data>{VARINT} {
+ String str( (Byte const*)YYText(), YYLeng() );
+ int i = My_midi_lexer::varint2int_i( str );
+ String* str_p = new String;
+ while ( i-- )
+ *str_p += (char)yyinput();
+ yylval.str_p = str_p;
+ yy_pop_state();
+ yy_pop_state();
+ return DATA;
+}
+
+
+<<EOF>> {
+// mtor << "<<EOF>>";
+
+ if ( !close_i() )
+ yyterminate(); // can't move this, since it actually rets a YY_NULL
+}
+
+%%
+
--- /dev/null
+%{
+
+#include <iostream.h>
+
+#include "my-midi-lexer.hh"
+#include "my-midi-parser.hh"
+#include "midi-event.hh"
+#include "midi-track.hh"
+#include "midi-score.hh"
+
+#ifndef NDEBUG
+#define YYDEBUG 1
+#endif
+
+%}
+
+%union {
+ Byte byte;
+ char c;
+ int i;
+ String* str_p;
+ Request* request_p;
+ Midi_event* midi_event_p; // Voice_element* ?
+ Midi_score* midi_score_p; // Input_score* ?
+ Midi_track* midi_track_p; // Input_music* ?
+}
+
+%token HEADER TRACK
+%token SYSEX_EVENT1 SYSEX_EVENT2
+%token META_EVENT
+%token SEQUENCE TEXT COPYRIGHT TRACK_NAME INSTRUMENT_NAME LYRIC MARKER CUE_POINT
+%token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME
+
+%token<i> INT8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT
+%token<i> RUNNING_STATUS NOTE_OFF NOTE_ON PROGRAM_CHANGE
+%token<str_p> DATA
+
+%type <midi_score_p> header midi_score
+%type <midi_track_p> track
+%type <midi_event_p> event
+%type <midi_event_p> the_event meta_event text_event midi_event sysex_event
+%type <midi_event_p> running_status note_off note_on program_change
+
+%%
+
+midi: /* empty */
+ | midi midi_score {
+ midi_parser_l_g->add_score( $2 );
+ }
+ ;
+
+midi_score:
+ header {
+ }
+ | midi_score track {
+ $$->add_track( $2 );
+ }
+ ;
+
+header:
+ HEADER INT32 INT16 INT16 INT16 {
+ $$ = new Midi_score( $3, $4, $5 );
+ }
+ ;
+
+track:
+ TRACK INT32 {
+ $$ = new Midi_track;
+ }
+ | track event {
+ $$->add_event( $2 );
+ }
+ ;
+
+event:
+ VARINT the_event {
+ }
+ ;
+
+the_event:
+ meta_event {
+ }
+ | midi_event {
+ }
+ | sysex_event {
+ }
+ ;
+
+meta_event:
+ META_EVENT the_meta_event {
+ };
+
+the_meta_event:
+ SEQUENCE INT16 {
+ }
+ | text_event DATA {
+ }
+ | END_OF_TRACK {
+ }
+ | TEMPO INT8 INT8 INT8 {
+ }
+ | SMPTE_OFFSET INT8 INT8 INT8 INT8 INT8 {
+ }
+ | TIME INT8 INT8 INT8 INT8 {
+ }
+ | KEY INT8 INT8 {
+ }
+ | SSME DATA {
+ }
+ ;
+
+text_event:
+ TEXT {
+ }
+ | COPYRIGHT {
+ }
+ | TRACK_NAME {
+ }
+ | INSTRUMENT_NAME {
+ }
+ | LYRIC {
+ }
+ | MARKER {
+ }
+ | CUE_POINT {
+ }
+ ;
+
+midi_event:
+ running_status {
+ }
+ | note_off {
+ }
+ | note_on {
+ }
+ | program_change {
+ }
+ ;
+
+running_status:
+ RUNNING_STATUS {
+ }
+ ;
+
+note_off:
+ NOTE_OFF INT8 INT8 {
+ }
+ ;
+
+note_on:
+ NOTE_ON INT8 INT8 {
+ int pitch_i = $2;
+ // assuming key of C
+ String notename_str = ( pitch_i % 12 )[ "ccddeffggaab" ];
+ static int accidental_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
+ int accidental_i = accidental_i_a[ pitch_i % 12 ];
+ if ( accidental_i == 1 )
+ notename_str += "is";
+ cout << "note(" << pitch_i << "): " << notename_str << endl;
+ }
+ ;
+
+program_change:
+ PROGRAM_CHANGE {
+ }
+ ;
+
+sysex_event:
+ SYSEX_EVENT1 {
+ }
+ | SYSEX_EVENT2 {
+ }
+ ;
+++ /dev/null
-#include "musicalrequest.hh"
-#include "voice.hh"
-#include "staffwalker.hh"
-#include "debug.hh"
-#include "staff.hh"
-#include "midistaff.hh"
-#include "midicolumn.hh"
-#include "midiitem.hh"
-#include "sccol.hh"
-#include "pscore.hh"
-#include "main.hh"
-
-Midi_column::Midi_column(Midi_staff* mstaff_l)
-{
- mstaff_l_ = mstaff_l;
-}
-
-void
-Midi_column::setup_one_request(Request*req_l)
-{
- if ( req_l->melodic() )
- melreq_l_array_.push( req_l->melodic() );
-}
-
-void
-Midi_column::note_off( Midi_track* midi_track_l, Moment next )
-{
- Moment delta_t = next - when();
- for ( int i = 0; i < melreq_l_array_.size(); i++ ) {
- Midi_note midi_note( melreq_l_array_[ i ], midi_track_l->number_i_, false );
- midi_track_l->add( delta_t, &midi_note );
- delta_t = 0.0;
- }
-}
-
-void
-Midi_column::note_on( Midi_track* midi_track_l )
-{
- Moment delta_t = 0.0;
- for ( int i = 0; i < melreq_l_array_.size(); i++ ) {
- Midi_note midi_note( melreq_l_array_[ i ], midi_track_l->number_i_, true );
- midi_track_l->add( delta_t, &midi_note );
- }
-}
// destructor
// routines, alphasorted
-Mididef::Mididef()
+Midi_def::Midi_def()
{
set_tempo( Moment( 1, 4 ), 60 );
outfile_str_ = "lelie.midi";
}
-Mididef::Mididef( Mididef const& midi_c_r )
+Midi_def::Midi_def( Midi_def const& midi_c_r )
{
whole_seconds_f_ = midi_c_r.whole_seconds_f_;
outfile_str_ = midi_c_r.outfile_str_;
}
-Mididef::~Mididef()
+Midi_def::~Midi_def()
{
}
Real
-Mididef::duration_to_seconds_f( Moment moment )
+Midi_def::duration_to_seconds_f( Moment moment )
{
if (!moment)
return 0;
}
int
-Mididef::get_tempo_i( Moment moment )
+Midi_def::get_tempo_i( Moment moment )
{
return Moment( whole_seconds_f_ ) * Moment( 60 ) * moment;
}
void
-Mididef::print() const
+Midi_def::print() const
{
#ifndef NPRINT
mtor << "Midi {4/min: " << Real( 60 ) / ( whole_seconds_f_ * 4 );
}
void
-Mididef::set_tempo( Moment moment, int count_per_minute_i )
+Midi_def::set_tempo( Moment moment, int count_per_minute_i )
{
whole_seconds_f_ = Moment( count_per_minute_i ) / Moment( 60 ) / moment;
}
void
Midi_chunk::add( String str )
{
- data_str_ += str;
+ data_str_ += str;
}
void
Midi_chunk::set( String header_str, String data_str, String footer_str )
{
- data_str_ = data_str;
- footer_str_ = footer_str;
- header_str_ = header_str;
+ data_str_ = data_str;
+ footer_str_ = footer_str;
+ header_str_ = header_str;
}
String
Midi_chunk::str()
{
- String str = header_str_;
- String length_str = StringConversion::int2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
- length_str = StringConversion::hex2bin_str( length_str );
- str += length_str;
- str += data_str_;
- str += footer_str_;
- return str;
+ String str = header_str_;
+ String length_str = StringConversion::int2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
+ length_str = StringConversion::hex2bin_str( length_str );
+ str += length_str;
+ str += data_str_;
+ str += footer_str_;
+ return str;
}
Midi_duration::Midi_duration( Real seconds_f )
{
- seconds_f_ = seconds_f;
+ seconds_f_ = seconds_f;
}
String
Midi_duration::str()
{
- return String( "<duration: " ) + String( seconds_f_ ) + ">";
+ return String( "<duration: " ) + String( seconds_f_ ) + ">";
}
Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i )
{
- String str;
+ String str;
- String format_str = StringConversion::int2hex_str( format_i, 4, '0' );
- str += StringConversion::hex2bin_str( format_str );
+ String format_str = StringConversion::int2hex_str( format_i, 4, '0' );
+ str += StringConversion::hex2bin_str( format_str );
- String tracks_str = StringConversion::int2hex_str( tracks_i, 4, '0' );
- str += StringConversion::hex2bin_str( tracks_str );
+ String tracks_str = StringConversion::int2hex_str( tracks_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tracks_str );
- String tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' );
- str += StringConversion::hex2bin_str( tempo_str );
+ String tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tempo_str );
- set( "MThd", str, "" );
+ set( "MThd", str, "" );
}
String
Midi_item::int2varlength_str( int i )
{
- int buffer_i = i & 0x7f;
- while ( (i >>= 7) > 0 ) {
- buffer_i <<= 8;
- buffer_i |= 0x80;
- buffer_i += (i & 0x7f);
- }
-
- String str;
- while ( 1 ) {
- str += (char)buffer_i;
- if ( buffer_i & 0x80 )
- buffer_i >>= 8;
- else
- break;
- }
- return str;
+ int buffer_i = i & 0x7f;
+ while ( (i >>= 7) > 0 ) {
+ buffer_i <<= 8;
+ buffer_i |= 0x80;
+ buffer_i += (i & 0x7f);
+ }
+
+ String str;
+ while ( 1 ) {
+ str += (char)buffer_i;
+ if ( buffer_i & 0x80 )
+ buffer_i >>= 8;
+ else
+ break;
+ }
+ return str;
}
void
Midi_item::output_midi( Midi_stream& midi_stream_r )
{
- midi_stream_r << str();
+ midi_stream_r << str();
}
Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo )
{
- pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
- channel_i_ = channel_i;
- on_bo_ = on_bo;
+
+ if (!melreq_l )
+ pitch_i_ = INT_MAX-1; // any pitch.
+ else
+ pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
+
+ channel_i_ = channel_i;
+
+ // poor man-s staff dynamics:
+ dynamic_byte_ = (melreq_l)? 0x64 - 0x10 * channel_i_:0;
+ on_b_ = on_bo;
}
String
Midi_note::str()
{
- if ( pitch_i_ != INT_MAX ) {
- Byte status_by = ( on_bo_ ? 0x90 : 0x80 ) + channel_i_;
- String str = String( (char)status_by );
- str += (char)pitch_i_;
- // poor man-s staff dynamics:
- Byte dynamic_by = 0x64 - 0x10 * channel_i_;
- str += (char)dynamic_by;
- return str;
- }
- return String( "" );
+ if ( pitch_i_ != INT_MAX ) {
+ Byte status_byte = ( on_b_ ? 0x90 : 0x80 ) + channel_i_;
+ String str = String( (char)status_byte );
+ str += (char)pitch_i_;
+ // poor man-s staff dynamics:
+ str += (char)dynamic_byte_;
+ return str;
+ }
+ return String( "" );
}
Midi_track::Midi_track( int number_i )
// mi = 0: major key
// mi = 1: minor key
- number_i_ = number_i;
+ number_i_ = number_i;
- char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
- "00" "ff51" "0307" "a120"
+ char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
+ "00" "ff51" "0307" "a120"
// why a key at all, in midi?
// key: C
- "00" "ff59" "02" "00" "00"
+ "00" "ff59" "02" "00" "00"
// key: F (scsii-menuetto)
// "00" "ff59" "02" "ff" "00"
- ;
+ ;
- String data_str;
- // only for format 0 (currently using format 1)?
- data_str += StringConversion::hex2bin_str( data_ch_c_l );
+ String data_str;
+ // only for format 0 (currently using format 1)?
+ data_str += StringConversion::hex2bin_str( data_ch_c_l );
- char const* footer_ch_c_l = "00" "ff2f" "00";
- String footer_str = StringConversion::hex2bin_str( footer_ch_c_l );
+ char const* footer_ch_c_l = "00" "ff2f" "00";
+ String footer_str = StringConversion::hex2bin_str( footer_ch_c_l );
- set( "MTrk", data_str, footer_str );
+ set( "MTrk", data_str, footer_str );
}
void
Midi_track::add( int delta_time_i, String event_str )
{
- Midi_chunk::add( int2varlength_str( delta_time_i ) + event_str );
+ assert(delta_time_i >= 0);
+ Midi_chunk::add( int2varlength_str( delta_time_i ) + event_str );
}
void
Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
{
- // silly guess: 24 midi clocks per 4 note
- // huh?
+ // silly guess: 24 midi clocks per 4 note
+ // huh?
// int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 24 );
- int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 96 );
- add( delta_time_i, mitem_l->str() );
+ int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 96 );
+ add( delta_time_i, mitem_l->str() );
}
+++ /dev/null
-/*
- midiscorewalker.cc -- implement Midi_score_walker
-
- source file of the LilyPond music typesetter
-
- (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwehuizen <jan@digicash.com>
-*/
-#include "plist.hh"
-#include "debug.hh"
-#include "score.hh"
-#include "staffwalker.hh"
-#include "staff.hh"
-#include "sccol.hh"
-#include "midistream.hh"
-#include "midiscorewalker.hh"
-
-Midi_score_walker::Midi_score_walker( Score* score_l, Midi_stream* midi_stream_l )
- :Score_walker( score_l )
-{
- midi_stream_l_ = midi_stream_l;
-}
-
-Midi_score_walker::~Midi_score_walker()
-{
-}
-
-void
-Midi_score_walker::process()
-{
-}
-
+++ /dev/null
-#include "musicalrequest.hh"
-#include "voice.hh"
-#include "staffwalker.hh"
-#include "debug.hh"
-#include "staff.hh"
-#include "midistaff.hh"
-#include "midicolumn.hh"
-#include "midiwalker.hh"
-#include "midiitem.hh"
-#include "midistream.hh"
-
-Midi_staff::Midi_staff()
-{
-}
-
-Staff_column*
-Midi_staff::create_col()
-{
- return new Midi_column(this);
-}
-
-Staff_walker*
-Midi_staff::get_walker_p()
-{
- return new Midi_walker(this);
-}
-
-void
-Midi_staff::midi( Midi_stream* midi_stream_l, int track_i )
-{
- Midi_track midi_track( track_i );
- Midi_column* last_mcol_l = 0;
- for ( Midi_walker w( this ); w.ok(); w++ ) {
- Midi_column* mcol_l = (Midi_column*)*w;
- if ( last_mcol_l )
- last_mcol_l->note_off( &midi_track, w->when() );
- mcol_l->note_on( &midi_track );
- last_mcol_l = mcol_l;
- }
- if ( last_mcol_l )
- last_mcol_l->note_off( &midi_track, last() );
- *midi_stream_l << midi_track;
-}
-
-void
-Midi_staff::set_output(PScore*pscore_l)
-{
- //i don-t want no pscore!
-}
-
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwenhuizen <jan@digicash.com>
*/
-#include "misc.hh"
#include "musicalrequest.hh"
-#include "voice.hh"
#include "pscore.hh"
#include "staff.hh"
-#include "midicolumn.hh"
-#include "midistaff.hh"
+#include "stcol.hh"
#include "midiwalker.hh"
-#include "debug.hh"
#include "midiitem.hh"
#include "midistream.hh"
+#include "debug.hh"
-Midi_walker::Midi_walker( Midi_staff* mstaff_l )
- : Staff_walker( mstaff_l, 0 )
-{
-}
-
-Midi_column*
-Midi_walker::mcol_l()
+Midi_walker::Midi_walker(Staff *st_l, Midi_track* track_l)
+ : PCursor<Staff_column*>(st_l->cols_)
{
- return (Midi_column*) *(*this);
+ track_l_ = track_l;
+ last_moment_= 0;
}
-Midi_staff*
-Midi_walker::mstaff_l()
+void
+Midi_walker::do_stop_notes(Moment max_moment)
{
- return (Midi_staff*)staff_l_;
+ while (stop_notes.size() && stop_notes.front_idx() <= max_moment) {
+ Moment stop_moment = stop_notes.front_idx();
+ Melodic_req * req_l = stop_notes.get();
+
+ Midi_note note(req_l, track_l_->number_i_, false);
+
+ Moment delta_t = stop_moment-last_moment_ ;
+ last_moment_ += delta_t;
+ track_l_->add(delta_t, ¬e );
+ }
}
void
Midi_walker::process_requests()
{
- allow_break();
+ do_stop_notes(ptr()->when());
+ for ( int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++ ) {
+
+ Rhythmic_req *n = ptr()->musicalreq_l_arr_[i]->rhythmic();
+ if ( !n || !(n->note() || n->rest()) )
+ continue;
+
+ Midi_note note(n->melodic(), track_l_->number_i_, true);
+ stop_notes.enter(n->melodic(), n->duration() + ptr()->when() );
+ Moment dt = 0;
+ track_l_->add(dt, ¬e);
+ }
}
+Midi_walker::~Midi_walker()
+{
+ do_stop_notes( last_moment_ + Moment(10,1)); // ugh
+}
#include "identparent.hh"
#include "associter.hh"
#include "lexer.hh"
+#include "inputfile.hh"
#include "parser.hh"
#include "keyword.hh"
#include "assoc.hh"
linewidth = 15 *CM_TO_PT; // in cm for now
whole_width = 8 * note_width();
geometric_ = sqrt(2);
+ outfile = "lelie.out";
}
Paperdef::~Paperdef()
String *string;
const char *consstr;
Paperdef *paper;
- Mididef* midi;
+ Midi_def* midi;
Input_music *music;
Music_general_chord *chord;
Music_voice *mvoice;
/*cont*/ '{' score_body '}' {
$$ = $4;
$$->defined_ch_c_l_ = define_spots.pop();
- if (!$$->paper_p_)
+ if (!$$->paper_p_ && ! $$->midi_p_)
$$->paper_p_ = default_paper();
/* handle error levels. */
;
midi_body: {
- $$ = new Mididef;
+ $$ = new Midi_def;
}
| midi_body OUTPUT STRING {
$$->outfile_str_ = *$3;
$$ = new Input_staff(*$1);
delete $1;
}
- | MIDI {
- $$ = new Input_staff("midi");
- }
;
staff_body:
}
bool
-PCol::used()const
+PCol::used_b()const
{
return breakable_b() || its.size();
}
PScore::clean_cols()
{
for (iter_top(cols,c); c.ok(); )
- if (!c->used()) {
+ if (!c->used_b()) {
delete c.get();
} else
c++;
}
bool
-Score_column::used() {
- return pcol_l_->used();
+Score_column::used_b() {
+ return pcol_l_->used_b();
}
void
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
*/
-
#include "tstream.hh"
#include "score.hh"
#include "sccol.hh"
#include "source.hh"
#include "sourcefile.hh"
#include "scorewalker.hh"
+#include "midioutput.hh"
#include "mididef.hh"
-#include "midiitem.hh"
-#include "midistream.hh"
-#include "midicolumn.hh"
-#include "midistaff.hh"
-#include "midiwalker.hh"
+
+extern String default_out_fn;
void
Score::setup_music()
error("Need to have music in a score.", defined_ch_c_l_);
}
- pscore_p_ = new PScore(paper_p_);
- find_col(0, false)->set_breakable(); // ugh
- find_col(last(), false)->set_breakable();
-
-
-
for (iter_top(staffs_,i); i.ok(); i++) {
- i->set_output(pscore_p_);
i->setup_staffcols();
i->OK();
}
{
setup_music();
- process_music();
+ paper();
+ midi();
+}
+
+void
+Score::paper()
+{
+ if (!paper_p_)
+ return;
+
+ pscore_p_ = new PScore(paper_p_);
- // do this after processing, staffs first have to generate PCols.
+ find_col(0, false)->set_breakable(); // ugh
+ find_col(last(), false)->set_breakable();
do_cols();
+
+ for (iter_top(staffs_,i); i.ok(); i++)
+ i->set_output(pscore_p_);
+
+
+ process_music();
+ clean_cols(); // can't move clean_cols() farther up.
print();
calc_idealspacing();
OK();
*mlog << endl;
pscore_p_->process();
+
+ // output
+ paper_output();
+
}
/**
i->clean_cols();
for (iter_top(cols_,c); c.ok(); ) {
- if (!c->pcol_l_->used()) {
+ if (!c->pcol_l_->used_b()) {
delete c.get();
} else {
c->preprocess();
void
Score::do_cols()
+
{
+
iter_top(cols_,i);
for (; i.ok(); i++) {
pscore_p_->add(i->pcol_l_);
}
- clean_cols(); // can't move clean_cols() farther up.
+
}
Moment
}
void
-Score::set(Mididef* midi_p)
+Score::set(Paperdef *pap_p)
+{
+ delete paper_p_;
+ paper_p_ = pap_p;
+}
+
+void
+Score::set(Midi_def* midi_p)
{
delete midi_p_;
midi_p_ = midi_p;
}
if (pscore_p_)
pscore_p_->print();
+ if (midi_p_)
+ midi_p_->print();
mtor << "}\n";
#endif
}
-Score::Score(Paperdef*paper_p)
+Score::Score()
{
pscore_p_=0;
- paper_p_ = paper_p;
+ paper_p_ = 0;
midi_p_ = 0;
errorlevel_i_ = 0;
defined_ch_c_l_ = 0;
}
void
-Score::output(String s)
+Score::paper_output()
{
OK();
if (paper_p_->outfile=="")
- paper_p_->outfile = s;
-
+ paper_p_->outfile = default_out_fn + ".out";
+
if ( errorlevel_i_ ) {
*mlog << "lilypond: warning: no output to: " << paper_p_->outfile
<< " (errorlevel=" << errorlevel_i_ << ")" << endl;
return;
}
- *mlog << "output to " << paper_p_->outfile << "...\n";
+ *mlog << "TeX output to " << paper_p_->outfile << " ...\n";
Tex_stream the_output(paper_p_->outfile);
the_output << "% outputting Score, defined at: " <<
- source_global_l->
+ source_l_g->
sourcefile_l (defined_ch_c_l_)->file_line_no_str(defined_ch_c_l_) << "\n";
pscore_p_->output(the_output);
}
if (!midi_p_)
return;
- *mlog << "midi output to " << midi_p_->outfile_str_ << "...\n";
-
- int track_i = 0;
- for ( PCursor<Staff*> staff_l_pcur( staffs_.top() ); staff_l_pcur.ok(); staff_l_pcur++ ) {
- Midi_staff* mstaff_l = (Midi_staff*)*staff_l_pcur;
- if ( !mstaff_l->pscore_l_ ) // we _are_ a midi-staff, ugh
- track_i++;
- }
-
- Midi_stream midi_stream( midi_p_->outfile_str_, track_i, midi_p_->get_tempo_i( Moment( 1, 4 ) ) );
-
- track_i = 0;
- for ( PCursor<Staff*> staff_l_pcur( staffs_.top() ); staff_l_pcur.ok(); staff_l_pcur++ ) {
- Midi_staff* mstaff_l = (Midi_staff*)*staff_l_pcur;
- if ( !mstaff_l->pscore_l_ ) // we _are_ a midi-staff, ugh
- mstaff_l->midi( &midi_stream, track_i++ );
- }
+ if (midi_p_->outfile_str_ == "")
+ midi_p_->outfile_str_ = default_out_fn + ".midi";
+
+ *mlog << "midi output to " << midi_p_->outfile_str_ << " ...\n";
+ Midi_output(this, midi_p_);
}
void
#include "inputscore.hh"
#include "score.hh"
#include "string.hh"
+#include "paperdef.hh"
+#include "debug.hh"
static Array<Input_score*> score_array_global;
+String default_out_fn = "lelie";
-static String outfn="lelie.out";
-
-// todo: check we don't overwrite default output.
void
do_scores()
{
for (int i=0; i < score_array_global.size(); i++) {
- Score * s_p = score_array_global[i]->parse();
- delete score_array_global[i];
+ Input_score* &is_p = score_array_global[i];
+ if (is_p->errorlevel_i_) {
+ warning("Score contains errors. Will not process it. ",
+ is_p->defined_ch_c_l_);
+ delete is_p;
+ continue;
+ }
+
+ if (only_midi) {
+ delete is_p->paper_p_;
+ is_p->paper_p_ = 0;
+ }
+
+ Score * s_p = is_p->parse();
+ delete is_p;
s_p->print ();
s_p->process();
- s_p->output(outfn);
- s_p->midi();
delete s_p;
}
score_array_global.set_size(0);
score_array_global.push(s);
}
-#if 0
-Input_score*
-current_iscore_l()
-{
- if ( score_array_global.size() )
- return score_array_global.top(); // UGH
- else
- return 0;
-}
-#endif
-
void
set_default_output(String s)
{
- outfn = s;
+ default_out_fn = s;
}
Score_walker::Score_walker(Score *s)
:PCursor<Score_column *> (s->cols_)
{
+ score_l_ = s;
for (iter_top(s->staffs_,i); i.ok(); i++) {
Staff_walker* w_p=i->get_walker_p();
w_p->score_walk_l_ =this;
{
for (int i=0; i < walker_p_arr_.size(); i++)
delete walker_p_arr_[i];
+ assert( !score_l_->find_col(score_l_->last(), true)->used_b());
}
data_caddr_ = (caddr_t)mmap( (void*)0, size_off_, PROT_READ, MAP_SHARED, fildes_i_, 0 );
if ( (int)data_caddr_ == -1 )
+ // ugh: defined_ch_c_l...
warning( String( "can't map: " ) + name_str_ + String( ": " ) + strerror( errno ), defined_ch_c_l ); //lexer->here_ch_c_l() );
}
void
Staff::clean_cols()
{
- iter_top(cols,i);
+ iter_top(cols_,i);
for(; i.ok(); ){
- if (!i->musical_column_l_->used())
+ if (!i->musical_column_l_->used_b())
i->musical_column_l_ = 0;
- if (!i->command_column_l_->used())
+ if (!i->command_column_l_->used_b())
i->command_column_l_ =0;
if (!i->command_column_l_&& !i->musical_column_l_)
}
}
-// Midi_track*
-// Staff::midi_track_p()
-// {
-// Midi_track_p midi_track_p = new Midi_track;
-// Midi_walker( *this );
-// }
-
Staff_column *
Staff::get_col(Moment w, PCursor<Staff_column*> *last)
{
- iter_top(cols,i);
+ iter_top(cols_,i);
if (last && last->ok() && (*last)->when() <= w)
i = *last;
PCursor<Score_column*> sccols(score_l_->find_col(w, false));
- Staff_column* stcol_p = create_col();
-
+ Staff_column* stcol_p = new Staff_column;
+ stcol_p->staff_l_ = this;
Score_column* comcol_l = sccols++;
stcol_p->set_cols(comcol_l, sccols);
if (!i.ok()) {
- cols.bottom().add( stcol_p);
- i = cols.bottom();
+ cols_.bottom().add( stcol_p);
+ i = cols_.bottom();
} else {
i.insert(stcol_p);
i--;
Staff::setup_staffcols()
{
for (iter_top(voice_list_,i); i.ok(); i++) {
- PCursor<Staff_column*> last(cols);
+ PCursor<Staff_column*> last(cols_);
Moment now = i->start;
for (iter_top(i->elts,j); j.ok(); j++) {
s_l->add(j);
now += j->duration;
}
-// get_col(now,last);
+
}
OK();
}
Staff::OK() const
{
#ifndef NDEBUG
- cols.OK();
+ cols_.OK();
voice_list_.OK();
- iter_top(cols, i);
- iter_top(cols, j);
+ iter_top(cols_, i);
+ iter_top(cols_, j);
i++;
for (; i.ok(); j++,i++) {
assert(j->when () < i->when() );
Staff::Staff()
{
score_l_ =0;
- pscore_l_ =0;
+ pscore_l_ =0;
+ pstaff_l_ =0;
}
}
Staff_walker::Staff_walker(Staff * s, PScore*ps )
- : PCursor<Staff_column*> (s->cols)
+ : PCursor<Staff_column*> (s->cols_)
{
staff_l_ = s;
pscore_l_ = ps;
- default_grouping = new Rhythmic_grouping(MInterval(0, 1), 4); // should be in tdes. TODO
+
+ // should be in tdes. TODO
+ default_grouping = new Rhythmic_grouping(MInterval(0, 1), 4);
score_walk_l_ = 0;
}
process_timing_reqs();
process_requests();
}
+
void
Staff_walker::allow_break()
{
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
*/
-
+#include "staff.hh"
#include "voice.hh"
#include "timedescription.hh"
#include "sccol.hh"
#include "stcol.hh"
#include "commandrequest.hh"
#include "musicalrequest.hh"
+#include "interval.hh"
+#include "pscore.hh"
+#include "item.hh"
+#include "pcol.hh"
void
Staff_column::OK() const
{
for (iter_top(ve->reqs,j); j.ok(); j++) {
if (j->nonmus()) {
- if (j->nonmus()->timing()) {
+ Nonmusical_req * c_l = j->nonmus();
+ if (c_l->timing()) {
timing_req_l_arr_.push(j->nonmus()->timing());
}
- if (!j->barcheck() && !j->nonmus()->measuregrouping())
+ if (!c_l->barcheck() && !c_l->partial() &&
+ !c_l->measuregrouping())
setup_one_request(j); // no need to bother children
} else {
if (j->rhythmic()) {
musical_column_l_->add_duration(j->rhythmic()->duration());
}
- setup_one_request(j);
+ if (!j->musical()->skip())
+ setup_one_request(j);
}
}
}
{
musical_column_l_ = 0;
command_column_l_ = 0;
+ staff_l_ = 0;
}
command_column_l_ = c1;
musical_column_l_ = c2;
}
+
+void
+Staff_column::setup_one_request(Request * j)
+{
+ if (j->nonmus()) // ugh
+ commandreq_l_arr_.push(j);
+ else if (j->musical())
+ musicalreq_l_arr_.push(j);
+}
+
+void
+Staff_column::typeset_musical_item(Item*i)
+{
+ assert(i);
+ Score_column * sccol_l = musical_column_l_;
+ musical_column_l_->pcol_l_->pscore_l_->typeset_item(i, sccol_l->pcol_l_,
+ staff_l_->pstaff_l_);
+}
+
+/**
+ align items in #item_l_arr#, return the width.
+ */
+Interval
+align_items(Array<Item*> item_l_arr)
+{
+ Interval wid(0,0);
+ for (int i =0; i < item_l_arr.size(); i++) {
+ Interval item_width= item_l_arr[i]->width();
+ item_l_arr[i]->translate(Offset( wid.right - item_width.left ,0));
+ wid.unite(item_width);
+ }
+ return wid;
+}
+
+void
+translate_items(Real x, Array<Item*> item_l_arr)
+{
+ for (int i =0; i < item_l_arr.size(); i++)
+ item_l_arr[i]->translate(Offset(x, 0));
+}
+/*
+ UGR
+ This still sux
+ */
+void
+Staff_column::typeset_breakable_items(Array<Item *> &pre_p_arr,
+ Array<Item *> &nobreak_p_arr,
+ Array<Item *> &post_p_arr)
+{
+ PCol * c= command_column_l_->pcol_l_;
+ PScore *ps_l=command_column_l_->pcol_l_->pscore_l_;
+
+ if (!c->breakable_b()) {
+ for (int i =0; i < pre_p_arr.size(); i++)
+ delete pre_p_arr[i];
+ pre_p_arr.set_size(0);
+ for (int i =0; i < post_p_arr.size(); i++)
+ delete post_p_arr[i];
+ post_p_arr.set_size(0);
+ }
+
+
+ for (int i =0; i < pre_p_arr.size(); i++) {
+ ps_l->typeset_item(pre_p_arr[i], c, staff_l_->pstaff_l_,0);
+ }
+ for (int i =0; i < nobreak_p_arr.size(); i++) {
+ ps_l->typeset_item(nobreak_p_arr[i], c, staff_l_->pstaff_l_,1);
+ }
+ for (int i =0; i < post_p_arr.size(); i++) {
+ ps_l->typeset_item(post_p_arr[i], c, staff_l_->pstaff_l_,2);
+ }
+
+ Interval pre_wid= align_items(pre_p_arr);
+ translate_items( -pre_wid.right, pre_p_arr);
+ align_items(nobreak_p_arr);
+ Interval post_wid =align_items(post_p_arr);
+ translate_items (-post_wid.left , post_p_arr);
+
+ pre_p_arr.set_size(0);
+ post_p_arr.set_size(0);
+ nobreak_p_arr.set_size(0);
+}
int stafftop = 2*staff_center;
stemlen = STEMLEN + (maxnote - minnote);
- // uhh... how about non 5-line staffs?
+ // uhh... how about non 5-line staffs?
if (maxnote < -2 && dir == 1){
int t = staff_center - staff_center/2;
stemlen = t - minnote +2;
set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
if (dir > 0){
- stem_xoffset = paper()->note_width();
+ stem_xoffset = paper()->note_width()-paper()->rule_thickness();
} else
stem_xoffset = 0;
}
message( String message_str, char const* context_ch_c_l )
{
String str = "lilypond: ";
- Source_file* sourcefile_l = source_global_l->sourcefile_l( context_ch_c_l );
+ Source_file* sourcefile_l = source_l_g->sourcefile_l( context_ch_c_l );
if ( sourcefile_l ) {
str += sourcefile_l->file_line_no_str(context_ch_c_l) + String(": ");
}