From a3e8a1ccfeb040b3ec18bb77841dc4ececdd65e1 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 24 Feb 1997 10:48:04 +0100 Subject: [PATCH] release: 0.0.34 --- .dstreamrc | 2 +- ANNOUNCE | 18 +- Documentation/CodingStyle.pod | 13 +- Documentation/README.pod | 5 + Documentation/faq.pod | 19 +- Generate.make | 13 +- Makefile | 9 +- NEWS | 17 ++ Sources.make | 75 ++++++-- TODO | 9 +- Variables.make | 20 +- configure | 2 +- flower/Makefile | 2 +- flower/NEWS | 9 +- flower/Sources.make | 5 +- flower/Variables.make | 4 +- flower/fproto.hh | 3 +- flower/string.cc | 82 ++++---- flower/string.hh | 14 +- flower/stringconversion.cc | 12 +- flower/stringconversion.hh | 6 +- flower/stringdata.hh | 94 +++++++++ flower/stringdata.inl | 212 +++++++++++++++++++++ flower/stringhandle.hh | 70 +++++++ flower/stringhandle.inl | 151 +++++++++++++++ flower/stringutil.cc | 349 ++-------------------------------- flower/stringutil.hh | 150 --------------- hdr/Makefile | 3 +- hdr/complexcolumn.hh | 36 ---- hdr/complexstaff.hh | 9 +- hdr/complexwalker.hh | 1 - hdr/inputfile.hh | 28 +++ hdr/inputscore.hh | 4 +- hdr/lexer.hh | 20 +- hdr/lyriccolumn.hh | 30 --- hdr/lyricstaff.hh | 4 - hdr/lyricwalker.hh | 2 - hdr/main.hh | 5 +- hdr/midicolumn.hh | 28 --- hdr/mididef.hh | 8 +- hdr/midiitem.hh | 70 ++++--- hdr/midioutput.hh | 19 ++ hdr/midiscorewalker.hh | 28 --- hdr/midistaff.hh | 28 --- hdr/midiwalker.hh | 37 ++-- hdr/pcol.hh | 10 +- hdr/proto.hh | 10 +- hdr/sccol.hh | 2 +- hdr/score.hh | 19 +- hdr/scorewalker.hh | 1 + hdr/source.hh | 4 + hdr/staff.hh | 9 +- hdr/stcol.hh | 17 +- input/cadenza.ly | 2 +- input/error.ly | 2 +- input/maartje.ly | 9 +- input/martien.ly | 25 +-- input/midi.ly | 18 +- input/pavane.ly | 1 - input/scsii-menuetto.ly | 4 - input/standchen.ly | 33 ++-- input/twinkle.ly | 4 +- input/wohltemperirt.ly | 21 +- src/Makefile | 6 +- src/barreg.cc | 1 - src/calcideal.cc | 2 +- src/complexcolumn.cc | 102 ---------- src/complexstaff.cc | 16 +- src/complexwalker.cc | 19 +- src/inputscore.cc | 12 +- src/inputstaff.cc | 4 +- src/lexerinit.cc | 33 +--- src/lyriccolumn.cc | 29 --- src/lyricstaff.cc | 12 -- src/lyricwalker.cc | 25 +-- src/main.cc | 12 +- src/midi-lexer.l | 261 +++++++++++++++++++++++++ src/midi-parser.y | 173 +++++++++++++++++ src/midicolumn.cc | 44 ----- src/mididef.cc | 14 +- src/midiitem.cc | 142 +++++++------- src/midiscorewalker.cc | 31 --- src/midistaff.cc | 50 ----- src/midiwalker.cc | 51 +++-- src/mylexer.cc | 1 + src/paperdef.cc | 1 + src/parser.y | 9 +- src/pcol.cc | 2 +- src/pscore.cc | 2 +- src/sccol.cc | 4 +- src/score.cc | 95 +++++---- src/scores.cc | 38 ++-- src/scorewalker.cc | 2 + src/sourcefile.cc | 1 + src/staff.cc | 36 ++-- src/staffwalker.cc | 7 +- src/stcol.cc | 98 +++++++++- src/stem.cc | 4 +- src/warn.cc | 2 +- 99 files changed, 1787 insertions(+), 1470 deletions(-) create mode 100644 flower/stringdata.hh create mode 100644 flower/stringdata.inl create mode 100644 flower/stringhandle.hh create mode 100644 flower/stringhandle.inl delete mode 100644 flower/stringutil.hh delete mode 100644 hdr/complexcolumn.hh create mode 100644 hdr/inputfile.hh delete mode 100644 hdr/lyriccolumn.hh delete mode 100644 hdr/midicolumn.hh create mode 100644 hdr/midioutput.hh delete mode 100644 hdr/midiscorewalker.hh delete mode 100644 hdr/midistaff.hh delete mode 100644 src/complexcolumn.cc delete mode 100644 src/lyriccolumn.cc create mode 100644 src/midi-lexer.l create mode 100644 src/midi-parser.y delete mode 100644 src/midicolumn.cc delete mode 100644 src/midiscorewalker.cc delete mode 100644 src/midistaff.cc diff --git a/.dstreamrc b/.dstreamrc index b2c6cfc5da..0ae4806aca 100644 --- a/.dstreamrc +++ b/.dstreamrc @@ -38,7 +38,7 @@ Input_cursor 1 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 diff --git a/ANNOUNCE b/ANNOUNCE index 56579bf36b..48bbdd0cbd 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -16,6 +16,8 @@ Technically it is a preprocessor which generates TeX 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 @@ -35,18 +37,18 @@ having a large user base is a burden then. 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 @@ -108,7 +110,7 @@ EXAMPLE INPUT } commands { meter {2 * 4} - skip 24*2 + skip {24*2} bar "||" } } diff --git a/Documentation/CodingStyle.pod b/Documentation/CodingStyle.pod index 02b580c602..521bf1e126 100644 --- a/Documentation/CodingStyle.pod +++ b/Documentation/CodingStyle.pod @@ -42,13 +42,20 @@ the C is a Hungarian notation postfix for $C$. See below 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 */ @@ -57,8 +64,10 @@ http://www.zib.de/Visual/software/doc++/index.html /** short memo. long doco of member() + @param description of arguments + @return Rettype */ - member(); + Rettype member(Argtype); /// memo only boring_member(); diff --git a/Documentation/README.pod b/Documentation/README.pod index a837d6a070..7126e8edc1 100644 --- a/Documentation/README.pod +++ b/Documentation/README.pod @@ -120,6 +120,11 @@ broken systems. add F 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 diff --git a/Documentation/faq.pod b/Documentation/faq.pod index fac6903cb1..b0096fd73a 100644 --- a/Documentation/faq.pod +++ b/Documentation/faq.pod @@ -17,7 +17,7 @@ specify 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). @@ -26,18 +26,27 @@ Have a look at http://www.cygnus.com/gnu-win32. To make LilyPond type 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. diff --git a/Generate.make b/Generate.make index 701c6d79b0..0b1e6c490d 100644 --- a/Generate.make +++ b/Generate.make @@ -1,9 +1,12 @@ +# 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 \ @@ -18,9 +21,11 @@ $(parsheadnew): $(CCDIR)/parser.cc $(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 $< > $@ diff --git a/Makefile b/Makefile index 830b08c360..3e4a16e511 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +# Makefile +# top level makefile of LilyPond + include Variables.make .SUFFIXES: @@ -8,11 +11,13 @@ $(exe): $(obs) $(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;\ @@ -21,7 +26,7 @@ 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: diff --git a/NEWS b/NEWS index ce2cca67ca..9e99b19fe0 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,24 @@ +******* +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 diff --git a/Sources.make b/Sources.make index 2312887b2a..ba5833629c 100644 --- a/Sources.make +++ b/Sources.make @@ -1,24 +1,27 @@ -# -*- 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 \ @@ -33,22 +36,24 @@ hdr= bar.hh barreg.hh beam.hh boxes.hh break.hh clefreg.hh clefitem.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\ @@ -67,8 +72,44 @@ mycc=bar.cc barreg.cc beam.cc boxes.cc break.cc calcideal.cc clefreg.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\ + + +# diff --git a/TODO b/TODO index 4eba110c2d..341f837438 100644 --- a/TODO +++ b/TODO @@ -1,16 +1,15 @@ 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? ! @@ -21,6 +20,8 @@ done, or is an idea that I want to think about BUGS * key undo + * c8. c32 c32 + * key print if clef change. * $cis ( | ) cis$ diff --git a/Variables.make b/Variables.make index 96aa6194dd..cc697d7c3c 100644 --- a/Variables.make +++ b/Variables.make @@ -3,7 +3,7 @@ # version info MAJVER=0 MINVER=0 -PATCHLEVEL=33 +PATCHLEVEL=34 @@ -19,7 +19,7 @@ DEBUGFLAG=-g # 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. @@ -63,15 +63,25 @@ INPUTDIR=input # # 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 @@ -81,9 +91,10 @@ DOCDIR=docxx 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 @@ -100,6 +111,7 @@ CXXFLAGS=$(DEFINES) -I$(HEADERDIR) -I$(FLOWERDIR) $(EXTRACXXFLAGS) FLEX=flex BISON=bison exe=$(PACKAGENAME) +m2m=$(M2MNAME) OUTPUT_OPTION=$< -o $@ DDIR=$(TOPDIR)/$(DNAME) SUBDIRS=Documentation $(OBJECTDIR) $(CCDIR) $(HEADERDIR) $(INITDIR) $(DEPDIR) \ diff --git a/configure b/configure index 21ee567e83..45a8f9b13a 100755 --- a/configure +++ b/configure @@ -12,7 +12,7 @@ function setversion() { MAKE=${MAKE:-make} PREFIX=${PREFIX:-.} -NEEDFLOWERVER=1.1.1 +NEEDFLOWERVER=1.1.2 echo using PREFIX=$PREFIX echo I need Flower version $NEEDFLOWERVER diff --git a/flower/Makefile b/flower/Makefile index 611691fae6..447072b75a 100644 --- a/flower/Makefile +++ b/flower/Makefile @@ -6,7 +6,7 @@ $(staticlib): $(obs) fversion.hh include depend depend: Sources.make - $(CXX) -MM $(cc) > depend + $(CXX) $(CXXFLAGS) -MM $(cc) > depend clean: rm -f $(obs) $(staticlib) fversion.hh diff --git a/flower/NEWS b/flower/NEWS index c545441b69..4e397700ca 100644 --- a/flower/NEWS +++ b/flower/NEWS @@ -1,5 +1,12 @@ -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: ------------------ diff --git a/flower/Sources.make b/flower/Sources.make index 4b7cca4ec6..bfffc6084b 100644 --- a/flower/Sources.make +++ b/flower/Sources.make @@ -6,11 +6,12 @@ textdb.cc textstream.cc unionfind.cc vector.cc 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 diff --git a/flower/Variables.make b/flower/Variables.make index d2a35182bd..91802a52e8 100644 --- a/flower/Variables.make +++ b/flower/Variables.make @@ -1,11 +1,11 @@ MAJVER=1 MINVER=1 -PATCHLEVEL=0 +PATCHLEVEL=1 PACKAGENAME=flower #PROFILEFLAG=-pg -DEBUGFLAG= -g +#DEBUGFLAG= -g OPTIFLAG= -DNPRINT -O2 -DSTRING_UTILS_INLINED -DNDEBUG ######################################### diff --git a/flower/fproto.hh b/flower/fproto.hh index dcd17595d0..1d643ed621 100644 --- a/flower/fproto.hh +++ b/flower/fproto.hh @@ -27,7 +27,7 @@ struct Choleski_decomposition ; struct long_option_init ; struct Getopt_long ; struct Matrix ; -struct StringData ; +struct String_data ; struct String_handle ; struct String; struct virtual_smat ; @@ -36,5 +36,6 @@ class Text_stream; class Data_file ; struct Text_db; struct Scalar; +typedef unsigned char Byte; #endif // FPROTO_HH diff --git a/flower/string.cc b/flower/string.cc index 8a53710dcb..1e532a2fad 100644 --- a/flower/string.cc +++ b/flower/string.cc @@ -4,7 +4,7 @@ Rehacked by HWN 3/nov/95 removed String & - introduced Class String_handle + introduced class String_handle */ #include @@ -15,6 +15,10 @@ #include "string.hh" +#ifdef STRING_DEBUG +void* mymemmove( void* dest, void* src, size_t n ); +#define memmove mymemmove +#endif static char* strlwr( char* s ) @@ -58,9 +62,9 @@ String::String(Rational r) // 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; @@ -86,16 +90,16 @@ String::String( char const* source ) 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 @@ -104,16 +108,14 @@ String::length_i() const 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) @@ -133,13 +135,13 @@ String::String( const int i, const int n, char const c ) 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* @@ -149,9 +151,9 @@ String::ch_c_l() const } Byte* -String::by_l() +String::byte_l() { - return strh_.by_l(); + return strh_.byte_l(); } char* @@ -164,8 +166,8 @@ String::ch_l() 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; @@ -173,12 +175,8 @@ String::compare(String const& s1, String const& s2 ) int i2 = s2.length_i(); int i = i1 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 ); } @@ -338,7 +336,7 @@ String::upper() { // not binary safe assert( length_i() == strlen( ch_c_l() ) ); - char *s = strh_.by_l(); + char *s = strh_.byte_l(); strupr( s ); return *this; } @@ -350,7 +348,7 @@ String::lower() { // not binary safe assert( length_i() == strlen( ch_c_l() ) ); - char* s = strh_.by_l(); + char* s = strh_.byte_l(); strlwr(s); return *this; } @@ -401,18 +399,18 @@ String quoteString( String msg, String quote) 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; } @@ -420,6 +418,6 @@ String String::reversed() const { String str = *this; - strrev( str.by_l(), str.length_i() ); + strrev( str.byte_l(), str.length_i() ); return str; } diff --git a/flower/string.hh b/flower/string.hh index 23608994bf..a253b7ca61 100644 --- a/flower/string.hh +++ b/flower/string.hh @@ -1,8 +1,6 @@ /* - 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 @@ -17,7 +15,7 @@ #include #include -#include "stringutil.hh" +#include "stringhandle.hh" /** @@ -66,7 +64,7 @@ public: /// 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 ); @@ -82,12 +80,12 @@ public: 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(); } diff --git a/flower/stringconversion.cc b/flower/stringconversion.cc index 7a9d1f4551..55ea29ade4 100644 --- a/flower/stringconversion.cc +++ b/flower/stringconversion.cc @@ -12,10 +12,10 @@ String 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; } @@ -27,11 +27,11 @@ StringConversion::hex2bin_i( String hex_str, String& bin_str_r ) 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 ); diff --git a/flower/stringconversion.hh b/flower/stringconversion.hh index 39b809e4c4..3ad9bbea4b 100644 --- a/flower/stringconversion.hh +++ b/flower/stringconversion.hh @@ -4,12 +4,12 @@ */ -#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 ); diff --git a/flower/stringdata.hh b/flower/stringdata.hh new file mode 100644 index 0000000000..ba9099c440 --- /dev/null +++ b/flower/stringdata.hh @@ -0,0 +1,94 @@ +/* + stringdata.hh -- declare String_data + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#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 diff --git a/flower/stringdata.inl b/flower/stringdata.inl new file mode 100644 index 0000000000..927ca0998d --- /dev/null +++ b/flower/stringdata.inl @@ -0,0 +1,212 @@ +/* -*-C++-*- + String_data.inl -- implement String_data + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGDATA_INL +#define STRINGDATA_INL + +#include +#include + +#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 = 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 // diff --git a/flower/stringhandle.hh b/flower/stringhandle.hh new file mode 100644 index 0000000000..df92e50216 --- /dev/null +++ b/flower/stringhandle.hh @@ -0,0 +1,70 @@ +/* + stringhandle.hh -- declare String_handle + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#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 diff --git a/flower/stringhandle.inl b/flower/stringhandle.inl new file mode 100644 index 0000000000..bc84cd868b --- /dev/null +++ b/flower/stringhandle.inl @@ -0,0 +1,151 @@ +/* -*-c++-*- + + stringhandle.inl -- implement String_handle + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGHANDLE_INL +#define STRINGHANDLE_INL + +#include +#include + +#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 diff --git a/flower/stringutil.cc b/flower/stringutil.cc index bca803a23e..0596c458ad 100644 --- a/flower/stringutil.cc +++ b/flower/stringutil.cc @@ -1,340 +1,23 @@ -// 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 -#include -#include "stringutil.hh" + (c) 1997 Han-Wen Nienhuys +*/ -// 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" diff --git a/flower/stringutil.hh b/flower/stringutil.hh deleted file mode 100644 index 728ce9bb30..0000000000 --- a/flower/stringutil.hh +++ /dev/null @@ -1,150 +0,0 @@ -#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 // diff --git a/hdr/Makefile b/hdr/Makefile index f23ddcf6ca..384c9bc39e 100644 --- a/hdr/Makefile +++ b/hdr/Makefile @@ -1,6 +1,6 @@ default: $(MAKE) -C .. -DISTFILES=Makefile $(hdr) +DISTFILES=Makefile $(allhdr) dist: ln $(DISTFILES) $(DDIR)/$(SUBDIR) @@ -10,3 +10,4 @@ TAGS: $(hdr) clean: rm -f parser.hh + rm -f midi-parser.hh diff --git a/hdr/complexcolumn.hh b/hdr/complexcolumn.hh deleted file mode 100644 index 4065954b64..0000000000 --- a/hdr/complexcolumn.hh +++ /dev/null @@ -1,36 +0,0 @@ -/* - complexcolumn.hh -- declare Complex_column - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef COMPLEXCOLUMN_HH -#define COMPLEXCOLUMN_HH - -#include "stcol.hh" - -/// column of Complex_staff: store one request -struct Complex_column : Staff_column { - - Array first_l_arr_; - Array second_l_arr_; - - Complex_staff* staff_l_; - - /* *************** */ - - Slur_req *find_slur(Voice *); - - void typeset_musical_item(Item *); - void typeset_breakable_items(Array &pre_p_arr, - Array &nobreak_p_arr, - Array &post_p_arr); - virtual void setup_one_request(Request*); - - Complex_column(Complex_staff*rs); -}; - -#endif // COMPLEXCOLUMN_HH diff --git a/hdr/complexstaff.hh b/hdr/complexstaff.hh index 5a605d475e..b7d0c714d9 100644 --- a/hdr/complexstaff.hh +++ b/hdr/complexstaff.hh @@ -12,19 +12,14 @@ #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 diff --git a/hdr/complexwalker.hh b/hdr/complexwalker.hh index d8444c7c9e..5f0a808450 100644 --- a/hdr/complexwalker.hh +++ b/hdr/complexwalker.hh @@ -91,7 +91,6 @@ public: Complex_walker(Complex_staff*); ~Complex_walker(); - Complex_column *col(); Complex_staff *staff(); private: }; diff --git a/hdr/inputfile.hh b/hdr/inputfile.hh new file mode 100644 index 0000000000..5e55050299 --- /dev/null +++ b/hdr/inputfile.hh @@ -0,0 +1,28 @@ +/* + inputfile.hh -- declare Input_file + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef INPUT_FILE_HH +#define INPUT_FILE_HH +#include +#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 diff --git a/hdr/inputscore.hh b/hdr/inputscore.hh index 3b84d44fdb..88cc1894a8 100644 --- a/hdr/inputscore.hh +++ b/hdr/inputscore.hh @@ -24,7 +24,7 @@ struct Input_score { /// paper_, staffs_ and commands_ form the problem definition. Paperdef *paper_p_; - Mididef* midi_p_; + Midi_def* midi_p_; IPointerList staffs_; Input_music * score_wide_music_p_; @@ -37,7 +37,7 @@ struct Input_score { ~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*); diff --git a/hdr/lexer.hh b/hdr/lexer.hh index ce760fe22d..7f06158c3a 100644 --- a/hdr/lexer.hh +++ b/hdr/lexer.hh @@ -1,3 +1,11 @@ +/* + lexer.hh -- declare My_flex_lexer + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + #ifndef LEXER_HH #define LEXER_HH #include @@ -12,18 +20,6 @@ bool busy_parsing(); 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 { diff --git a/hdr/lyriccolumn.hh b/hdr/lyriccolumn.hh deleted file mode 100644 index e7aaaafc86..0000000000 --- a/hdr/lyriccolumn.hh +++ /dev/null @@ -1,30 +0,0 @@ -// -// lyriccolumn.hh -- declare Lyric_column -// -// copyright 1997 Jan Nieuwenhuizen - - -#ifndef LYRIC_COLUMN_HH -#define LYRIC_COLUMN_HH - -#include "key.hh" -#include "stcol.hh" -#include "staff.hh" - -/// (lcol) -struct Lyric_column : Staff_column { - - Array 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 - - - - diff --git a/hdr/lyricstaff.hh b/hdr/lyricstaff.hh index f7166bfc99..fb88c5e5aa 100644 --- a/hdr/lyricstaff.hh +++ b/hdr/lyricstaff.hh @@ -13,12 +13,8 @@ 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 diff --git a/hdr/lyricwalker.hh b/hdr/lyricwalker.hh index f89be76249..40ef06d972 100644 --- a/hdr/lyricwalker.hh +++ b/hdr/lyricwalker.hh @@ -10,7 +10,6 @@ #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 { @@ -20,7 +19,6 @@ struct Lyric_walker: Staff_walker { virtual void process_requests(); Lyric_walker(Lyric_staff* lstaff_l); - Lyric_column* lcol_l(); Lyric_staff* lstaff_l(); }; diff --git a/hdr/main.hh b/hdr/main.hh index e19b0aff12..4a4a85e786 100644 --- a/hdr/main.hh +++ b/hdr/main.hh @@ -10,6 +10,9 @@ void set_default_output(String s); 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 diff --git a/hdr/midicolumn.hh b/hdr/midicolumn.hh deleted file mode 100644 index 8d8b6353a3..0000000000 --- a/hdr/midicolumn.hh +++ /dev/null @@ -1,28 +0,0 @@ -// -// midicolumn.hh -- declare Midi_column -// -// copyright 1997 Jan Nieuwenhuizen - - -#ifndef MIDI_COLUMN_HH -#define MIDI_COLUMN_HH - -#include "key.hh" -#include "stcol.hh" -#include "staff.hh" - -/// (mcol) -struct Midi_column : Staff_column { - - Array 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 - diff --git a/hdr/mididef.hh b/hdr/mididef.hh index a2efdbecd0..9a24fa51ff 100644 --- a/hdr/mididef.hh +++ b/hdr/mididef.hh @@ -17,16 +17,16 @@ /** */ -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 ); diff --git a/hdr/midiitem.hh b/hdr/midiitem.hh index 9527c53375..d30e6448fc 100644 --- a/hdr/midiitem.hh +++ b/hdr/midiitem.hh @@ -5,62 +5,72 @@ #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 // diff --git a/hdr/midioutput.hh b/hdr/midioutput.hh new file mode 100644 index 0000000000..fed37feffa --- /dev/null +++ b/hdr/midioutput.hh @@ -0,0 +1,19 @@ +/* + midioutput.hh -- declare Midi_output + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#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 diff --git a/hdr/midiscorewalker.hh b/hdr/midiscorewalker.hh deleted file mode 100644 index 7ecce2a9ea..0000000000 --- a/hdr/midiscorewalker.hh +++ /dev/null @@ -1,28 +0,0 @@ -// -// midiscorewalker.hh -- declare Midi_score_walker -// -// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen -// - -#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 - - diff --git a/hdr/midistaff.hh b/hdr/midistaff.hh deleted file mode 100644 index 51053e89bf..0000000000 --- a/hdr/midistaff.hh +++ /dev/null @@ -1,28 +0,0 @@ -/* - midistaff.hh -- part of LilyPond - - copyright 1997 Jan Nieuwenhuizen - */ - -#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 - - - - - diff --git a/hdr/midiwalker.hh b/hdr/midiwalker.hh index e97c59864f..2121f57d3a 100644 --- a/hdr/midiwalker.hh +++ b/hdr/midiwalker.hh @@ -1,8 +1,8 @@ -// -// midiwalker.hh -- declare Midi_walker -// -// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen -// +/* + midiwalker.hh -- declare Midi_walker + + (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen + */ #ifndef MIDIWALKER_HH #define MIDIWALKER_HH @@ -10,16 +10,29 @@ #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 { + Midi_track *track_l_; + PQueue 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(); }; diff --git a/hdr/pcol.hh b/hdr/pcol.hh index 21fdb698d9..4fac246e49 100644 --- a/hdr/pcol.hh +++ b/hdr/pcol.hh @@ -51,8 +51,8 @@ struct PCol { /// 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); @@ -64,10 +64,10 @@ struct PCol { 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); diff --git a/hdr/proto.hh b/hdr/proto.hh index 967df3d56c..cfedd6b30f 100644 --- a/hdr/proto.hh +++ b/hdr/proto.hh @@ -28,7 +28,6 @@ struct Clef_register; struct Clef_item; struct Col_hpositions; struct Colinfo; -struct Complex_column; struct Complex_music; struct Complex_staff; struct Complex_walker; @@ -65,17 +64,22 @@ struct Measure_grouping_req; 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; diff --git a/hdr/sccol.hh b/hdr/sccol.hh index 8237822219..e961d04920 100644 --- a/hdr/sccol.hh +++ b/hdr/sccol.hh @@ -44,7 +44,7 @@ public: void preprocess(); bool breakable_b(); bool musical_b() { return musical_b_; } - bool used(); + bool used_b(); void print() const; diff --git a/hdr/score.hh b/hdr/score.hh index b9555b2036..bab7020ccc 100644 --- a/hdr/score.hh +++ b/hdr/score.hh @@ -21,7 +21,7 @@ struct Score { /// paper_, staffs_ and commands_ form the problem definition. Paperdef *paper_p_; - Mididef *midi_p_; + Midi_def *midi_p_; IPointerList staffs_; /// "runtime" fields for setting up spacing @@ -34,7 +34,7 @@ struct Score { /* *************************************************************** */ /// construction - Score(Paperdef*); + Score(); ~Score(); void add(Staff*); @@ -44,11 +44,11 @@ struct Score { /// 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; @@ -61,8 +61,15 @@ struct Score { 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 create_cols(Moment); diff --git a/hdr/scorewalker.hh b/hdr/scorewalker.hh index 0bfc991374..fdbad24fae 100644 --- a/hdr/scorewalker.hh +++ b/hdr/scorewalker.hh @@ -19,6 +19,7 @@ */ class Score_walker : public PCursor { + Score* score_l_; /// walkers for the individual staves. Array walker_p_arr_; Array disallow_break_walk_l_arr; diff --git a/hdr/source.hh b/hdr/source.hh index 3bdbef721e..6c79b75a99 100644 --- a/hdr/source.hh +++ b/hdr/source.hh @@ -19,4 +19,8 @@ private: IPointerList sourcefile_p_iplist_; }; + +// ugh +extern Source* source_l_g; + #endif // SOURCE_HH // diff --git a/hdr/staff.hh b/hdr/staff.hh index 74b7df1340..e45398e789 100644 --- a/hdr/staff.hh +++ b/hdr/staff.hh @@ -15,20 +15,21 @@ /// base class for a collection of voices. class Staff { - Staff_column *get_col(Moment, PCursor * last= 0); Staff(const Staff&src); /// synchronous horizontal stuff IPointerList voice_list_; + Staff_column *get_col(Moment, PCursor * last= 0); public: /// runtime field - IPointerList cols; + IPointerList cols_; Score *score_l_; PScore *pscore_l_; - + PStaff *pstaff_l_; + /* *************************************************************** */ void add(const PointerList &s); @@ -55,6 +56,6 @@ public: virtual Staff_walker *get_walker_p()=0; virtual ~Staff() { } protected: - virtual Staff_column * create_col()=0; + }; #endif diff --git a/hdr/stcol.hh b/hdr/stcol.hh index 613dffb758..b6ecdb18a6 100644 --- a/hdr/stcol.hh +++ b/hdr/stcol.hh @@ -12,8 +12,14 @@ /// store simultaneous requests class Staff_column { + Staff_column(Staff_column const&); + public: + Array musicalreq_l_arr_; + Array commandreq_l_arr_; + Staff * staff_l_; + /// fields to collect timing data vertically. Array timing_req_l_arr_; Score_column *musical_column_l_, *command_column_l_; @@ -26,12 +32,13 @@ public: 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 &pre_p_arr, + Array &nobreak_p_arr, + Array &post_p_arr); + void typeset_musical_item(Item *i); protected: - virtual void setup_one_request(Request*)=0; - + void setup_one_request(Request*); }; diff --git a/input/cadenza.ly b/input/cadenza.ly index fb7669e3fa..76095fc06e 100644 --- a/input/cadenza.ly +++ b/input/cadenza.ly @@ -53,6 +53,6 @@ score { cadenza {1} grouping{1*4} } + paper {} midi { tempo 4:80 } - staff { midi music { cad } } } \ No newline at end of file diff --git a/input/error.ly b/input/error.ly index 74924e9b25..283f48922d 100644 --- a/input/error.ly +++ b/input/error.ly @@ -5,7 +5,7 @@ mwa = music { [ 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 diff --git a/input/maartje.ly b/input/maartje.ly index 9a79cf47c3..7f35583ae2 100644 --- a/input/maartje.ly +++ b/input/maartje.ly @@ -57,14 +57,15 @@ score { 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} } diff --git a/input/martien.ly b/input/martien.ly index 683f14d464..86c737badc 100644 --- a/input/martien.ly +++ b/input/martien.ly @@ -42,37 +42,20 @@ score { 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 } diff --git a/input/midi.ly b/input/midi.ly index c08b1bc348..bdb0a48d38 100644 --- a/input/midi.ly +++ b/input/midi.ly @@ -1,12 +1,9 @@ % 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 | % :| $ } @@ -15,7 +12,7 @@ begeleiding = music { $ \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 | $ } @@ -31,15 +28,8 @@ bass_staf = staff { } 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 } diff --git a/input/pavane.ly b/input/pavane.ly index 1e2c6da688..bb7fd643b0 100644 --- a/input/pavane.ly +++ b/input/pavane.ly @@ -115,5 +115,4 @@ score { bar "||" } midi { tempo 4:70 } - staff { midi music { horn } } } diff --git a/input/scsii-menuetto.ly b/input/scsii-menuetto.ly index 932bd7d381..872615b1b3 100644 --- a/input/scsii-menuetto.ly +++ b/input/scsii-menuetto.ly @@ -132,14 +132,10 @@ score { 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" diff --git a/input/standchen.ly b/input/standchen.ly index 219cb50765..4d104f84ee 100644 --- a/input/standchen.ly +++ b/input/standchen.ly @@ -216,9 +216,6 @@ begeleiding = music { $ %%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 } } | @@ -464,19 +461,19 @@ tekst2 = music { } 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} } @@ -485,14 +482,10 @@ score { 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 } diff --git a/input/twinkle.ly b/input/twinkle.ly index a356386099..035854e846 100644 --- a/input/twinkle.ly +++ b/input/twinkle.ly @@ -152,11 +152,9 @@ score { } 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 } diff --git a/input/wohltemperirt.ly b/input/wohltemperirt.ly index 1038169bab..b5ea0f6654 100644 --- a/input/wohltemperirt.ly +++ b/input/wohltemperirt.ly @@ -42,31 +42,32 @@ bassdux = music { $ 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 } diff --git a/src/Makefile b/src/Makefile index 8c88c5dbc7..e78d5785f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,12 +4,12 @@ default: 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) diff --git a/src/barreg.cc b/src/barreg.cc index 566b9d58a5..9a10f913b5 100644 --- a/src/barreg.cc +++ b/src/barreg.cc @@ -10,7 +10,6 @@ #include "bar.hh" #include "commandrequest.hh" #include "complexwalker.hh" -#include "complexcolumn.hh" #include "sccol.hh" diff --git a/src/calcideal.cc b/src/calcideal.cc index a656482e7d..08180c64fb 100644 --- a/src/calcideal.cc +++ b/src/calcideal.cc @@ -18,7 +18,7 @@ Score::calc_idealspacing() iter_top(cols_,i); for (; i.ok(); i++) { - assert(i->used()); + assert(i->used_b()); PCursor j(i+1); if (i->musical_b()) { assert(j.ok()); diff --git a/src/complexcolumn.cc b/src/complexcolumn.cc deleted file mode 100644 index 22e695016a..0000000000 --- a/src/complexcolumn.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - complexcolumn.cc -- implement Complex_column - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ -#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_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_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 &pre_p_arr, - Array &nobreak_p_arr, - Array &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); -} diff --git a/src/complexstaff.cc b/src/complexstaff.cc index 3ecf9fdb89..9eb84cb59a 100644 --- a/src/complexstaff.cc +++ b/src/complexstaff.cc @@ -1,7 +1,6 @@ #include "debug.hh" #include "complexstaff.hh" #include "complexwalker.hh" -#include "complexcolumn.hh" #include "score.hh" #include "pscore.hh" #include "staffsym.hh" @@ -22,10 +21,7 @@ Complex_staff::set_output(PScore* pscore_l ) 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); @@ -38,16 +34,6 @@ Complex_staff::set_output(PScore* pscore_l ) 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() diff --git a/src/complexwalker.cc b/src/complexwalker.cc index c6478fbb23..f85abe8f21 100644 --- a/src/complexwalker.cc +++ b/src/complexwalker.cc @@ -173,14 +173,14 @@ Complex_walker::try_request(Request*req) 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(); @@ -212,7 +212,7 @@ Complex_walker::typeset_element(Staff_elem *elem_p) 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) @@ -255,11 +255,6 @@ Complex_walker::staff() return (Complex_staff*) staff_l_; } -Complex_column* -Complex_walker::col() -{ - return (Complex_column*) *(*this); -} void Complex_walker::do_pre_move() @@ -275,7 +270,7 @@ 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_); } diff --git a/src/inputscore.cc b/src/inputscore.cc index 82d7a6c96a..6fca9dc8eb 100644 --- a/src/inputscore.cc +++ b/src/inputscore.cc @@ -30,7 +30,7 @@ Input_score::set(Paperdef*p) } void -Input_score::set(Mididef* midi_p) +Input_score::set(Midi_def* midi_p) { delete midi_p_; midi_p_ = midi_p; @@ -39,6 +39,7 @@ Input_score::set(Mididef* 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_) ? @@ -48,12 +49,13 @@ Input_score::Input_score(Input_score const&s) 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_); diff --git a/src/inputstaff.cc b/src/inputstaff.cc index 7fbc37dbac..952af6bd71 100644 --- a/src/inputstaff.cc +++ b/src/inputstaff.cc @@ -13,7 +13,7 @@ #include "staff.hh" #include "complexstaff.hh" #include "lyricstaff.hh" -#include "midistaff.hh" + #include "lexer.hh" @@ -38,8 +38,6 @@ Input_staff::parse(Score*score_l, Input_music *default_score_wide) 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 ); diff --git a/src/lexerinit.cc b/src/lexerinit.cc index 43a1c2c5a6..02dd000e63 100644 --- a/src/lexerinit.cc +++ b/src/lexerinit.cc @@ -1,3 +1,11 @@ +/* + lexerinit.cc -- implement some stuff + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + #include #include #include "proto.hh" @@ -20,28 +28,3 @@ busy_parsing() { 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 << "["<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_); -} diff --git a/src/lyricstaff.cc b/src/lyricstaff.cc index 6d199970c7..8ee1793328 100644 --- a/src/lyricstaff.cc +++ b/src/lyricstaff.cc @@ -4,21 +4,9 @@ #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) { diff --git a/src/lyricwalker.cc b/src/lyricwalker.cc index 51a2b03594..fbff9a8cd5 100644 --- a/src/lyricwalker.cc +++ b/src/lyricwalker.cc @@ -13,15 +13,20 @@ #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); } } @@ -32,15 +37,3 @@ Lyric_walker::Lyric_walker(Lyric_staff* lstaff_l) } - -Lyric_staff* -Lyric_walker::lstaff_l() -{ - return (Lyric_staff*)staff_l_; -} - -Lyric_column* -Lyric_walker::lcol_l() -{ - return (Lyric_column*) *(*this); -} diff --git a/src/main.cc b/src/main.cc index e100ec2884..55a5129055 100644 --- a/src/main.cc +++ b/src/main.cc @@ -12,8 +12,8 @@ #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); @@ -26,6 +26,7 @@ long_option_init theopts[] = { 0, "debug", 'd', 1, "init", 'i', 1, "include", 'I', + 0, "midi", 'M', 0,0,0 }; @@ -39,11 +40,13 @@ help() "--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" @@ -110,6 +113,9 @@ main (int argc, char **argv) case 'd': set_debug(true); break; + case 'M': + only_midi = true; + break; default: assert(false); break; diff --git a/src/midi-lexer.l b/src/midi-lexer.l new file mode 100644 index 0000000000..d95696dbb5 --- /dev/null +++ b/src/midi-lexer.l @@ -0,0 +1,261 @@ +%{ +// midi-lexer.l + +#include + +#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} { + puts( "lex: int32" ); + assert( YYLeng() == 4 ); + String str( (Byte const*)YYText(), YYLeng() ); + yylval.i = StringConversion::bin2int_i( str ); + yy_pop_state(); + return INT32; +} +{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} { + puts( "lex: int8" ); + assert( YYLeng() == 1 ); +// yylval.byte = *(Byte*)YYText(); + yylval.i = *(Byte*)YYText(); + yy_pop_state(); + return INT8; +} + +{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; +} + +{RUNNING_STATUS} { + yylval.byte = *(Byte*)YYText(); + yy_pop_state(); + yy_push_state( int8 ); + return RUNNING_STATUS; +} +{NOTE_OFF} { + puts( "lex: note off" ); + yylval.byte = *(Byte*)YYText(); + yy_pop_state(); + yy_push_state( int8 ); + yy_push_state( int8 ); + return NOTE_OFF; +} +{NOTE_ON} { + puts( "lex: note on" ); + yylval.byte = *(Byte*)YYText(); + yy_pop_state(); + yy_push_state( int8 ); + yy_push_state( int8 ); + return NOTE_ON; +} +{PROGRAM_CHANGE} { + yylval.byte = *(Byte*)YYText(); + yy_pop_state(); + yy_push_state( int8 ); + return PROGRAM_CHANGE; +} +{META_EVENT} { + yy_push_state( meta_event ); + return META_EVENT; +} + +{SEQUENCE} { // ssss sequence number + yy_push_state( int16 ); + return SEQUENCE; +} +{TEXT} { // len data + yy_push_state( data ); + return TEXT; +} +{COPYRIGHT} { + yy_push_state( data ); + return COPYRIGHT; +} +{TRACK_NAME} { + yy_push_state( data ); + return TRACK_NAME; +} +{INSTRUMENT_NAME} { + yy_push_state( data ); + return INSTRUMENT_NAME; +} +{LYRIC} { + yy_push_state( data ); + return LYRIC; +} +{MARKER} { + yy_push_state( data ); + return MARKER; +} +{CUE_POINT} { + yy_push_state( data ); + return CUE_POINT; +} +{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; +} +{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; +} +{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; +} +{KEY} { // sf mi + puts( "lex: key" ); + yy_pop_state(); + yy_pop_state(); + yy_push_state( int8 ); + yy_push_state( int8 ); + return KEY; +} +{SSME} { // len data + yy_pop_state(); + yy_pop_state(); + yy_push_state( data ); + return SSME; +} +{END_OF_TRACK} { + puts( "lex: end of track" ); + yy_pop_state(); + yy_pop_state(); + yy_pop_state(); + return END_OF_TRACK; +} +{INT8} { + yylval.byte = *(Byte*)YYText(); + return INT8; +} + +{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; +} + + +<> { +// mtor << "<>"; + + if ( !close_i() ) + yyterminate(); // can't move this, since it actually rets a YY_NULL +} + +%% + diff --git a/src/midi-parser.y b/src/midi-parser.y new file mode 100644 index 0000000000..519266f1fb --- /dev/null +++ b/src/midi-parser.y @@ -0,0 +1,173 @@ +%{ + +#include + +#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 INT8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT +%token RUNNING_STATUS NOTE_OFF NOTE_ON PROGRAM_CHANGE +%token DATA + +%type header midi_score +%type track +%type event +%type the_event meta_event text_event midi_event sysex_event +%type 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 { + } + ; diff --git a/src/midicolumn.cc b/src/midicolumn.cc deleted file mode 100644 index 13abbd03d5..0000000000 --- a/src/midicolumn.cc +++ /dev/null @@ -1,44 +0,0 @@ -#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 ); - } -} diff --git a/src/mididef.cc b/src/mididef.cc index 56ee59e0b7..2c7bf7a7a7 100644 --- a/src/mididef.cc +++ b/src/mididef.cc @@ -16,24 +16,24 @@ // 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; @@ -42,13 +42,13 @@ Mididef::duration_to_seconds_f( Moment moment ) } 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 ); @@ -58,7 +58,7 @@ Mididef::print() const } 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; } diff --git a/src/midiitem.cc b/src/midiitem.cc index e7d5ccc92f..b86eb95f1b 100644 --- a/src/midiitem.cc +++ b/src/midiitem.cc @@ -23,104 +23,111 @@ Midi_chunk::Midi_chunk() 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( ""; + return String( ""; } 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 ) @@ -139,40 +146,41 @@ 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() ); } diff --git a/src/midiscorewalker.cc b/src/midiscorewalker.cc deleted file mode 100644 index cfe92e7913..0000000000 --- a/src/midiscorewalker.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - midiscorewalker.cc -- implement Midi_score_walker - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys , Jan Nieuwehuizen -*/ -#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() -{ -} - diff --git a/src/midistaff.cc b/src/midistaff.cc deleted file mode 100644 index c63ac9688b..0000000000 --- a/src/midistaff.cc +++ /dev/null @@ -1,50 +0,0 @@ -#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! -} - diff --git a/src/midiwalker.cc b/src/midiwalker.cc index 5072fb6320..f1d74d87e4 100644 --- a/src/midiwalker.cc +++ b/src/midiwalker.cc @@ -6,38 +6,55 @@ (c) 1997 Han-Wen Nienhuys , Jan Nieuwenhuizen */ -#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(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 +} diff --git a/src/mylexer.cc b/src/mylexer.cc index ea86b3094b..a02c323ea3 100644 --- a/src/mylexer.cc +++ b/src/mylexer.cc @@ -3,6 +3,7 @@ #include "identparent.hh" #include "associter.hh" #include "lexer.hh" +#include "inputfile.hh" #include "parser.hh" #include "keyword.hh" #include "assoc.hh" diff --git a/src/paperdef.cc b/src/paperdef.cc index 21cc42f317..f5c3bcdfae 100644 --- a/src/paperdef.cc +++ b/src/paperdef.cc @@ -32,6 +32,7 @@ Paperdef::Paperdef(Lookup *l) linewidth = 15 *CM_TO_PT; // in cm for now whole_width = 8 * note_width(); geometric_ = sqrt(2); + outfile = "lelie.out"; } Paperdef::~Paperdef() diff --git a/src/parser.y b/src/parser.y index f761069e3e..d065f19cae 100644 --- a/src/parser.y +++ b/src/parser.y @@ -39,7 +39,7 @@ int fatal_error_i = 0; String *string; const char *consstr; Paperdef *paper; - Mididef* midi; + Midi_def* midi; Input_music *music; Music_general_chord *chord; Music_voice *mvoice; @@ -201,7 +201,7 @@ score_block: /*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. */ @@ -267,7 +267,7 @@ midi_block: ; midi_body: { - $$ = new Mididef; + $$ = new Midi_def; } | midi_body OUTPUT STRING { $$->outfile_str_ = *$3; @@ -300,9 +300,6 @@ staff_init: $$ = new Input_staff(*$1); delete $1; } - | MIDI { - $$ = new Input_staff("midi"); - } ; staff_body: diff --git a/src/pcol.cc b/src/pcol.cc index 5256947ce7..4f1b65dcd7 100644 --- a/src/pcol.cc +++ b/src/pcol.cc @@ -115,7 +115,7 @@ PCol::add( Item *i) } bool -PCol::used()const +PCol::used_b()const { return breakable_b() || its.size(); } diff --git a/src/pscore.cc b/src/pscore.cc index c18fe83e01..cebeb86f4c 100644 --- a/src/pscore.cc +++ b/src/pscore.cc @@ -27,7 +27,7 @@ void PScore::clean_cols() { for (iter_top(cols,c); c.ok(); ) - if (!c->used()) { + if (!c->used_b()) { delete c.get(); } else c++; diff --git a/src/sccol.cc b/src/sccol.cc index 1722599b21..43d549b175 100644 --- a/src/sccol.cc +++ b/src/sccol.cc @@ -30,8 +30,8 @@ Score_column::Score_column(Moment w) } bool -Score_column::used() { - return pcol_l_->used(); +Score_column::used_b() { + return pcol_l_->used_b(); } void diff --git a/src/score.cc b/src/score.cc index 368188bbc1..83bffd72f7 100644 --- a/src/score.cc +++ b/src/score.cc @@ -5,7 +5,6 @@ (c) 1997 Han-Wen Nienhuys */ - #include "tstream.hh" #include "score.hh" #include "sccol.hh" @@ -17,12 +16,10 @@ #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() @@ -33,14 +30,7 @@ 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(); } @@ -60,10 +50,28 @@ Score::process() { 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(); @@ -71,6 +79,10 @@ Score::process() OK(); *mlog << endl; pscore_p_->process(); + + // output + paper_output(); + } /** @@ -83,7 +95,7 @@ Score::clean_cols() 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(); @@ -148,12 +160,14 @@ Score::find_col(Moment w, bool mus) 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 @@ -167,7 +181,14 @@ Score::last() const } 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; @@ -203,15 +224,17 @@ Score::print() const } 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; @@ -225,24 +248,24 @@ Score::~Score() } 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); } @@ -253,23 +276,11 @@ Score::midi() if (!midi_p_) return; - *mlog << "midi output to " << midi_p_->outfile_str_ << "...\n"; - - int track_i = 0; - for ( PCursor 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_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 diff --git a/src/scores.cc b/src/scores.cc index 2788fe062a..b4019fd141 100644 --- a/src/scores.cc +++ b/src/scores.cc @@ -2,22 +2,33 @@ #include "inputscore.hh" #include "score.hh" #include "string.hh" +#include "paperdef.hh" +#include "debug.hh" static Array 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); @@ -29,20 +40,9 @@ add_score(Input_score * s) 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; } diff --git a/src/scorewalker.cc b/src/scorewalker.cc index 760bd29c75..1cd9339ce9 100644 --- a/src/scorewalker.cc +++ b/src/scorewalker.cc @@ -16,6 +16,7 @@ Score_walker::Score_walker(Score *s) :PCursor (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; @@ -104,6 +105,7 @@ Score_walker::~Score_walker() { 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()); } diff --git a/src/sourcefile.cc b/src/sourcefile.cc index f10d419b5a..0775719160 100644 --- a/src/sourcefile.cc +++ b/src/sourcefile.cc @@ -152,6 +152,7 @@ Source_file::map() 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() ); } diff --git a/src/staff.cc b/src/staff.cc index c93ca997cc..a996964661 100644 --- a/src/staff.cc +++ b/src/staff.cc @@ -26,11 +26,11 @@ Staff::paper() const 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_) @@ -40,17 +40,10 @@ Staff::clean_cols() } } -// 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 *last) { - iter_top(cols,i); + iter_top(cols_,i); if (last && last->ok() && (*last)->when() <= w) i = *last; @@ -65,14 +58,14 @@ Staff::get_col(Moment w, PCursor *last) PCursor 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--; @@ -90,7 +83,7 @@ void Staff::setup_staffcols() { for (iter_top(voice_list_,i); i.ok(); i++) { - PCursor last(cols); + PCursor last(cols_); Moment now = i->start; for (iter_top(i->elts,j); j.ok(); j++) { @@ -99,7 +92,7 @@ Staff::setup_staffcols() s_l->add(j); now += j->duration; } -// get_col(now,last); + } OK(); } @@ -108,10 +101,10 @@ void 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() ); @@ -146,5 +139,6 @@ Staff::print() const Staff::Staff() { score_l_ =0; - pscore_l_ =0; + pscore_l_ =0; + pstaff_l_ =0; } diff --git a/src/staffwalker.cc b/src/staffwalker.cc index d93243255d..bba82e38b8 100644 --- a/src/staffwalker.cc +++ b/src/staffwalker.cc @@ -30,11 +30,13 @@ Staff_walker::Staff_walker(Staff_walker const &s) } Staff_walker::Staff_walker(Staff * s, PScore*ps ) - : PCursor (s->cols) + : PCursor (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; } @@ -98,6 +100,7 @@ Staff_walker::process() process_timing_reqs(); process_requests(); } + void Staff_walker::allow_break() { diff --git a/src/stcol.cc b/src/stcol.cc index f3498db0e1..c12a0d898f 100644 --- a/src/stcol.cc +++ b/src/stcol.cc @@ -5,13 +5,17 @@ (c) 1997 Han-Wen Nienhuys */ - +#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 @@ -34,16 +38,19 @@ Staff_column::add(Voice_element*ve) { 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); } } } @@ -52,6 +59,7 @@ Staff_column::Staff_column() { musical_column_l_ = 0; command_column_l_ = 0; + staff_l_ = 0; } @@ -67,3 +75,85 @@ Staff_column::set_cols(Score_column*c1, Score_column*c2) 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_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_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 &pre_p_arr, + Array &nobreak_p_arr, + Array &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); +} diff --git a/src/stem.cc b/src/stem.cc index b11386afec..22123356c6 100644 --- a/src/stem.cc +++ b/src/stem.cc @@ -88,7 +88,7 @@ Stem::set_default_stemlen() 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; @@ -111,7 +111,7 @@ Stem::set_default_extents() 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; } diff --git a/src/warn.cc b/src/warn.cc index 63490de581..b57c6d2bdc 100644 --- a/src/warn.cc +++ b/src/warn.cc @@ -48,7 +48,7 @@ void 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(": "); } -- 2.39.2