From: fred Date: Sun, 24 Mar 2002 19:32:39 +0000 (+0000) Subject: lilypond-0.0.33 X-Git-Tag: release/1.5.59~5338 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=cb987b2bb958540f025ca179eb351b5812602c85;p=lilypond.git lilypond-0.0.33 --- diff --git a/.dstreamrc b/.dstreamrc index b4d6029922..b2c6cfc5da 100644 --- a/.dstreamrc +++ b/.dstreamrc @@ -38,8 +38,9 @@ Input_cursor 1 Commands_at 1 Input_command 1 Time_description 1 -Melodic_req 0 -Stem_req 0 +Melodic_req 1 +Midi_walker 0 +Stem_req 1 Group_change_req 1 Script_req 1 Colinfo 1 diff --git a/Sources.make b/Sources.make index ffb0f96cd5..2312887b2a 100644 --- a/Sources.make +++ b/Sources.make @@ -12,7 +12,10 @@ hdr= bar.hh barreg.hh beam.hh boxes.hh break.hh clefreg.hh clefitem.hh\ keyword.hh leastsquares.hh lexer.hh linespace.hh \ localkeyitem.hh localkeyreg.hh lookup.hh \ lyriccolumn.hh lyricitem.hh lyricstaff.hh lyricwalker.hh\ - main.hh meter.hh meterreg.hh misc.hh\ + main.hh meter.hh meterreg.hh\ + midicolumn.hh mididef.hh midiitem.hh midistaff.hh midistream.hh\ + midiwalker.hh midiscorewalker.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\ @@ -42,6 +45,8 @@ mycc=bar.cc barreg.cc beam.cc boxes.cc break.cc calcideal.cc clefreg.cc\ localkeyitem.cc localkeyreg.cc lookup.cc\ lyriccolumn.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\ register.cc request.cc rest.cc sccol.cc score.cc\ diff --git a/hdr/lexer.hh b/hdr/lexer.hh index 8f1e67123e..ce760fe22d 100644 --- a/hdr/lexer.hh +++ b/hdr/lexer.hh @@ -31,7 +31,6 @@ struct My_flex_lexer : yyFlexLexer { Assoc *the_id_tab; Keyword_table * keytable; Notename_tab * defaulttab; - char const* data_ch_c_l_; int errorlevel_i_; /* *************** */ int ret_notename(int *p, String text, int octave_mod); diff --git a/hdr/lyriccolumn.hh b/hdr/lyriccolumn.hh index a7202e593d..e7aaaafc86 100644 --- a/hdr/lyriccolumn.hh +++ b/hdr/lyriccolumn.hh @@ -1,11 +1,11 @@ // // lyriccolumn.hh -- declare Lyric_column // -// copyright 1997 Jan Nieuwenhuizen +// copyright 1997 Jan Nieuwenhuizen -#ifndef LYRICCOLUMN_HH -#define LYRICCOLUMN_HH +#ifndef LYRIC_COLUMN_HH +#define LYRIC_COLUMN_HH #include "key.hh" #include "stcol.hh" @@ -23,7 +23,7 @@ struct Lyric_column : Staff_column { Lyric_column(Lyric_staff*rs); }; -#endif // LYRICSTAFF_HH +#endif // LYRIC_COLUMN_HH diff --git a/hdr/midicolumn.hh b/hdr/midicolumn.hh new file mode 100644 index 0000000000..8d8b6353a3 --- /dev/null +++ b/hdr/midicolumn.hh @@ -0,0 +1,28 @@ +// +// 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 new file mode 100644 index 0000000000..a2efdbecd0 --- /dev/null +++ b/hdr/mididef.hh @@ -0,0 +1,38 @@ +/* + mididef.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + + +#ifndef MIDIDEF_HH +#define MIDIDEF_HH +#include "proto.hh" +#include "real.hh" +#include "string.hh" +#include "moment.hh" + + +/** + */ +struct Mididef { + /// output file name + String outfile_str_; + + /// duration of whole note + Real whole_seconds_f_; + + Mididef(); + Mididef(Mididef const& midi_c_r); + ~Mididef(); + + Real duration_to_seconds_f(Moment); + int get_tempo_i( Moment moment ); + void set_tempo( Moment moment, int count_per_minute_i ); + void print() const; +}; + +#endif // MIDIDEF_HH // + diff --git a/hdr/midiitem.hh b/hdr/midiitem.hh new file mode 100644 index 0000000000..9527c53375 --- /dev/null +++ b/hdr/midiitem.hh @@ -0,0 +1,67 @@ +// +// midiitem.hh -- part of LilyPond +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MIDI_ITEM_HH +#define MIDI_ITEM_HH + +struct Midi_item { + /* *************** */ + 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 ); + + virtual String str(); + + int channel_i_; + int on_bo_; + int pitch_i_; +}; + +struct Midi_duration : public Midi_item { + /* *************** */ + Midi_duration( Real seconds_f ); + + virtual String str(); + + Real seconds_f_; +}; + +struct Midi_chunk : Midi_item { + /* *************** */ + Midi_chunk(); + + 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_; +}; + +struct Midi_header : Midi_chunk { + /* *************** */ + Midi_header( int format_i, int tracks_i, int tempo_i ); +}; + +struct Midi_track : Midi_chunk { + /* *************** */ + int number_i_; + Midi_track( int number_i ); + + 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 ); +}; + +#endif // MIDI_ITEM_HH // + diff --git a/hdr/midiscorewalker.hh b/hdr/midiscorewalker.hh new file mode 100644 index 0000000000..7ecce2a9ea --- /dev/null +++ b/hdr/midiscorewalker.hh @@ -0,0 +1,28 @@ +// +// 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 new file mode 100644 index 0000000000..51053e89bf --- /dev/null +++ b/hdr/midistaff.hh @@ -0,0 +1,28 @@ +/* + 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/midistream.hh b/hdr/midistream.hh new file mode 100644 index 0000000000..34e9c9b523 --- /dev/null +++ b/hdr/midistream.hh @@ -0,0 +1,32 @@ +// +// midistream.hh -- part of LilyPond +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MIDI_STREAM_HH +#define MIDI_STREAM_HH + +#include +#include "string.hh" + +/// Midi output +struct Midi_stream { + ostream* os_p_; + String filename_str_; + int tempo_i_; + int tracks_i_; + + Midi_stream( String filename_str, int tracks_i, int tempo_i ); + ~Midi_stream(); + + Midi_stream& operator <<( String str ); + Midi_stream& operator <<( Midi_item& mitem_r ); + Midi_stream& operator <<( int i ); + + void header(); + void open(); + +//private: +// Midi_stream(Midi_stream const&); +}; +#endif // MIDI_STREAM_HH // diff --git a/hdr/midiwalker.hh b/hdr/midiwalker.hh new file mode 100644 index 0000000000..e97c59864f --- /dev/null +++ b/hdr/midiwalker.hh @@ -0,0 +1,28 @@ +// +// midiwalker.hh -- declare Midi_walker +// +// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen +// + +#ifndef MIDIWALKER_HH +#define MIDIWALKER_HH + +#include "proto.hh" +#include "grouping.hh" +#include "staffwalker.hh" + +/// 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(); +}; + + +#endif // MIDIWALKER_HH + + diff --git a/hdr/musicalrequest.hh b/hdr/musicalrequest.hh index 2a864eb9ef..240b72afd9 100644 --- a/hdr/musicalrequest.hh +++ b/hdr/musicalrequest.hh @@ -96,6 +96,8 @@ struct Melodic_req :virtual Musical_req /// return height from central c (in halflines) int height()const; + /// return pitch from central c (in halfnotes) + int pitch()const; Melodic_req(); REQUESTMETHODS(Melodic_req,melodic); @@ -144,6 +146,17 @@ struct Span_req : Musical_req { }; +/// request for backward plet generation +struct Plet_req : Request { + char type_c_; + int dur_i_; + int type_i_; + Plet_req(); + + REQUESTMETHODS(Plet_req,plet); +}; +/** +*/ /** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an appropriate number over the beam diff --git a/hdr/proto.hh b/hdr/proto.hh index 1ef4d8d9f2..967df3d56c 100644 --- a/hdr/proto.hh +++ b/hdr/proto.hh @@ -1,4 +1,3 @@ - /* proto.hh -- part of LilyPond @@ -14,93 +13,117 @@ struct Absdynamic_req; struct Accidental; struct Atom; +struct Bar; +struct Bar_register; struct Barcheck_req; +struct Bar_req; struct Beam; struct Beam_req; struct Box; struct Bracket_req; -struct CNote_info; +struct Cadenza_req; struct Chord; -struct Clef; +struct Clef_change_req; +struct Clef_register; struct Clef_item; struct Col_hpositions; struct Colinfo; -struct Command; -struct Commands_at ; struct Complex_column; struct Complex_music; struct Complex_staff; struct Complex_walker; struct Cresc_req; struct Decresc_req; +struct Durational_req; struct Dynamic; struct Group_change_req; struct Group_feature_req; struct Idealspacing; struct Identifier; -struct Input_command; -struct Input_commands; struct Input_file; struct Input_music; struct Input_score; struct Input_staff; struct Item; struct Key; -struct Keyitem; +struct Key_register; +struct Key_change_req; +struct Key_item; struct Keyword; struct Keyword_table; struct Line_of_score; struct Line_of_staff; struct Linestaff; struct Local_key; +struct Local_key_register; struct Local_key_item; struct Lookup; +struct Lyric_item; struct Lyric_req; -struct Lyric_req; -struct Mark_req; struct Melodic_req; +struct Measure_grouping_req; +struct Meter_change_req; +struct Meter; +struct Meter_register; +struct Midi_column; +struct Mididef; +struct Midi_duration; +struct Midi_header; +struct Midi_item; +struct Midi_pitch; +struct Midi_staff; +struct Midi_stream; +struct Midi_track; +struct Midi_walker; struct Mixed_qp; struct Molecule; +struct Musical_req; struct Music_general_chord; struct Music_voice; +struct Nonmusical_req; struct Note_req; struct Notehead; +struct Notehead_register; struct Notename_tab; struct Offset; struct Output; struct PCol; +struct Plet_req; struct PScore; struct PStaff; struct Paperdef; -struct Parametric_symbol; +struct Partial_measure_req; struct Rational; struct Request; struct Request_register; struct Rest; struct Rest_req; struct Rhythmic_grouping; +struct Rhythmic_grouping_req; struct Rhythmic_req; struct Score; struct Score_column; +struct Score_walker; struct Script_def; struct Script; +struct Script_register; struct Script_req; struct Simple_music; +struct Skip_req; struct Slur; +struct Slur_register; struct Slur_req; -class Source; -class Source_file; +struct Source; +struct Source_file; struct Spacing_req ; struct Span_req; struct Spanner; struct Blank_req; struct Staff; struct Staff_column; -struct Staff_command_req; -struct Staff_commands; -struct Staff_commands_at ; struct Staff_elem; struct Staff_elem_info; +struct Staff_symbol; struct Staff_walker; struct Stem; struct Stem_req; @@ -114,7 +137,9 @@ struct Terminate_voice_req; struct Text_item ; struct Text_def; struct Text_gob; +struct Text_register; struct Text_req; +struct Timing_req; struct Time_description; struct Voice; struct Voice_element; diff --git a/hdr/staff.hh b/hdr/staff.hh index 4c507c4b5b..74b7df1340 100644 --- a/hdr/staff.hh +++ b/hdr/staff.hh @@ -44,6 +44,9 @@ public: /// when does the last *musical* element finish? Moment last() const; +// /// extract midi info +// Midi_track* midi_track_p(); + /// remove unused cols void clean_cols() ; Staff(); diff --git a/input/coriolan-alto.ly b/input/coriolan-alto.ly index 683141814d..2037580f13 100644 --- a/input/coriolan-alto.ly +++ b/input/coriolan-alto.ly @@ -14,9 +14,9 @@ alto = music { $ \duration{ 8 } - \key {$bes es as$} + \key {bes es as} - } \clef "alto" + \clef "alto" % these are chords (i.e. non-divisi) % that-s why i-d rather type chords, % but how to type slurs? diff --git a/input/error.ly b/input/error.ly index 922f9ebefd..74924e9b25 100644 --- a/input/error.ly +++ b/input/error.ly @@ -1,7 +1,11 @@ +include "this-is-hopefully-a-nonexisting-file" + mwa = music { $ [ a8 a8 a8 a8 a8 ] % [ a8 ] % +% segfault +% { \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/martien.ly b/input/martien.ly index cf40cc9788..683f14d464 100644 --- a/input/martien.ly +++ b/input/martien.ly @@ -41,15 +41,15 @@ score { } commands { meter {2*4} - key $fis$ +% key $fis$ skip 56*2 - key $bes es as$ +% key $bes es as$ skip 8*2 meter {6*8} skip 48*8 meter {2*4} skip 16*2 - key $fis$ +% key $fis$ } paper { % unitspace 16mm @@ -57,4 +57,23 @@ score { 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/mlalt.ly b/input/mlalt.ly index 51f7de8742..cbe46e0f23 100644 --- a/input/mlalt.ly +++ b/input/mlalt.ly @@ -16,6 +16,7 @@ alto = music { \duration{16} \clef\alto \octave{} + \key{fis} %1 [ `b8. `a ] [ `g8 `b c ] | %2 @@ -112,31 +113,31 @@ alto = music { %44 [ `b8. c32 `b32 ] `a4 | %45 - \plet{ 4/6 } [ `g `a `g `a `g `a ] \plet{ 1/1 } \plet{ 4/6 } [ `g `b c d e fis ] \plet{ 1/1 } | + [ `g `a `g `a `g `a ]4/6 [ `g `b c d e fis ]4/6 | %46 - \plet{ 4/6 } [ g fis e d `b `g ] \plet{ 1/1 } [ `a8 `g8 ] | + [ g fis e d `b `g ]4/6 [ `a8 `g8 ] | %47 - \plet{ 4/6 } [ g fis e d c `b ] \plet{ 1/1 } \plet{ 4/6 } [ e d c `b `a `g ] \plet{ 1/1 } | + [ g fis e d c `b ]4/6 [ e d c `b `a `g ]4/6 | %48 - \plet{ 4/6 } [ d e d d `b `g ] \plet{ 1/1 } [ `a8 `g8 ] | + [ d e d d `b `g ]4/6 [ `a8 `g8 ] | %theme 2 \duration{8} %49 - \plet{ 2/3 } [ f e d ] \plet{ 1/1 } f4 | + [ f e d ]2/3 f4 | %50 - \plet{ 2/3 } [ e d c ] \plet{ 1/1 } e4 | + [ e d c ]2/3 e4 | %51 - \plet{ 2/3 } [ d g `g ] \plet{ 1/1 } \plet{ 2/3 } [ `g `a `b ] \plet{ 1/1 } | + [ d g `g ]2/3 [ `g `a `b ]2/3 | %52 d4 e4 | %53 - \plet{ 2/3 } [ f e d ] \plet{ 1/1 } f4 | + [ f e d ]2/3 f4 | %54 - \plet{ 2/3 } [ e d c ] \plet{ 1/1 } e4 | + [ e d c ]2/3 e4 | %55 - \plet{ 2/3 } [ d g `g ] \plet{ 1/1 } \plet{ 2/3 } [ `g `a `b ] \plet{ 1/1 } | + [ d g `g ]2/3 [ `g `a `b ]2/3 | %56 - `b4 c4 | % || \key\Es + `b4 c4 \key{bes es as} | % || \key\Es %57 [ `b d ] [ `g `b ] | %58 @@ -205,7 +206,7 @@ alto = music { `b2 | %88 \textstyle "italic" - c2_"dacapo" | + c2_"dacapo" \key{fis} | \textstyle "roman" %\scoreverb{\mulooseness=1} % \key\G || diff --git a/input/mlcello.ly b/input/mlcello.ly index cdc0b43348..558fc1fb15 100644 --- a/input/mlcello.ly +++ b/input/mlcello.ly @@ -15,6 +15,7 @@ cello = music { $ \clef"bass" \octave{`} \duration{4} + \key{fis} %%1 g `g | %%2 @@ -127,22 +128,22 @@ cello = music { %%49 \textstyle "italic" r4_"arco" - \plet{ 2/3 } [ `g `g `g ] \plet{ 1/1 } | + [ `g `g `g ]2/3 | \textstyle "roman" %%50 - r4 \plet{ 2/3 } [ c c c ] \plet{ 1/1 } | + r4 [ c c c ]2/3 | %%51 g2 | %%52 c2 | %%53 - r4 \plet{ 2/3 } [ `g `g `g ] \plet{ 1/1 } | + r4 [ `g `g `g ]2/3 | %%54 - r4 \plet{ 2/3 } [ c c c ] \plet{ 1/1 } | + r4 [ c c c ]2/3 | %%55 g2 | %%56 - `g4 `c4 | + `g4 `c4 \key{bes es as}| % \key\`es || %%57 g r g r | @@ -212,7 +213,7 @@ cello = music { d | %%88 \textstyle "italic" - d_"dacapo" + d_"dacapo" \key{fis} | \textstyle "roman" % \key\`g || $ diff --git a/input/mlvio1.ly b/input/mlvio1.ly index a6f2b049f4..b1d277bd31 100644 --- a/input/mlvio1.ly +++ b/input/mlvio1.ly @@ -13,9 +13,10 @@ % violin1 = music { $ -\clef "violin" + \clef "violin" \octave{} \duration{4} + \key{fis} %1 g [ b8. a16 ] | %2 @@ -123,22 +124,22 @@ violin1 = music { %theme 2 %49 \textstyle "italic" - r4_"arco" \plet{ 2/3 } [ b8 b b ] \plet{ 1/1 } + r4_"arco" [ b8 b b ]2/3 \textstyle "roman" | %50 - r4 \plet{ 2/3 } [ g g g ] \plet{ 1/1 } | + r4 [ g g g ]2/3 | %51 b2 | %52 'c2 | %53 - r4 \plet{ 2/3 } [ b b b ] \plet{ 1/1 } | + r4 [ b b b ]2/3 | %54 - r4 \plet{ 2/3 } [ g g g ] \plet{ 1/1 } | + r4 [ g g g ]2/3 | %55 b2 | %56 - g2 | + g2 \key{bes es as}| % \key\Es || %57 f r f r | @@ -150,11 +151,11 @@ violin1 = music { 'c r 'c4 | %61 \duration{16} - \plet{ 4/6 } [ as f d f as 'd ] \plet{ 1/1 } \plet{ 4/6 } [ as f d `as d f ] \plet{ 1/1 } | + [ as f d f as 'd ]4/6 [ as f d `as d f ]4/6 | %62 - \plet{ 4/6 } [ g es c `g c es ] \plet{ 1/1 } \plet{ 4/6 } [ g 'c 'es 'c g es ] \plet{ 1/1 } | + [ g es c `g c es ]4/6 [ g 'c 'es 'c g es ]4/6 | %63 - \plet{ 4/6 } [ g d g bes 'd 'g ] \plet{ 1/1 } \plet{ 4/6 } [ 'f 'd bes g f d ] \plet{ 1/1 } | + [ g d g bes 'd 'g ]4/6 [ 'f 'd bes g f d ]4/6 | %64 \duration{8} [ c g ] g4 | @@ -186,11 +187,11 @@ violin1 = music { 'c r 'c4 | %77 \duration{16} - \plet{ 4/6 } [ as f d f as 'd ] \plet{ 1/1 } \plet{ 4/6 } [ as f d `as d f ] \plet{ 1/1 } | + [ as f d f as 'd ]4/6 [ as f d `as d f ]4/6 | %78 - \plet{ 4/6 } [ g es c `g c es ] \plet{ 1/1 } \plet{ 4/6 } [ f 'c 'es 'c g es ] \plet{ 1/1 } | + [ g es c `g c es ]4/6 [ f 'c 'es 'c g es ]4/6 | %79 - \plet{ 4/6 } [ g d f b 'd 'g ] \plet{ 1/1 } \plet{ 4/6 } [ 'f 'd b g f d ] \plet{ 1/1 } | + [ g d f b 'd 'g ]4/6 [ 'f 'd b g f d ]4/6 | %80 [ c8 g8 ] g4 | %81 @@ -212,6 +213,7 @@ violin1 = music { \textstyle "italic" a_"dacapo" \textstyle "roman" + \key{fis} | % \key\G || $ } diff --git a/input/mlvio2.ly b/input/mlvio2.ly index ad6deb44a4..c3ed9bb999 100644 --- a/input/mlvio2.ly +++ b/input/mlvio2.ly @@ -15,6 +15,7 @@ violin2 = music { $ \clef "violin" \octave{} \duration{4} + \key{fis} %1 d2 | %2 @@ -92,7 +93,7 @@ violin2 = music { %35 [ g8 e e ] [ e8 g g ] | %36 - b4 fis4 | + b4 fis4 | %37 [ a8 a a ] [ a8 a a ] | %38 @@ -126,21 +127,21 @@ violin2 = music { \textstyle "italic" r4_"arco" \textstyle "roman" - \plet{ 2/3 } [ d8 d d ] \plet{ 1/1 } | + [ d8 d d ]2/3 | %50 - r4 \plet{ 2/3 } [ g8 g g ] \plet{ 1/1 } | + r4 [ g8 g g ]2/3 | %51 d2 | %52 c2 | %53 - r4 \plet{ 2/3 } [ d8 d d ] \plet{ 1/1 } | + r4 [ d8 d d ]2/3 | %54 - r4 \plet{ 2/3 } [ e e e ] \plet{ 1/1 } | + r4 [ e e e ]2/3 | %55 d2 | %56 - f4 e4 | + f4 e4 \key{bes es as}| % \key\Es || %57 d r `b r | @@ -182,9 +183,9 @@ violin2 = music { %74 `g r es r | %75 - g r g r | + g r g r | %76 - g r es4 | + g r es4 | %77 \duration{2} f | @@ -210,7 +211,7 @@ violin2 = music { % = g | %88 \textstyle "italic" - fis_"dacapo" | + fis_"dacapo" \key{fis}| \textstyle "roman" % \key\G || $ diff --git a/input/twinkle.ly b/input/twinkle.ly index 9b081c43fa..a356386099 100644 --- a/input/twinkle.ly +++ b/input/twinkle.ly @@ -15,6 +15,7 @@ melodie = music { c c | g g | a a | g g | f f | e e | d d8.( e16 | )c2 % :| + \bar ":|" $ } @@ -30,6 +31,7 @@ begeleiding = music { c 'c | 'e 'c | 'f 'c | 'e 'c | 'd b | 'c a | f g | c2 + \bar ":|" $ } @@ -150,8 +152,13 @@ score { } commands { meter {2 * 4} - skip 24*2 - bar "||" +% skip 24*2 +% bar "||" + } + staff { midi_track music { melodie } } + staff { midi_track music { begeleiding } } + midi { + tempo 4:120 } } diff --git a/src/midicolumn.cc b/src/midicolumn.cc new file mode 100644 index 0000000000..13abbd03d5 --- /dev/null +++ b/src/midicolumn.cc @@ -0,0 +1,44 @@ +#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 new file mode 100644 index 0000000000..56ee59e0b7 --- /dev/null +++ b/src/mididef.cc @@ -0,0 +1,64 @@ +// +// mididef.cc -- implement midi output +// +// source file of the LilyPond music typesetter +// +// (c) 1997 Jan Nieuwenhuizen + +#include +#include "misc.hh" +#include "mididef.hh" +#include "debug.hh" + +// classes, alphasorted +// statics +// constructors +// destructor +// routines, alphasorted + +Mididef::Mididef() +{ + set_tempo( Moment( 1, 4 ), 60 ); + outfile_str_ = "lelie.midi"; +} + +Mididef::Mididef( Mididef const& midi_c_r ) +{ + whole_seconds_f_ = midi_c_r.whole_seconds_f_; + outfile_str_ = midi_c_r.outfile_str_; +} + +Mididef::~Mididef() +{ +} + +Real +Mididef::duration_to_seconds_f( Moment moment ) +{ + if (!moment) + return 0; + + return whole_seconds_f_ * moment; +} + +int +Mididef::get_tempo_i( Moment moment ) +{ + return Moment( whole_seconds_f_ ) * Moment( 60 ) * moment; +} + +void +Mididef::print() const +{ +#ifndef NPRINT + mtor << "Midi {4/min: " << Real( 60 ) / ( whole_seconds_f_ * 4 ); + mtor << "out: " << outfile_str_; + mtor << "}\n"; +#endif +} + +void +Mididef::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 new file mode 100644 index 0000000000..e7d5ccc92f --- /dev/null +++ b/src/midiitem.cc @@ -0,0 +1,178 @@ +// +// midiitem.cc +// +// source file of the LilyPond music typesetter +// +// (c) 1997 Jan Nieuwenhuizen + +#include +#include "plist.hh" +#include "pcol.hh" +#include "debug.hh" +#include "misc.hh" +#include "request.hh" +#include "musicalrequest.hh" +#include "voice.hh" +#include "midiitem.hh" +#include "midistream.hh" + +Midi_chunk::Midi_chunk() +{ +} + +void +Midi_chunk::add( String 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; +} + +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; +} + +Midi_duration::Midi_duration( Real seconds_f ) +{ + seconds_f_ = seconds_f; +} + +String +Midi_duration::str() +{ + return String( ""; +} + +Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i ) +{ + String 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 tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' ); + str += StringConversion::hex2bin_str( tempo_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; +} + +void +Midi_item::output_midi( Midi_stream& midi_stream_r ) +{ + 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; +} + +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( "" ); +} + +Midi_track::Midi_track( int number_i ) +{ +// 4D 54 72 6B MTrk +// 00 00 00 3B chunk length (59) +// 00 FF 58 04 04 02 18 08 time signature +// 00 FF 51 03 07 A1 20 tempo + +// FF 59 02 sf mi Key Signature +// sf = -7: 7 flats +// sf = -1: 1 flat +// sf = 0: key of C +// sf = 1: 1 sharp +// sf = 7: 7 sharps +// mi = 0: major key +// mi = 1: minor key + + number_i_ = number_i; + + 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" +// 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 ); + + 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 ); +} + +void +Midi_track::add( int delta_time_i, String event_str ) +{ + 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? +// 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() ); +} + diff --git a/src/midiscorewalker.cc b/src/midiscorewalker.cc new file mode 100644 index 0000000000..cfe92e7913 --- /dev/null +++ b/src/midiscorewalker.cc @@ -0,0 +1,31 @@ +/* + 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 new file mode 100644 index 0000000000..c63ac9688b --- /dev/null +++ b/src/midistaff.cc @@ -0,0 +1,50 @@ +#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/midistream.cc b/src/midistream.cc new file mode 100644 index 0000000000..73fe2e4733 --- /dev/null +++ b/src/midistream.cc @@ -0,0 +1,87 @@ +// +// midistream.cc +// +// source file of the LilyPond music typesetter +// +// (c) 1997 Jan Nieuwenhuizen + +#include +#include +#include "main.hh" +#include "misc.hh" +#include "midiitem.hh" +#include "midistream.hh" +#include "debug.hh" + +Midi_stream::Midi_stream( String filename_str, int tracks_i, int tempo_i ) +{ + filename_str_ = filename_str; + tracks_i_ = tracks_i; + tempo_i_ = tempo_i; + open(); + header(); +} + +Midi_stream::~Midi_stream() +{ + delete os_p_; +} + +Midi_stream& +Midi_stream::operator <<( String str ) +{ + // still debugging... + if ( check_debug ) + str = StringConversion::bin2hex_str( str ); + // string now 1.0.26-2 handles binary streaming + *os_p_ << str; + return *this; +} + +Midi_stream& +Midi_stream::operator <<( Midi_item& mitem_r ) +{ + mitem_r.output_midi( *this ); + if ( check_debug ) + *os_p_ << "\n"; + return *this; +} + +Midi_stream& +Midi_stream::operator <<( int i ) +{ + // output binary string ourselves + *this << Midi_item::int2varlength_str( i ); + return *this; +} + +void +Midi_stream::header() +{ +// *os_p_ << "% Creator: " << get_version(); +// *os_p_ << "% Automatically generated, at "; +// time_t t(time(0)); +// *os_p_ << ctime(&t); + +// 4D 54 68 64 MThd +// String str = "MThd"; +// 00 00 00 06 chunk length +// 00 01 format 1 +// 00 01 one track +// 00 60 96 per quarter-note + +// char const ch_c_l = "0000" "0006" "0001" "0001" "0060"; +// str += StringConversion::hex2bin_str( ch_c_l ); +// *os_p_ << str; + +// *this << Midi_header( 1, 1, tempo_i_ ); + *this << Midi_header( 1, tracks_i_, tempo_i_ ); +} + +void +Midi_stream::open() +{ + os_p_ = new ofstream( filename_str_ ); + if ( !*os_p_ ) + error ("can't open `" + filename_str_ + "\'" ); +} diff --git a/src/midiwalker.cc b/src/midiwalker.cc new file mode 100644 index 0000000000..5072fb6320 --- /dev/null +++ b/src/midiwalker.cc @@ -0,0 +1,43 @@ +/* + midiwalker.cc -- implement Midi_walker + + source file of the LilyPond music typesetter + + (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 "midiwalker.hh" +#include "debug.hh" +#include "midiitem.hh" +#include "midistream.hh" + +Midi_walker::Midi_walker( Midi_staff* mstaff_l ) + : Staff_walker( mstaff_l, 0 ) +{ +} + +Midi_column* +Midi_walker::mcol_l() +{ + return (Midi_column*) *(*this); +} + +Midi_staff* +Midi_walker::mstaff_l() +{ + return (Midi_staff*)staff_l_; +} + +void +Midi_walker::process_requests() +{ + allow_break(); +} + diff --git a/src/mylexer.cc b/src/mylexer.cc index 7af820ae44..ea86b3094b 100644 --- a/src/mylexer.cc +++ b/src/mylexer.cc @@ -26,6 +26,7 @@ static Keyword_ent the_key_tab[]={ "key", KEY, "meter", METER, + "midi", MIDI, "mm", MM_T, "multivoice", MULTIVOICE, "octave", OCTAVECOMMAND, @@ -43,6 +44,7 @@ static Keyword_ent the_key_tab[]={ "table", TABLE, "symboltables", SYMBOLTABLES, "notenames", NOTENAMES, + "tempo", TEMPO, "texid", TEXID, "textstyle", TEXTSTYLE, "unitspace", UNITSPACE, @@ -59,10 +61,12 @@ My_flex_lexer::ret_notename(int *p, String text, int octave_mod) { text.lower(); char const* ch_c_l = here_ch_c_l(); - ch_c_l--; - while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) ) + if ( ch_c_l ) { ch_c_l--; - ch_c_l++; + while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) ) + ch_c_l--; + ch_c_l++; + } lookup_notename(p[0], p[1], text); p[2] = octave_mod; @@ -70,7 +74,7 @@ My_flex_lexer::ret_notename(int *p, String text, int octave_mod) if (p[0] < 0) { errorlevel_i_ |= 1; - warning( String( "notename does not exist: " ) + YYText(), ch_c_l ); + error( String( "notename does not exist: " ) + YYText(), ch_c_l ); p[0] = p[1] = 0; } return NOTENAME; @@ -81,7 +85,6 @@ My_flex_lexer::My_flex_lexer() keytable = new Keyword_table(the_key_tab); the_id_tab = new Assoc; defaulttab = 0; - data_ch_c_l_ = 0; errorlevel_i_ = 0; } @@ -103,7 +106,7 @@ My_flex_lexer::lookup_identifier(String s) char const* My_flex_lexer::here_ch_c_l() { - return data_ch_c_l_ ? data_ch_c_l_ + yyin->tellg() : 0; + return include_stack.top()->sourcefile_l_->ch_c_l() + yyin->tellg(); } void @@ -144,7 +147,7 @@ My_flex_lexer::LexerError(const char *s) ch_c_l++; } errorlevel_i_ |= 1; - warning( s, ch_c_l ); + error( s, ch_c_l ); } } @@ -161,10 +164,6 @@ My_flex_lexer::new_input(String s) Input_file *newin = new Input_file(s); include_stack.push(newin); switch_streams(newin->is); - if ( newin->sourcefile_l_ ) - data_ch_c_l_ = newin->sourcefile_l_->ch_c_l(); - else - data_ch_c_l_ = 0; yylineno = 1; } diff --git a/src/score.cc b/src/score.cc index 3084f90c90..368188bbc1 100644 --- a/src/score.cc +++ b/src/score.cc @@ -17,13 +17,20 @@ #include "source.hh" #include "sourcefile.hh" #include "scorewalker.hh" +#include "mididef.hh" +#include "midiitem.hh" +#include "midistream.hh" +#include "midicolumn.hh" +#include "midistaff.hh" +#include "midiwalker.hh" void Score::setup_music() { *mlog << "\nSetting up music ..." << flush; if (last() == Moment(0)) { - warning("Need to have music in a score.", defined_ch_c_l_); + errorlevel_i_ |= 1; + error("Need to have music in a score.", defined_ch_c_l_); } pscore_p_ = new PScore(paper_p_); @@ -45,13 +52,14 @@ Score::process_music() *mlog << "Processing music ..." << flush; for (Score_walker w(this); w.ok(); w++) { w.process(); - } + } } void Score::process() { setup_music(); + process_music(); // do this after processing, staffs first have to generate PCols. @@ -158,6 +166,13 @@ Score::last() const return l; } +void +Score::set(Mididef* midi_p) +{ + delete midi_p_; + midi_p_ = midi_p; +} + void Score::OK() const { @@ -197,6 +212,7 @@ Score::Score(Paperdef*paper_p) { pscore_p_=0; paper_p_ = paper_p; + midi_p_ = 0; errorlevel_i_ = 0; defined_ch_c_l_ = 0; } @@ -205,6 +221,7 @@ Score::~Score() { delete pscore_p_; delete paper_p_; + delete midi_p_; } void @@ -230,7 +247,30 @@ Score::output(String s) pscore_p_->output(the_output); } +void +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++ ); + } +} void Score::add(Staff*s) diff --git a/src/scores.cc b/src/scores.cc index 59b6f6670d..2788fe062a 100644 --- a/src/scores.cc +++ b/src/scores.cc @@ -17,6 +17,7 @@ do_scores() s_p->print (); s_p->process(); s_p->output(outfn); + s_p->midi(); delete s_p; } score_array_global.set_size(0); diff --git a/src/staff.cc b/src/staff.cc index a69f625aed..c93ca997cc 100644 --- a/src/staff.cc +++ b/src/staff.cc @@ -8,6 +8,7 @@ #include "debug.hh" #include "musicalrequest.hh" #include "commandrequest.hh" // todo +#include "midistream.hh" void Staff::add(PointerList const &l) @@ -39,6 +40,13 @@ 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) { @@ -123,7 +131,6 @@ Staff::last() const return l; } - void Staff::print() const {