From: Jan Nieuwenhuizen Date: Wed, 20 Aug 1997 14:32:20 +0000 (+0200) Subject: patch::: 0.1.9.jcn2: pats X-Git-Tag: release/0.1.10~2 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=388e4a0e9c5f5d470357709b2ec205b1a1c7351e;p=lilypond.git patch::: 0.1.9.jcn2: pats pl 9.jcn2 - redo of mi2mu frontend (midi-parser) - bf: String_convert::bin2_i; added bin2_u - bf's: Binary_source_file - bf: constr. Tempo/Timing_req --- diff --git a/NEWS b/NEWS index c0a1a5bda0..741694ca8d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +pl 9.jcn2 + - redo of mi2mu frontend (midi-parser) + - bf: String_convert::bin2_i; added bin2_u + - bf's: Binary_source_file + - bf: constr. Tempo/Timing_req + pl 9 - declare rhythic_request - preliminary support for real \mudelaheaders diff --git a/VERSION b/VERSION index ba28d0f309..2f45472edd 100644 --- a/VERSION +++ b/VERSION @@ -3,4 +3,4 @@ TOPLEVEL_MINOR_VERSION = 1 TOPLEVEL_PATCH_LEVEL = 9 # use to send patches, always empty for released version: -TOPLEVEL_MY_PATCH_LEVEL = .jcn1 +TOPLEVEL_MY_PATCH_LEVEL = .jcn2 diff --git a/bin/genheader.in b/bin/genheader.in index 9b6bb4d6cb..8643a3794f 100644 --- a/bin/genheader.in +++ b/bin/genheader.in @@ -6,7 +6,7 @@ my $fn; sub do_init { - $MAILADRESS=$ENV{MAILADRESS}; + $MAILADDRESS=$ENV{MAILADDRESS}; @pw=(getpwuid($<)); $username=$pw[6]; @@ -34,7 +34,7 @@ sub source file of $PROJECT - (c) 1997 $username <$MAILADRESS> + (c) 1997 $username <$MAILADDRESS> */\n"; print $headstr; } diff --git a/flower/include/string-convert.hh b/flower/include/string-convert.hh index 63785ac28d..1d3f5d0300 100644 --- a/flower/include/string-convert.hh +++ b/flower/include/string-convert.hh @@ -21,7 +21,8 @@ public: static String bin2dec_str (String bin_str); static String bin2hex_str (String bin_str); static String dec2bin_str (String str); - static int bin2_i (String str); + static int bin2_i (String bin_str); + static unsigned bin2_u (String bin_str); static String char_str (char c, int n); static int dec2_i (String dec_str); static double dec2_f (String dec_str); diff --git a/flower/string-convert.cc b/flower/string-convert.cc index c105169cee..5acdb4c88f 100644 --- a/flower/string-convert.cc +++ b/flower/string-convert.cc @@ -40,15 +40,21 @@ String_convert::bin2hex_str (String bin_str) int String_convert::bin2_i (String bin_str) { - assert (bin_str.length_i() <= 4); + return bin2_u (bin_str); +} + +unsigned +String_convert::bin2_u (String bin_str) +{ + assert (bin_str.length_i() <= (int)sizeof(unsigned)); - int result_i = 0; + unsigned result_u = 0; for ( int i = 0; i < bin_str.length_i(); i++) { - result_i <<= 8; - result_i += (Byte)bin_str[ i ]; + result_u <<= 8; + result_u += (Byte)bin_str[ i ]; } - return result_i; + return result_u; } // breendet imp from String diff --git a/lib/binary-source-file.cc b/lib/binary-source-file.cc index 666012f0c6..8c4aac4474 100644 --- a/lib/binary-source-file.cc +++ b/lib/binary-source-file.cc @@ -27,7 +27,7 @@ Binary_source_file::~Binary_source_file() } String -Binary_source_file::error_str( char const* pos_ch_c_l ) +Binary_source_file::error_str( char const* pos_ch_c_l ) const { assert( this ); if ( !in_b( pos_ch_c_l ) ) @@ -53,7 +53,7 @@ Binary_source_file::error_str( char const* pos_ch_c_l ) } int -Binary_source_file::line_i( char const* pos_ch_c_l ) +Binary_source_file::line_i( char const* pos_ch_c_l ) const { if ( !in_b( pos_ch_c_l ) ) return 0; diff --git a/lib/include/binary-source-file.hh b/lib/include/binary-source-file.hh index bc8279f6ab..63127ea9ad 100644 --- a/lib/include/binary-source-file.hh +++ b/lib/include/binary-source-file.hh @@ -13,8 +13,8 @@ public: Binary_source_file( String& filename_str ); virtual ~Binary_source_file(); - virtual String error_str( char const* pos_ch_c_l ); - virtual int line_i( char const* pos_ch_c_l ); + virtual String error_str( char const* pos_ch_c_l ) const; + virtual int line_i( char const* pos_ch_c_l ) const; }; #endif // BINARY_SOURCE_FILE_HH // diff --git a/lib/include/source.hh b/lib/include/source.hh index 1d199671ff..fc0ca2728d 100644 --- a/lib/include/source.hh +++ b/lib/include/source.hh @@ -12,12 +12,13 @@ class Sources { public: + Sources(); + Source_file * get_file_l( String &filename ); Source_file* sourcefile_l( char const* ch_C ); void set_path(File_path*p_C); - Sources(); void set_binary(bool); - ~Sources(); + private: const File_path * path_C_; void add( Source_file* sourcefile_p ); diff --git a/lib/source-file.cc b/lib/source-file.cc index a67b466300..4ac7017f05 100644 --- a/lib/source-file.cc +++ b/lib/source-file.cc @@ -57,12 +57,14 @@ Source_file::name_str()const { return name_str_; } + Source_file::~Source_file() { delete istream_p_; istream_p_ = 0; delete storage_p_; } + String Source_file::error_str( char const* pos_ch_C )const { diff --git a/lib/source.cc b/lib/source.cc index e60041553c..dd1c5f27d6 100644 --- a/lib/source.cc +++ b/lib/source.cc @@ -17,6 +17,18 @@ #include "source.hh" #include "path.hh" +Sources::Sources() +{ + path_C_= 0; + binary_b_ = false; +} + +void +Sources::set_binary(bool bo) +{ + binary_b_ = bo; +} + void Sources::set_path(File_path *f_C) { @@ -47,12 +59,6 @@ Sources::get_file_l(String &file_str ) //UGH return f_p; } -Sources::Sources() -{ - path_C_= 0; - binary_b_ = false; -} - void Sources::add( Source_file* sourcefile_p ) { @@ -74,5 +80,3 @@ Sources::sourcefile_l( char const* ch_C ) return 0; } -Sources::~Sources() -{} diff --git a/lily/include/command-request.hh b/lily/include/command-request.hh index 1a78f14d75..f5adca4428 100644 --- a/lily/include/command-request.hh +++ b/lily/include/command-request.hh @@ -53,7 +53,6 @@ class Timing_req : public Command_req { public: REQUESTMETHODS(Timing_req, timing); virtual Tempo_req * tempo(){return 0; } - Tempo_req(); }; diff --git a/lily/score.cc b/lily/score.cc index fd11b56542..f421259e3f 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -28,8 +28,9 @@ extern String default_out_fn; Score::Score() { - header_p_ =0; - pscore_p_=0; + header_p_ = 0; + music_p_ = 0; + pscore_p_ = 0; audio_score_p_ = 0; paper_p_ = 0; midi_p_ = 0; @@ -42,7 +43,7 @@ Score::Score (Score const &s) music_p_ = s.music_p_->clone(); midi_p_ = new Midi_def (*s.midi_p_); paper_p_ = new Paper_def (*s.paper_p_); - header_p_ = new Header(*s.header_p_); + header_p_ = new Header (*s.header_p_); } Score::~Score() diff --git a/mi2mu/Makefile b/mi2mu/Makefile index 7100902c8f..85bcfed18e 100644 --- a/mi2mu/Makefile +++ b/mi2mu/Makefile @@ -75,7 +75,8 @@ DEPFILES = $(wildcard $(depdir)/*.dep) -include /dev/null $(DEPFILES) # localclean: - rm -f $(outdir)/{midi-parser,midi-lexer}.* +# obsoliet +# rm -f $(outdir)/{midi-parser,midi-lexer}.* localinstall: installexe diff --git a/mi2mu/TODO b/mi2mu/TODO index e9cb89c143..e522176955 100644 --- a/mi2mu/TODO +++ b/mi2mu/TODO @@ -6,16 +6,6 @@ grep for TODO and ugh/ugr IMPORTANT - * fix parser: either - - parse into midi-items (merge with lily/midi-*) and pass - these nealy up, same for track and score. look at all - tracks a time (vertically through score), creating columns - and mudela items in time-order (no searching for columns). - or - - junk lex/yacc altogether, parse on byte level, straight - from memore, vertically through score. there might be no - need for midi-items, here. - * get rid of (last few?) midi-specifics in mudela-* * find / remove trend (tempo) of mudela columns @@ -64,16 +54,8 @@ PROJECTS BUGS - * mi2mu nonexist.midi ? - * output of 0 duration c'0 - * no output on certain midis - - * silly progress indicator upon mudela output - - * check for illegal track names, e.g. "Piano________ = \melodic" - * array memleaks(?): use Link_array / create Pointer_array? * fix "#undef MEVENT_LIST" source tree: Array diff --git a/mi2mu/VERSION b/mi2mu/VERSION index 22b9eff149..bbbdde49e2 100644 --- a/mi2mu/VERSION +++ b/mi2mu/VERSION @@ -1,6 +1,6 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 -PATCH_LEVEL = 19 +PATCH_LEVEL = 20 # use to send patches, always empty for released version: MY_PATCH_LEVEL = # diff --git a/mi2mu/include/mi2mu-proto.hh b/mi2mu/include/mi2mu-proto.hh index 5aa6579ae3..da4d89ba54 100644 --- a/mi2mu/include/mi2mu-proto.hh +++ b/mi2mu/include/mi2mu-proto.hh @@ -10,7 +10,10 @@ #ifndef MI2MU_PROTO_HH #define MI2MU_PROTO_HH - +class Midi_parser; +struct Midi_parser_info; +class Midi_score_parser; +class Midi_track_parser; class Mudela_stream; class Mudela_item; class Mudela_key; @@ -21,8 +24,6 @@ class Mudela_text; class Mudela_score; class Mudela_staff; class Mudela_voice; -class My_midi_lexer; -class My_midi_parser; class Mudela_column; #endif // MI2MU_PROTO_HH diff --git a/mi2mu/include/midi-parser.hh b/mi2mu/include/midi-parser.hh new file mode 100644 index 0000000000..55c75a5a77 --- /dev/null +++ b/mi2mu/include/midi-parser.hh @@ -0,0 +1,110 @@ +/* + midi-parser.hh -- declare Midi_parser + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_PARSER_HH +#define MIDI_PARSER_HH + +// must, gcc 2.7.2{,.1} hits ico on midi-track-parser.cc:134 (@Midi_note) +#define INLINES + +#ifdef INLINES + +#define next_byte() (inline_next_byte (__FUNCTION__)) +#define peek_byte() (inline_peek_byte (__FUNCTION__)) +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#else + +#define next_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_++\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define peek_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#endif + +#include "proto.hh" +#include "moment.hh" + +struct Midi_parser_info +{ + Midi_parser_info(); + int division_1_i_; + int format_i_; + int tracks_i_; + int errorlevel_i_; + Byte const* byte_L_; + Byte const* end_byte_L_; + Source_file* source_l_; + Moment bar_mom_; +}; + +#include "string.hh" + +class Midi_parser +{ +public: + Midi_parser (); + + Midi_parser_info* info_l_; + +protected: +// Byte const* inline_forward_byte_L (int n) + Byte const* inline_forward_byte_L (char const* fun, int n) + { + if (info_l_->byte_L_ + n < info_l_->end_byte_L_ ) + { + Byte const* p = info_l_->byte_L_; + info_l_->byte_L_ += n; + return p; + } +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } + +#ifdef INLINES +// Byte inline_next_byte () + Byte inline_next_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_++; +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } + +// Byte inline_peek_byte () + Byte inline_peek_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_; +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } +#endif + + int get_i (int); + String get_str (int); + unsigned get_u (int); + int get_var_i (); + int exit (String); + void error (String); + String message (String); + void warning (String); +}; + +#endif // MIDI_PARSER_HH diff --git a/mi2mu/include/midi-score-parser.hh b/mi2mu/include/midi-score-parser.hh new file mode 100644 index 0000000000..f9c8b646d8 --- /dev/null +++ b/mi2mu/include/midi-score-parser.hh @@ -0,0 +1,33 @@ +/* + midi-score-parser.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_SCORE_PARSER_HH +#define MIDI_SCORE_PARSER_HH + +#include "midi-parser.hh" +#include "proto.hh" +#include "mi2mu-proto.hh" +#include "parray.hh" + +class Midi_score_parser : public Midi_parser +{ +public: + Mudela_score* parse (String filename_str, Sources*); + +private: + void open (String filename_str, Sources*); + + void parse_header (); + // why the #*&$#{%) has Link_array another behaviour than Link_list?? + // int find_earliest_i (Link_array& tracks); + int find_earliest_i (Link_array& tracks); + Mudela_score* parse_score (); +}; + +#endif // MIDI_SCORE_PARSER_HH diff --git a/mi2mu/include/midi-track-parser.hh b/mi2mu/include/midi-track-parser.hh new file mode 100644 index 0000000000..021197c737 --- /dev/null +++ b/mi2mu/include/midi-track-parser.hh @@ -0,0 +1,44 @@ +/* + midi-track-parser.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_TRACK_PARSER_HH +#define MIDI_TRACK_PARSER_HH + +#include "proto.hh" +#include "plist.hh" +#include "moment.hh" +#include "mi2mu-proto.hh" +#include "midi-parser.hh" + +class Midi_track_parser : public Midi_parser +{ +public: + + Midi_track_parser (Midi_parser_info* info_l); + ~Midi_track_parser (); + + Moment at_mom (); + Mudela_staff* parse (Mudela_column* col_l); + +private: + bool eot (); + void note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ); + void note_end_all (Mudela_column* col_l) ; + void parse_delta_time (); + Mudela_item* parse_event (Mudela_column* col_l); + void parse_header (); + + Moment at_mom_; + Byte running_byte_; + Link_list open_note_l_list_; + Mudela_staff* mudela_staff_p_; + Midi_parser_info* track_info_p_; +}; + +#endif // MIDI_TRACK_PARSER_HH diff --git a/mi2mu/include/mudela-score.hh b/mi2mu/include/mudela-score.hh index 6d752fe1d6..d1102f0808 100644 --- a/mi2mu/include/mudela-score.hh +++ b/mi2mu/include/mudela-score.hh @@ -20,7 +20,8 @@ public: void add_item (Mudela_item* mudela_item_p); void add_staff (Mudela_staff* mudela_staff_p); - Mudela_column* mudela_column_l (Moment mom); + Mudela_column* find_column_l (Moment mom); + Mudela_column* get_column_l (Moment mom); void output (String filename_str); void process(); @@ -36,10 +37,9 @@ private: void quantify_durations(); void settle_columns(); - Pointer_list mudela_column_p_list_; Pointer_list mudela_staff_p_list_; -// Link_array column_l_array_; - // huh? + // wants Pointer_array! +// Pointer_list mudela_column_p_list_; Link_array column_l_array_; // ugh, ugh, ugh diff --git a/mi2mu/include/my-midi-lexer.hh b/mi2mu/include/my-midi-lexer.hh index 7b8b809aa7..e69de29bb2 100644 --- a/mi2mu/include/my-midi-lexer.hh +++ b/mi2mu/include/my-midi-lexer.hh @@ -1,41 +0,0 @@ -// -// my-midi-lexer.hh -- declare My_midi_lexer -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MY_MIDI_LEXER_HH -#define MY_MIDI_LEXER_HH - -#include -#include "proto.hh" -#include "varray.hh" -#include "string.hh" - -int yylex(); -void yyerror(const char *s); - -/// (midi_lexer) -class My_midi_lexer : yyFlexLexer { -public: - My_midi_lexer (String& filename_str, Sources*); - ~My_midi_lexer(); - - int close_i(); - void error (char const* sz_l); - char const* here_ch_C(); - static int varint2_i (String str); - int yylex(); - Source_file* source_file_l_ ; - -private: - int char_count_; - int running_status_i_; - -public: // ugh - int errorlevel_i_; -}; - -extern My_midi_lexer* midi_lexer_l_g; - -#endif // MY_MIDI_LEXER_HH - diff --git a/mi2mu/include/my-midi-parser.hh b/mi2mu/include/my-midi-parser.hh index bcebb14ff6..e69de29bb2 100644 --- a/mi2mu/include/my-midi-parser.hh +++ b/mi2mu/include/my-midi-parser.hh @@ -1,75 +0,0 @@ -// -// my-midi-parser.hh -- declare My_midi_parser -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MY_MIDI_PARSER_HH -#define MY_MIDI_PARSER_HH - -#include "mi2mu-proto.hh" -#include "proto.hh" -#include "plist.hh" -#include "string.hh" -#include "moment.hh" - -#include "string.hh" -#include "moment.hh" - -int yyparse(); - -/** - An interface to the YACC midi parser. - (midi_parser) - */ -class My_midi_parser { -public: - My_midi_parser (String filename_str,Sources *); - ~My_midi_parser(); - - void add_score (Mudela_score* mudela_score_p); - void error (char const* sz_l); - int parse(); - void forward (int i); - Moment at_mom(); - void note_begin (int channel_i, int pitch_i, int dyn_i); - void note_end (int channel_i, int pitch_i, int aftertouch_i); - void note_end_all(); - - void reset(); - void set_division_4 (int division_4_i); - void set_key (int accidentals_i, int minor_i); - void set_meter (int num_i, int den_i, int clocks_i, int count_32_i); - void set_tempo (int useconds_per_4_i); - - int bar_i_; - - // ugh - int track_i_; - String filename_str_; - String copyright_str_; - String instrument_str_; - String track_name_str_; - - // ugh - Mudela_key* mudela_key_p_; - Mudela_meter* mudela_meter_p_; - Mudela_tempo* mudela_tempo_p_; - - Mudela_staff* mudela_staff_l_; - Mudela_score* mudela_score_p_; - Mudela_column* mudela_column_l_; - -private: - Link_list open_mudela_note_l_list_; - - int division_1_i_; - - char const* defined_ch_C_; - int fatal_error_i_; - My_midi_lexer* midi_lexer_p_; -}; - -extern My_midi_parser* midi_parser_l_g; - -#endif // MY_MIDI_PARSER_HH - diff --git a/mi2mu/main.cc b/mi2mu/main.cc index c138322590..25dfab0694 100644 --- a/mi2mu/main.cc +++ b/mi2mu/main.cc @@ -4,6 +4,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "string-convert.hh" #include "lgetopt.hh" #include "path.hh" @@ -11,12 +12,17 @@ #include "source.hh" #include "mi2mu-global.hh" -#include "my-midi-parser.hh" +#include "midi-score-parser.hh" #include "mudela-score.hh" #include "version.hh" +// ugh +String filename_str_g; + +// ugh +Mudela_score* mudela_score_l_g = 0; + Sources source; -Sources* source_l_g = &source; static File_path path; @@ -102,8 +108,8 @@ main (int argc_i, char* argv_sz_a[]) Getopt_long getopt_long (argc_i, argv_sz_a, long_option_init_a); String output_str; - while (Long_option_init const* long_option_init_p = getopt_long()) - switch (long_option_init_p->shortname) + while (Long_option_init const* long_option_init_p = getopt_long()) + switch (long_option_init_p->shortname) { case 'b': Duration_convert::no_quantify_b_s = true; @@ -136,7 +142,7 @@ main (int argc_i, char* argv_sz_a[]) case 's': { int i = String_convert::dec2_i (getopt_long.optional_argument_ch_C_); - if (!i) + if (!i) { identify(); usage(); @@ -166,32 +172,31 @@ main (int argc_i, char* argv_sz_a[]) identify(); path.add (""); - source_l_g->set_path (&path); + source.set_binary (true); + source.set_path (&path); char const* arg_sz = 0; - while ( (arg_sz = getopt_long.get_next_arg())) + while ( (arg_sz = getopt_long.get_next_arg ())) { - My_midi_parser midi_parser (arg_sz, & source); - midi_parser_l_g = &midi_parser; + filename_str_g = arg_sz; + Midi_score_parser midi_parser; + Mudela_score* score_p = midi_parser.parse (arg_sz, &source); + + if (!score_p) + return 1; - int error_i = midi_parser.parse(); - if (error_i) - return error_i; + mudela_score_l_g = score_p; + score_p->process(); - if (!output_str.length_i()) + if (!output_str.length_i ()) { String d, dir, base, ext; - split_path (arg_sz, d, dir, base, ext); - output_str = base + ext + ".ly"; } - assert (midi_parser.mudela_score_p_); - midi_parser.mudela_score_p_->process(); - midi_parser.mudela_score_p_->output (output_str); - - midi_parser_l_g = 0; + score_p->output (output_str); + delete score_p; } return 0; } diff --git a/mi2mu/midi-lexer.l b/mi2mu/midi-lexer.l index 485312b974..e69de29bb2 100644 --- a/mi2mu/midi-lexer.l +++ b/mi2mu/midi-lexer.l @@ -1,522 +0,0 @@ -%{//-*-Fundamental-*- -// midi-lexer.l - -/* - yes, i know that midi is not really a (n evolving?) language, - and that using lex/yacc to parse midi is overkill, as well as - a grand example of misuse and asking for performance loss. - - it is, however, quite robust, simple, and very easy to extend - incrementally. - */ - -/* - backup rules - - after making a change to the lexer rules, run - flex -b - and make sure that - lex.backup - contains no backup states, but only the reminder - Compressed tables always back up. - (don-t forget to rm lex.yy.cc :-) - */ - -#include "string-convert.hh" -#include "mi2mu-global.hh" -#include "mi2mu-proto.hh" -#include "my-midi-lexer.hh" -#include "midi-parser.hh" - -#define YY_USER_ACTION char_count_ += YYLeng(); // ugh - -%} - -%option c++ -%option noyywrap -%option nodefault -%option debug -%option yyclass="My_midi_lexer" -%option stack - -%x data -%x event -%x i8 -%x u8 -%x int16 -%x int32 -%x meta_event -%x track - -U8 [\x00-\xff] -I8 {U8} -INT16 {U8}{U8} -BACKUP_INT16_0 {U8} -INT32 {INT16}{INT16} -BACKUP_INT32_0 {U8} -BACKUP_INT32_1 {U8}{U8} -BACKUP_INT32_2 {INT16}{U8} -INT7_8UNSET [\x00-\x7f] -INT7_8SET [\x80-\xff] -VARINT {INT7_8SET}{0,3}{INT7_8UNSET} -BACKUP_VARINT_0 {INT7_8SET} -BACKUP_VARINT_1 {INT7_8SET}{INT7_8SET} -BACKUP_VARINT_2 {INT7_8SET}{INT7_8SET}{INT7_8SET} - -HEADER MThd -TRACK MTrk -BACKUP_TOP_0 MT -BACKUP_TOP_1 MTh -BACKUP_TOP_2 MTr - -RUNNING_STATUS [\x00-\x5f] -DATA_ENTRY [\x60-\x79] -ALL_NOTES_OFF [\x7a-\x7f] -NOTE_OFF [\x80-\x8f] -NOTE_ON [\x90-\x9f] -POLYPHONIC_AFTERTOUCH [\xa0-\xaf] -CONTROLMODE_CHANGE [\xb0-\xbf] -PROGRAM_CHANGE [\xc0-\xcf] -CHANNEL_AFTERTOUCH [\xd0-\xdf] -PITCHWHEEL_RANGE [\xe0-\xef] - -SYSEX_EVENT1 [\xf0] -SYSEX_EVENT2 [\xf7] - -META_EVENT [\xff] - -SEQUENCE [\x00][\x02] -YYTEXT [\x01] -YYCOPYRIGHT [\x02] -YYTRACK_NAME [\x03] -YYINSTRUMENT_NAME [\x04] -YYLYRIC [\x05] -YYMARKER [\x06] -YYCUE_POINT [\x07] - -END_OF_TRACK [\x2f][\x00] -TEMPO [\x51][\x03] -SMPTE_OFFSET [\x54][\x05] -TIME [\x58][\x04] -KEY [\x59][\x02] -SSME [\0x7f][\x03] - -%% - -{HEADER} { - LOGOUT(DEBUG_ver) << "lex: header" << endl; - yy_push_state(int16); - yy_push_state(int16); - yy_push_state(int16); - yy_push_state(int32); - return HEADER; -} - -{TRACK} { - LOGOUT(DEBUG_ver) << "lex: track" << endl; - yy_push_state(track); - yy_push_state(int32); - return TRACK; -} -{U8} { - error(String("top level: header expected: ") - + String_convert::bin2hex_str(String(*YYText()))); - exit(1); -} -{BACKUP_TOP_0} { - error(String("top level: header expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_TOP_1} { - error(String("top level: header expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_TOP_2} { - error(String("top level: header expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{INT32} { // really signed? - LOGOUT(DEBUG_ver) << "lex: int32" << endl; - assert(YYLeng() == 4); - String str((Byte const*)YYText(), YYLeng()); - yylval.i = String_convert::bin2_i(str); - yy_pop_state(); - return INT32; -} -{BACKUP_INT32_0} { - error(String("int32: int32 expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_INT32_1} { - error(String("int32: int32 expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_INT32_2} { - error(String("int32: int32 expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{INT16} { // really signed? - LOGOUT(DEBUG_ver) << "lex: int16" << endl; - assert(YYLeng() == 2); - String str((Byte const*)YYText(), YYLeng()); - yylval.i = (short)String_convert::bin2_i(str); - yy_pop_state(); - return INT16; -} -{BACKUP_INT16_0} { - error(String("int16: int16 expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{I8} { - LOGOUT(DEBUG_ver) << "lex: i8" << endl; - assert(YYLeng() == 1); -// yylval.byte = *(signed char*)YYText(); - yylval.i = *(signed char*)YYText(); - yy_pop_state(); - return I8; -} -{U8} { - LOGOUT(DEBUG_ver) << "lex: u8" << endl; - assert(YYLeng() == 1); -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - return U8; -} - -{VARINT} { - String str((Byte const*)YYText(), YYLeng()); - yylval.i = My_midi_lexer::varint2_i(str); - LOGOUT(DEBUG_ver) << String("lex: track: varint(") - + String(yylval.i) + "): " - + String_convert::bin2hex_str(str) << endl; - yy_push_state(event); - return VARINT; -} -{U8} { - error(String("track: illegal byte: ") - + String_convert::bin2hex_str(String(*YYText()))); - exit(1); -} -{BACKUP_VARINT_0}{U8} { - error(String("track: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_VARINT_1}{U8} { - error(String("track: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_VARINT_2}{U8} { - error(String("track: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{RUNNING_STATUS} { -// yylval.byte = *(Byte*)YYText(); -// yylval.i = *(Byte*)YYText(); - yylval.i = running_status_i_; - LOGOUT(DEBUG_ver) << String ("lex: running status: ") + String(yylval.i) << endl; - /* - 'running status' rather means 'missing status'. - we'll put the running status data back, prepend (unput) - the running status, and try again. - */ - yyless(0); - unput(running_status_i_); - return RUNNING_STATUS; -} -{DATA_ENTRY} { -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - LOGOUT(DEBUG_ver) << String ("lex: undefined data entry: ") + String(yylval.i) << endl; - yy_pop_state(); - yy_push_state(u8); - return DATA_ENTRY; -} -{ALL_NOTES_OFF} { - LOGOUT(DEBUG_ver) << "lex: all note off" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - LOGOUT(DEBUG_ver) << String ("lex: all notes off: ") + String(yylval.i) << endl; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return ALL_NOTES_OFF; -} -{NOTE_OFF} { - LOGOUT(DEBUG_ver) << "lex: note off" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return NOTE_OFF; -} -{NOTE_ON} { - LOGOUT(DEBUG_ver) << "lex: note on" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return NOTE_ON; -} -{POLYPHONIC_AFTERTOUCH} { - LOGOUT(DEBUG_ver) << "lex: polyphonic aftertouch" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return POLYPHONIC_AFTERTOUCH; -} -{CONTROLMODE_CHANGE} { - LOGOUT(DEBUG_ver) << "lex: controlmode change" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return CONTROLMODE_CHANGE; -} -{PROGRAM_CHANGE} { - LOGOUT(DEBUG_ver) << "lex: program change" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - return PROGRAM_CHANGE; -} -{CHANNEL_AFTERTOUCH} { - LOGOUT(DEBUG_ver) << "lex: channel aftertouch" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return CHANNEL_AFTERTOUCH; -} -{PITCHWHEEL_RANGE} { - LOGOUT(DEBUG_ver) << "lex: pitchwheel range" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - running_status_i_ = yylval.i; - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return PITCHWHEEL_RANGE; -} -{SYSEX_EVENT1} { // len data - LOGOUT(DEBUG_ver) << "lex: sysex1" << endl; - yy_pop_state(); - yy_push_state(data); - return SYSEX_EVENT1; -} -{SYSEX_EVENT2} { // len data - LOGOUT(DEBUG_ver) << "lex: sysex2" << endl; - yy_pop_state(); -// yy_push_state(u8); //? - yy_push_state(data); - return SYSEX_EVENT2; -} -{META_EVENT} { - LOGOUT(DEBUG_ver) << "lex: meta" << endl; - yy_push_state(meta_event); - return META_EVENT; -} -{U8} { - error(String("event: illegal byte: ") - + String_convert::bin2hex_str(String(*YYText()))); - exit(1); -} -{SEQUENCE} { // ssss sequence number - LOGOUT(DEBUG_ver) << "lex: sequence" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(int16); - return SEQUENCE; -} -{YYTEXT} { // len data - LOGOUT(DEBUG_ver) << "lex: text" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYTEXT; -} -{YYCOPYRIGHT} { - LOGOUT(DEBUG_ver) << "lex: copyright" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYCOPYRIGHT; -} -{YYTRACK_NAME} { - LOGOUT(DEBUG_ver) << "lex: track name" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYTRACK_NAME; -} -{YYINSTRUMENT_NAME} { - LOGOUT(DEBUG_ver) << "lex: instrument name" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYINSTRUMENT_NAME; -} -{YYLYRIC} { - LOGOUT(DEBUG_ver) << "lex: lyric" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYLYRIC; -} -{YYMARKER} { - LOGOUT(DEBUG_ver) << "lex: marker" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYMARKER; -} -{YYCUE_POINT} { - LOGOUT(DEBUG_ver) << "lex: cue point" << endl; -// yylval.byte = *(Byte*)YYText(); - yylval.i = *(Byte*)YYText(); - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return YYCUE_POINT; -} -{TEMPO} { // tttttt usec - LOGOUT(DEBUG_ver) << "lex: tempo" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - return TEMPO; -} -{SMPTE_OFFSET} { // hr mn se fr ff - LOGOUT(DEBUG_ver) << "lex: smpte offset" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - return SMPTE_OFFSET; -} -{TIME} { // nn dd cc bb - LOGOUT(DEBUG_ver) << "lex: time" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - yy_push_state(u8); - return TIME; -} -{KEY} { // sf mi - LOGOUT(DEBUG_ver) << "lex: key" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(i8); - yy_push_state(i8); - return KEY; -} -{SSME} { // len data - LOGOUT(DEBUG_ver) << "lex: smme" << endl; - yy_pop_state(); - yy_pop_state(); - yy_push_state(data); - return SSME; -} -{END_OF_TRACK} { - LOGOUT(DEBUG_ver) << "lex: end of track" << endl; - yy_pop_state(); - yy_pop_state(); - yy_pop_state(); - return END_OF_TRACK; -} -{U8} { - warning(String("meta_event: unimplemented event: ") - + String_convert::bin2hex_str(String(*YYText())) -// huh? -// ,this->here_ch_C() - ); - yy_pop_state(); - yy_pop_state(); - yy_push_state(u8); - yy_push_state(u8); - return U8; -} - -{VARINT} { - LOGOUT(DEBUG_ver) << "lex: data" << endl; - String str((Byte const*)YYText(), YYLeng()); - int i = My_midi_lexer::varint2_i(str); - String* str_p = new String; - while (i--) - *str_p += (char)yyinput(); - yylval.str_p = str_p; - yy_pop_state(); - return DATA; -} -{U8} { - error(String("data: illegal byte: ") - + String_convert::bin2hex_str(String(*YYText()))); - exit(1); -} -{BACKUP_VARINT_0}{U8} { - error(String("data: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_VARINT_1}{U8} { - error(String("data: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} -{BACKUP_VARINT_2}{U8} { - error(String("data: varint expected: ") - + String_convert::bin2hex_str(String(*(YYText())))); - exit(1); -} - -<> { -// LOGOUT(NORMAL_ver) << "<>"; - - if (!close_i()) - yyterminate(); // can't move this, since it actually rets a YY_NULL -} - -%% - diff --git a/mi2mu/midi-parser.cc b/mi2mu/midi-parser.cc new file mode 100644 index 0000000000..c63c95dfc2 --- /dev/null +++ b/mi2mu/midi-parser.cc @@ -0,0 +1,97 @@ +/* + midi-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "source-file.hh" +#include "mi2mu-global.hh" +#include "midi-parser.hh" + +Midi_parser_info::Midi_parser_info () +{ + division_1_i_ = 0; + format_i_ = 0; + tracks_i_ = 0; + errorlevel_i_ = 0; + byte_L_ = 0; + end_byte_L_ = 0; +} + +Midi_parser::Midi_parser () +{ + info_l_ = 0; +} + +int +Midi_parser::exit (String str) +{ + error (str); + ::exit (1); + return 0; +} + +void +Midi_parser::error (String str) +{ + ::message (message (str)); +} + +int +Midi_parser::get_i (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +unsigned +Midi_parser::get_u (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +String +Midi_parser::get_str (int n) +{ + assert (n > 0); + Byte const* p = forward_byte_L (n); + return String (p, n); +} + +int +Midi_parser::get_var_i () +{ + int var_i = 0; + + while (1) + { + Byte byte = next_byte (); + var_i <<= 7; + var_i += byte & 0x7f; + if (!(byte & 0x80)) + return var_i; + } + exit ("get_var_i:"); + return 0; +} + +String +Midi_parser::message (String str) +{ + return String ("mi2mu: ") + + info_l_->source_l_->name_str () + ": " + + String_convert::i2dec_str (info_l_->source_l_->line_i ((char const*)info_l_->byte_L_), 0, 0) + ": " + + str + "\n" + + info_l_->source_l_->error_str ((char const*)info_l_->byte_L_); +} + +void +Midi_parser::warning (String str) +{ + ::message (message (String ("warning: ") + str)); +} diff --git a/mi2mu/midi-parser.y b/mi2mu/midi-parser.y index c1ec3edfed..e69de29bb2 100644 --- a/mi2mu/midi-parser.y +++ b/mi2mu/midi-parser.y @@ -1,332 +0,0 @@ -%{ - -#include "mi2mu-proto.hh" -#include "proto.hh" -#include "plist.hh" -#include "warn.hh" -#include "mi2mu-global.hh" -//#include "midi-parser.hh" -#include "my-midi-parser.hh" -#include "my-midi-lexer.hh" -#include "duration-convert.hh" -#include "string-convert.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" -#include "mudela-staff.hh" - -#ifndef NDEBUG -#define YYDEBUG 1 -#endif - -%} - -%union { - Byte byte; - char c; - int i; - String* str_p; - Mudela_item* mudela_item_p; // Voice_element* ? jup, just about :-) - Mudela_score* mudela_score_p; // Input_score* ? - Mudela_staff* mudela_staff_p; // Input_music* ? -} - -%token HEADER TRACK -%token SYSEX_EVENT1 SYSEX_EVENT2 -%token META_EVENT -%token SEQUENCE -%token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME - -%token I8 U8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT -%token RUNNING_STATUS DATA_ENTRY ALL_NOTES_OFF -%token NOTE_OFF NOTE_ON -%token POLYPHONIC_AFTERTOUCH CONTROLMODE_CHANGE PROGRAM_CHANGE -%token CHANNEL_AFTERTOUCH PITCHWHEEL_RANGE -%token YYTEXT YYCOPYRIGHT YYTRACK_NAME YYINSTRUMENT_NAME YYLYRIC YYMARKER YYCUE_POINT -%token DATA - -%type varint -%type header mudela_score -%type track -%type item -%type the_item meta_item the_meta_item text_item mudela_item sysex_item -%type running_status data_entry all_notes_off -%type note_off note_on -%type polyphonic_aftertouch controlmode_change program_change -%type channel_aftertouch pitchwheel_range - -%% - -midi: /* empty */ - | midi mudela_score { - midi_parser_l_g->add_score ($2); - } - ; - -mudela_score: - header { - } - | mudela_score track { - $$->add_staff ($2); - // ugh - $2->set_tempo (midi_parser_l_g->mudela_tempo_p_->useconds_per_4_i()); - $2->set_meter (midi_parser_l_g->mudela_meter_p_->num_i(), - midi_parser_l_g->mudela_meter_p_->den_i(), - midi_parser_l_g->mudela_meter_p_->clocks_1_i(), - 8); - if (midi_parser_l_g->copyright_str_.length_i()) - $2->copyright_str_ = midi_parser_l_g->copyright_str_; - if (midi_parser_l_g->track_name_str_.length_i()) - $2->name_str_ = midi_parser_l_g->track_name_str_; - if (midi_parser_l_g->instrument_str_.length_i()) - $2->instrument_str_ = midi_parser_l_g->instrument_str_; - midi_parser_l_g->reset(); - } - ; - -header: - HEADER INT32 INT16 INT16 INT16 { - // ugh, already constructed; - // need to have score in My_midi_parser... -// $$ = new Mudela_score ($3, $4, $5); - $$ = midi_parser_l_g->mudela_score_p_; - $$->format_i_ = $3; - $$->tracks_i_ = $4; - $$->tempo_i_ = $5; - midi_parser_l_g->set_division_4 ($5); - } - ; - -track: - TRACK INT32 { - LOGOUT (NORMAL_ver) << "\ntrack " << midi_parser_l_g->track_i_ << ": " << flush; - $$ = new Mudela_staff (midi_parser_l_g->track_i_++, - // silly, cause not set yet! - midi_parser_l_g->copyright_str_, - midi_parser_l_g->track_name_str_, - midi_parser_l_g->instrument_str_); - //ugh, need to know now! - midi_parser_l_g->mudela_staff_l_ = $$; - } - | track item { - if ($2) { - $2->mudela_column_l_ = midi_parser_l_g->mudela_column_l_; - $$->add_item ($2); - } - } - ; - -item: - varint the_item { - $$ = $2; - if ($2) { - String str = $2->str(); - if (str.length_i()) - LOGOUT (DEBUG_ver) << str << " " << flush; - } - } - ; - -varint: - VARINT { - midi_parser_l_g->forward ($1); - } - ; - -the_item: - meta_item { - } - | mudela_item { - } - | sysex_item { - } - ; - -meta_item: - META_EVENT the_meta_item { - $$ = $2; - } - | - META_EVENT U8 U8 U8 { - $$ = 0; - } - ; - -the_meta_item: - SEQUENCE INT16 { - } - | text_item DATA { - Mudela_text::Type type = (Mudela_text::Type)$1; - $$ = 0; - switch (type) - { - case Mudela_text::COPYRIGHT: - midi_parser_l_g->copyright_str_ = *$2; - break; - case Mudela_text::TRACK_NAME: - midi_parser_l_g->track_name_str_ = *$2; - break; - case Mudela_text::INSTRUMENT_NAME: - midi_parser_l_g->instrument_str_ = *$2; - break; - default: - $$ = new Mudela_text (type, *$2); - break; - } - LOGOUT (DEBUG_ver) << *$2 << endl; - delete $2; - } - | END_OF_TRACK { - $$ = 0; - } - | TEMPO U8 U8 U8 { - $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4); - LOGOUT (DEBUG_ver) << $$->str() << endl; - midi_parser_l_g->set_tempo ( ($2 << 16) + ($3 << 8) + $4); - } - | SMPTE_OFFSET U8 U8 U8 U8 U8 { - $$ = 0; - } - | TIME U8 U8 U8 U8 { - $$ = new Mudela_meter ($2, $3, $4, $5); - LOGOUT (DEBUG_ver) << $$->str() << endl; - midi_parser_l_g->set_meter ($2, $3, $4, $5); - } - | KEY I8 I8 { - $$ = new Mudela_key ($2, $3); - midi_parser_l_g->set_key ($2, $3 ); - } - | SSME DATA { - $$ = new Mudela_text ((Mudela_text::Type)0, *$2); - delete $2; - } - ; - -text_item: - YYTEXT { - LOGOUT (DEBUG_ver) << "\n% Text: "; - } - | YYCOPYRIGHT { - LOGOUT (DEBUG_ver) << "\n% Copyright: "; - } - | YYTRACK_NAME { - LOGOUT (DEBUG_ver) << "\n% Track name: "; - } - | YYINSTRUMENT_NAME { - LOGOUT (DEBUG_ver) << "\n% Instrument name: "; - } - | YYLYRIC { - LOGOUT (DEBUG_ver) << "\n% Lyric: "; - } - | YYMARKER { - LOGOUT (DEBUG_ver) << "\n% Marker: "; - } - | YYCUE_POINT { - LOGOUT (DEBUG_ver) << "\n% Cue point: "; - } - ; - -mudela_item: - running_status { - } - | data_entry { - } - | all_notes_off { - } - | note_off { - } - | note_on { - } - | polyphonic_aftertouch { - } - | controlmode_change { - } - | program_change { - } - | channel_aftertouch { - } - | pitchwheel_range { - } - ; - -running_status: - RUNNING_STATUS mudela_item { - $$ = $2; - } - ; - -data_entry: - DATA_ENTRY U8 { - $$ = 0; - } - ; - -all_notes_off: - ALL_NOTES_OFF U8 U8 { - midi_parser_l_g->note_end_all(); - $$ = 0; - } - ; - -note_off: - NOTE_OFF U8 U8 { - int i = $1; - i = i & ~0x80; - midi_parser_l_g->note_end ($1 & ~0x80, $2, $3); - $$ = 0; - } - ; - -note_on: - NOTE_ON U8 U8 { - int i = $1; - i = i & ~0x90; - $$ = 0; - if ($3) - midi_parser_l_g->note_begin ($1 & ~0x90, $2, $3); - /* - sss: some broken devices encode NOTE_OFF as - NOTE_ON with zero volume - */ - else - midi_parser_l_g->note_end ($1 & ~0x90, $2, $3); - } - ; - -polyphonic_aftertouch: - POLYPHONIC_AFTERTOUCH U8 U8 { - $$ = 0; - } - ; - -controlmode_change: - CONTROLMODE_CHANGE U8 U8 { - $$ = 0; - } - ; - -program_change: - PROGRAM_CHANGE U8 { - $$ = 0; - } - ; - -channel_aftertouch: - CHANNEL_AFTERTOUCH U8 U8 { - $$ = 0; - } - ; - -pitchwheel_range: - PITCHWHEEL_RANGE U8 U8 { - $$ = 0; - } - ; - -sysex_item: - SYSEX_EVENT1 DATA { - $$ = 0; - } - | SYSEX_EVENT2 DATA { // U8 ? - $$ = 0; - } - ; diff --git a/mi2mu/midi-score-parser.cc b/mi2mu/midi-score-parser.cc new file mode 100644 index 0000000000..d1a700069c --- /dev/null +++ b/mi2mu/midi-score-parser.cc @@ -0,0 +1,119 @@ +/* + midi-score-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include "moment.hh" +#include "source-file.hh" +#include "source.hh" +#include "mi2mu-global.hh" +#include "midi-score-parser.hh" +#include "midi-track-parser.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" + + +void +Midi_score_parser::open (String filename_str, Sources* sources_l) +{ + info_l_->source_l_ = sources_l->get_file_l (filename_str); + if (!info_l_->source_l_) + ::error ("can't find: `" + filename_str + "'"); + info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C (); +// info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i (); + info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1; +} + +Mudela_score* +Midi_score_parser::parse (String filename_str, Sources* sources_l) +{ + Midi_parser_info info; + info_l_ = &info; + open (filename_str, sources_l); + parse_header (); + return parse_score (); +} + +void +Midi_score_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MThd" ) + exit ("MIDI header expected"); + + int length_i = get_i (4); + // is this signed? + if (length_i < 6) + exit ("Invalid header length"); + info_l_->format_i_ = get_i (2); + if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1) + exit ("Invalid midi format"); + info_l_->tracks_i_ = get_i (2); + if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 ) + exit ("Invalid number of tracks"); + info_l_->division_1_i_ = get_i (2) * 4; + if (info_l_->division_1_i_ < 0) + exit ("Cannot handle non-metrical time"); + forward_byte_L (length_i - 6); +} + +int +Midi_score_parser::find_earliest_i (Link_array& tracks) +{ + int earliest_i = 0; + Moment earliest_mom = infinity_mom; + for (int i = 0; i < tracks.size(); i++) + { + if ( tracks [i]->at_mom () < earliest_mom ) + { + earliest_mom = tracks [i]->at_mom (); + earliest_i = i; + } + } + return earliest_i; +} + +Mudela_score* +Midi_score_parser::parse_score () +{ + Mudela_meter m4 (1, 4, 0, 0); + Moment bar4_mom = m4.bar_mom (); + + Link_array tracks; + for (int i = 0; i < info_l_->tracks_i_; i++) + tracks.push (new Midi_track_parser (info_l_)); + + int current_bar_i = 0; + + Mudela_score* score_p = new Mudela_score( 1, 1, 1 ); + while (tracks.size ()) + { + int i = find_earliest_i (tracks); + Moment at_mom = tracks [i]->at_mom (); + Mudela_column* column_l = score_p->get_column_l (at_mom); + Mudela_staff* staff_p = tracks [i]->parse (column_l); + if ( staff_p ) + { + score_p->add_staff (staff_p); + delete tracks [i]; + tracks.del (i); + } + + // brr, musta have some progress + for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++) + info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_; + + int bar_i = (int) (at_mom + / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1; + if (bar_i > current_bar_i) + { + LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; + current_bar_i = bar_i; + } + } + return score_p; +} + diff --git a/mi2mu/midi-track-parser.cc b/mi2mu/midi-track-parser.cc new file mode 100644 index 0000000000..8f346f565b --- /dev/null +++ b/mi2mu/midi-track-parser.cc @@ -0,0 +1,334 @@ +/* + midi-track-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "mi2mu-global.hh" +#include "midi-track-parser.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-staff.hh" + +Midi_track_parser::Midi_track_parser (Midi_parser_info* info_l) +{ + info_l_ = info_l; + at_mom_ = 0; + track_info_p_ = 0; + mudela_staff_p_ = new Mudela_staff (0, "", "", ""); + parse_header (); + parse_delta_time (); +} + +Midi_track_parser::~Midi_track_parser () +{ + delete mudela_staff_p_; + delete track_info_p_; +} + +Moment +Midi_track_parser::at_mom () +{ + return at_mom_; +} + +bool +Midi_track_parser::eot () +{ + if ( info_l_->byte_L_ < info_l_->end_byte_L_ ) + return false; + return true; +} + +void +Midi_track_parser::note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ) +{ + // junk dynamics + (void)aftertouch_i; + + for (PCursor i (open_note_l_list_.top ()); i.ok (); i++) + { + if ((i->pitch_i_ == pitch_i) && (i->channel_i_ == channel_i)) + { + i->end_column_l_ = col_l; + // LOGOUT(DEBUG_ver) << "Note: " << pitch_i; + // LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_; + // LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n"; + i.remove_p(); + return; + } + } + warning (String ("junking note-end event: ") + + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ') + + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' ')); +} + +void +Midi_track_parser::note_end_all (Mudela_column* col_l) +{ + // find + for (PCursor i (open_note_l_list_.top ()); i.ok (); i++) + { + i->end_column_l_ = col_l; + i.remove_p(); + // ugh + if (!i.ok()) + break; + } +} + +Mudela_staff* +Midi_track_parser::parse (Mudela_column* col_l) +{ + Moment mom = at_mom (); + while (!eot () && (mom == at_mom ())) + { + Mudela_item* p = parse_event (col_l); + if (p) + mudela_staff_p_->add_item (p); + } + + if (!eot()) + return 0; + + Mudela_staff* p = mudela_staff_p_; + mudela_staff_p_ = 0; + return p; +} + +void +Midi_track_parser::parse_delta_time () +{ + if (eot ()) + return; + int delta_i = get_var_i (); + at_mom_ += Moment (delta_i, info_l_->division_1_i_); +} + +Mudela_item* +Midi_track_parser::parse_event (Mudela_column* col_l) +{ + Byte byte = peek_byte (); + // RUNNING_STATUS [\x00-\x5f] + if (byte <= 0x5f) + { + if (running_byte_ <= 0x5f) + exit ("Invalid running status"); + /* + 'running status' rather means 'missing status'. + we'll just pretend we read the running status byte. + */ + byte = running_byte_; + } + else + byte = next_byte (); + + Mudela_item* item_p = 0; + // DATA_ENTRY [\x60-\x79] + if ((byte >= 0x60) && (byte <= 0x79)) + { + next_byte (); + } + // ALL_NOTES_OFF [\x7a-\x7f] + else if ((byte >= 0x7a) && (byte <= 0x7f)) + { + next_byte (); + next_byte (); + note_end_all (col_l); + } + // NOTE_OFF [\x80-\x8f] + else if ((byte >= 0x80) && (byte <= 0x8f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + note_end (col_l, channel_i, pitch_i, dyn_i); + } + // NOTE_ON [\x90-\x9f] + else if ((byte >= 0x90) && (byte <= 0x9f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + /* + sss: some broken devices encode NOTE_OFF as + NOTE_ON with zero volume + */ + if (dyn_i) + { + Mudela_note* p = new Mudela_note (col_l, channel_i, pitch_i, dyn_i); + item_p = p; + open_note_l_list_.bottom ().add (p); + } + else + { + note_end (col_l, channel_i, pitch_i, dyn_i); + } + } + // POLYPHONIC_AFTERTOUCH [\xa0-\xaf] + else if ((byte >= 0xa0) && (byte <= 0xaf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // CONTROLMODE_CHANGE [\xb0-\xbf] + else if ((byte >= 0xb0) && (byte <= 0xbf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PROGRAM_CHANGE [\xc0-\xcf] + else if ((byte >= 0xc0) && (byte <= 0xcf)) + { + running_byte_ = byte; + next_byte (); + } + // CHANNEL_AFTERTOUCH [\xd0-\xdf] + else if ((byte >= 0xd0) && (byte <= 0xdf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PITCHWHEEL_RANGE [\xe0-\xef] + else if ((byte >= 0xe0) && (byte <= 0xef)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // SYSEX_EVENT1 [\xf0] + else if (byte == 0xf0) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // SYSEX_EVENT2 [\xf7] + else if (byte == 0xf7) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // META_EVENT [\xff] + else if (byte == 0xff) + { + // SEQUENCE [\x00][\x02] + byte = next_byte (); + if (byte == 0) + { + next_byte (); + get_i (2); + } + // YYTEXT [\x01] + // YYCOPYRIGHT [\x02] + // YYTRACK_NAME [\x03] + // YYINSTRUMENT_NAME [\x04] + // YYLYRIC [\x05] + // YYMARKER [\x06] + // YYCUE_POINT [\x07] + else if ((byte >= 0x01) && (byte <= 0x07)) + { + // LOGOUT (DEBUG_ver) << "\n% Text(" << (int)byte << "):" << flush; + int length_i = get_var_i (); + String str = get_str (length_i); + // LOGOUT (DEBUG_ver) << str << endl; + item_p = new Mudela_text ((Mudela_text::Type)byte, str); + } + // END_OF_TRACK [\x2f][\x00] + else + { + Byte next = peek_byte (); + if ((byte == 0x2f) && (next == 0x00)) + { + next_byte (); + info_l_->byte_L_ = info_l_->end_byte_L_; + } + // TEMPO [\x51][\x03] + else if ((byte == 0x51) && (next == 0x03)) + { + next_byte (); + unsigned useconds_per_4_u = get_u (3); + // $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4); + // LOGOUT (DEBUG_ver) << $$->str() << endl; + item_p = new Mudela_tempo ( useconds_per_4_u ); + } + // SMPTE_OFFSET [\x54][\x05] + else if ((byte == 0x54) && (next == 0x05)) + { + next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + } + // TIME [\x58][\x04] + else if ((byte == 0x58) && (next == 0x04)) + { + next_byte (); + int num_i = (int)next_byte (); + int den_i = (int)next_byte (); + int clocks_4_i = (int)next_byte (); + int count_32_i = (int)next_byte (); + Mudela_meter* p = new Mudela_meter ( num_i, den_i, clocks_4_i, count_32_i ); + item_p = p; + info_l_->bar_mom_ = p->bar_mom (); + } + // KEY [\x59][\x02] + else if ((byte == 0x59) && (next == 0x02)) + { + next_byte (); + int accidentals_i = (int)next_byte (); + int minor_i = (int)next_byte (); + item_p = new Mudela_key (accidentals_i, minor_i); + } + // SSME [\0x7f][\x03] + else if ((byte == 0x7f) && (next == 0x03)) + { + next_byte (); + int length_i = get_var_i (); + String str = get_str (length_i); + item_p = new Mudela_text ((Mudela_text::Type)byte, str); + } + else + exit ("Invalid MIDI meta-event"); + } + } + else + exit ("Invalid MIDI event"); + + if (item_p) + item_p->mudela_column_l_ = col_l; + + parse_delta_time (); + + return item_p; +} + +void +Midi_track_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MTrk" ) + exit ("MIDI track expected"); + + int length_i = get_i (4); + // is this signed? + if (length_i < 0) + exit ("Invalid track length"); + assert (!track_info_p_); + track_info_p_ = new Midi_parser_info (*info_l_); + track_info_p_->end_byte_L_ = track_info_p_->byte_L_ + length_i; + forward_byte_L (length_i); +// forward_byte_L (length_i-1); + info_l_ = track_info_p_; +} + diff --git a/mi2mu/mudela-item.cc b/mi2mu/mudela-item.cc index 3179662b72..300ada5d4c 100644 --- a/mi2mu/mudela-item.cc +++ b/mi2mu/mudela-item.cc @@ -3,6 +3,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "mi2mu-global.hh" #include "string-convert.hh" #include "duration-convert.hh" @@ -17,13 +18,13 @@ Mudela_item::Mudela_item (Mudela_column* mudela_column_l) } Moment -Mudela_item::at_mom() +Mudela_item::at_mom () { - return mudela_column_l_->at_mom(); + return mudela_column_l_->at_mom (); } Moment -Mudela_item::duration_mom() +Mudela_item::duration_mom () { return Moment (0); } @@ -31,7 +32,7 @@ Mudela_item::duration_mom() void Mudela_item::output (Mudela_stream& mudela_stream_r) { - mudela_stream_r << str() << String (" "); + mudela_stream_r << str () << String (" "); } Mudela_key::Mudela_key (int accidentals_i, int minor_i) @@ -39,22 +40,22 @@ Mudela_key::Mudela_key (int accidentals_i, int minor_i) { accidentals_i_ = accidentals_i; minor_i_ = minor_i; - if (accidentals_i >= 0) + if (accidentals_i >= 0) key_i_ = ((accidentals_i % 7)[ "cgdaebf" ] - 'a' - 2) % 7; else key_i_ = ((-accidentals_i % 7)[ "cfbeadg" ] - 'a' - 2) % 7; } String -Mudela_key::str() +Mudela_key::str () { String str = "\\key "; - if (!minor_i_) + if (!minor_i_) str += String ((char) ((key_i_ + 2) % 7 + 'A')); else // heu, -2: should be - 1 1/2: A -> fis str += String ((char) ((key_i_ + 2 - 2) % 7 + 'a')); str = String ("% \"") + str - + String('"') + "; % not supported yet\n"; + + String ('"') + "; % not supported yet\n"; return str; } @@ -71,7 +72,7 @@ Mudela_key::notename_str (int pitch_i) static int accidentals_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }; int accidental_i = accidentals_i_a[ minor_i_ * 5 + pitch_i % 12 ]; - if (accidental_i && (accidentals_i_ < 0)) + if (accidental_i && (accidentals_i_ < 0)) { accidental_i = - accidental_i; notename_i = (notename_i + 1) % 7; @@ -98,7 +99,7 @@ Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i { sync_dur_.durlog_i_ = 3 ; sync_f_ = 1.0; - if (count_32_i != 8) + if (count_32_i != 8) warning (String ("#32 in quarter: ") + String (count_32_i)); num_i_ = num_i; den_i_ = den_i; @@ -106,7 +107,7 @@ Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i } Moment -Mudela_meter::bar_mom() +Mudela_meter::bar_mom () { Duration d; d.durlog_i_ = den_i_; @@ -114,25 +115,25 @@ Mudela_meter::bar_mom() } int -Mudela_meter::clocks_1_i() +Mudela_meter::clocks_1_i () { return clocks_1_i_; } int -Mudela_meter::den_i() +Mudela_meter::den_i () { return den_i_; } int -Mudela_meter::num_i() +Mudela_meter::num_i () { return num_i_; } String -Mudela_meter::str() +Mudela_meter::str () { String str = "\\meter " + String (num_i_) + "/" + String (1 << den_i_) @@ -160,22 +161,38 @@ Mudela_note::Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pit end_column_l_ = 0; } +Duration +Mudela_note::duration () +{ + assert (end_column_l_); + Moment mom = end_column_l_->at_mom () - at_mom (); + return Duration_convert::mom2_dur (mom); +} + +Moment +Mudela_note::duration_mom () +{ +// ugh +// return Duration_convert::dur2_mom (duration ()); + return end_column_l_->at_mom () - at_mom (); +} + String -Mudela_note::str() +Mudela_note::str () { - Duration dur = duration(); - if (dur.durlog_i_ < -10) + Duration dur = duration (); + if (dur.durlog_i_ < -10) return ""; String name_str = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_); - if (simple_plet_b_s) + if (simple_plet_b_s) return name_str + Duration_convert::dur2_str (dur) + " "; //ugh String str; - if (dur.plet_b()) + if (dur.plet_b ()) str += String ("\\plet ") + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0) + "/" @@ -188,28 +205,12 @@ Mudela_note::str() tmp.set_plet (1,1); str += Duration_convert::dur2_str (tmp); - if (dur.plet_b()) + if (dur.plet_b ()) str += String (" \\plet 1/1;"); return str + " "; } -Duration -Mudela_note::duration() -{ - assert (end_column_l_); - Moment mom = end_column_l_->at_mom() - at_mom(); - return Duration_convert::mom2_dur (mom); -} - -Moment -Mudela_note::duration_mom() -{ -// ugh -// return Duration_convert::dur2_mom (duration()); - return end_column_l_->at_mom() - at_mom(); -} - Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) : Mudela_item (mudela_column_l) { @@ -217,25 +218,25 @@ Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) } Duration -Mudela_skip::duration() +Mudela_skip::duration () { return Duration_convert::mom2_dur (mom_); } Moment -Mudela_skip::duration_mom() +Mudela_skip::duration_mom () { - return Duration_convert::dur2_mom (duration()); + return Duration_convert::dur2_mom (duration ()); } String -Mudela_skip::str() +Mudela_skip::str () { - if (!mom_) + if (!mom_) return String (""); - Duration dur = duration(); - if (dur.durlog_i_<-10) + Duration dur = duration (); + if (dur.durlog_i_<-10) return ""; String str = "\\skip "; @@ -252,7 +253,7 @@ Mudela_tempo::Mudela_tempo (int useconds_per_4_i) } String -Mudela_tempo::str() +Mudela_tempo::str () { String str = "\\tempo 4="; str += String (get_tempo_i (Moment (1, 4))); @@ -261,7 +262,7 @@ Mudela_tempo::str() } int -Mudela_tempo::useconds_per_4_i() +Mudela_tempo::useconds_per_4_i () { return useconds_per_4_i_; } @@ -280,10 +281,10 @@ Mudela_text::Mudela_text (Mudela_text::Type type, String text_str) } String -Mudela_text::str() +Mudela_text::str () { - if (!text_str_.length_i() - || (text_str_.length_i() != (int)strlen (text_str_.ch_C()))) + if (!text_str_.length_i () + || (text_str_.length_i () != (int)strlen (text_str_.ch_C ()))) return ""; return "% " + text_str_ + "\n"; diff --git a/mi2mu/mudela-score.cc b/mi2mu/mudela-score.cc index 843bab56c7..c8f575d04c 100644 --- a/mi2mu/mudela-score.cc +++ b/mi2mu/mudela-score.cc @@ -3,6 +3,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "moment.hh" #include "duration.hh" #include "duration-convert.hh" @@ -13,12 +14,20 @@ #include "mudela-staff.hh" #include "mudela-stream.hh" +static Mudela_key key_c (0, 0); +static Mudela_meter meter_4 (4, 2, 24, 8); +// useconds per 4: 250000 === 60 4 per minute +static Mudela_tempo tempo_60 (1000000); + Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i) { format_i_ = format_i; tracks_i_ = tracks_i; tempo_i_ = tempo_i; - mudela_column_p_list_.bottom().add (new Mudela_column (this, Moment (0))); + column_l_array_.push (new Mudela_column (this, Moment (0))); + mudela_key_l_ = &key_c; + mudela_meter_l_ = &meter_4; + mudela_tempo_l_ = &tempo_60; } Mudela_score::~Mudela_score() @@ -38,23 +47,27 @@ Mudela_score::add_staff (Mudela_staff* mudela_staff_p) } Mudela_column* -Mudela_score::mudela_column_l (Moment mom) +Mudela_score::find_column_l (Moment mom) +{ + // should do binary search + for (int i = 0; i < column_l_array_.size (); i++ ) + if ( column_l_array_[i]->at_mom () == mom ) + return column_l_array_[i]; + return 0; +} + +Mudela_column* +Mudela_score::get_column_l (Moment mom) { - for (PCursor i (mudela_column_p_list_); i.ok(); i++) + if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom ) { - if (i->at_mom() > mom) - { - Mudela_column* p = new Mudela_column (this, mom); - i.insert (p); - return p; - } - if (i->at_mom() == mom) - return *i; + error ("ugh"); + exit (1); } + if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom ) + column_l_array_.push (new Mudela_column (this, mom)); - Mudela_column* p = new Mudela_column (this, mom); - mudela_column_p_list_.bottom().add (p); - return p; + return column_l_array_ [column_l_array_.size() - 1]; } void @@ -93,7 +106,7 @@ Mudela_score::output (String filename_str) mudela_stream << "\\paper{}\n"; - mudela_stream << "\\midi{ "; + mudela_stream << "\\midi{\n"; // let's not use silly 0 track mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream); mudela_stream << "}\n"; @@ -107,8 +120,8 @@ Mudela_score::process() LOGOUT(NORMAL_ver) << "\nProcessing..." << endl; LOGOUT(DEBUG_ver) << "columns\n"; - for (PCursor i (mudela_column_p_list_); i.ok(); i++) - LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n"; +// for (PCursor i (mudela_column_p_list_); i.ok(); i++) +// LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n"; settle_columns(); filter_tempo(); @@ -171,12 +184,16 @@ Mudela_score::settle_columns() // return; LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl; +#if 0 assert (!column_l_array_.size()); int n = mudela_column_p_list_.size(); // huh? // column_l_array_.set_size (n); for (PCursor i (mudela_column_p_list_); i.ok(); i++) column_l_array_.push (*i); +#endif + + int n = column_l_array_.size(); int start_i = 0; int end_i = 0; diff --git a/mi2mu/mudela-staff.cc b/mi2mu/mudela-staff.cc index 3f1373a4ac..b8535618b9 100644 --- a/mi2mu/mudela-staff.cc +++ b/mi2mu/mudela-staff.cc @@ -3,6 +3,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include #include "moment.hh" #include "duration-convert.hh" @@ -14,9 +15,9 @@ #include "mudela-staff.hh" #include "mudela-stream.hh" #include "mudela-voice.hh" -#include "my-midi-parser.hh" #include "mudela-score.hh" +extern Mudela_score* mudela_score_l_g; Mudela_staff::Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str) { @@ -60,7 +61,7 @@ Mudela_staff::eat_voice (Link_list& items) { Moment dur = i->at_mom() - mom; // ugh, need score - Mudela_column* start = midi_parser_l_g->mudela_score_p_->mudela_column_l (mom); + Mudela_column* start = mudela_score_l_g->find_column_l (mom); voice_p->add_item (new Mudela_skip (start, dur)); mom = i->at_mom(); } diff --git a/mi2mu/mudela-stream.cc b/mi2mu/mudela-stream.cc index 1f171bf8ed..545887091f 100644 --- a/mi2mu/mudela-stream.cc +++ b/mi2mu/mudela-stream.cc @@ -5,13 +5,15 @@ // // (c) 1997 Jan Nieuwenhuizen +#include #include #include #include "mi2mu-global.hh" -#include "my-midi-parser.hh" #include "mudela-item.hh" #include "mudela-stream.hh" +extern String filename_str_g; + static int const INDENT_i = 8; Mudela_stream::Mudela_stream (String filename_str) @@ -73,7 +75,9 @@ Mudela_stream::header() time_t t (time (0)); *os_p_ << ctime (&t); *os_p_ << "% from input file: "; - *os_p_ << midi_parser_l_g->filename_str_; + // *os_p_ << midi_parser_l_g->filename_str_; + // ugh + *os_p_ << filename_str_g; *os_p_ << "\n\n"; // ugh *os_p_ << "\\version \"0.1.1\";\n"; diff --git a/mi2mu/my-midi-lexer.cc b/mi2mu/my-midi-lexer.cc index 483fce6927..e69de29bb2 100644 --- a/mi2mu/my-midi-lexer.cc +++ b/mi2mu/my-midi-lexer.cc @@ -1,91 +0,0 @@ -// -// my-midi-lexer.cc -- implement My_midi_lexer -// -// copyright 1997 Jan Nieuwenhuizen - -#include "string-convert.hh" -#include "mi2mu-global.hh" -#include "my-midi-lexer.hh" -#include "source.hh" -#include "source-file.hh" - -int -yylex() -{ - return midi_lexer_l_g->yylex(); -} - -My_midi_lexer* midi_lexer_l_g = 0; - -My_midi_lexer::My_midi_lexer (String &filename_str, Sources * sources) -{ - source_file_l_ = sources->get_file_l(filename_str); - if (!source_file_l_) - ::error ("can't find: `" + filename_str + "'"); - switch_streams (source_file_l_->istream_l(), 0); - errorlevel_i_ = 0; - char_count_ = 0; - running_status_i_ = 0; -} - -My_midi_lexer::~My_midi_lexer() -{ -// delete source_file_p_; -} - -void -My_midi_lexer::error (char const* sz_l) -{ - if (1|| !source_file_l_) - { - cerr << "error at EOF: `" << sz_l << "'\n"; - } - else - { - - // FIXME - #if 0 - char const* ch_C = here_ch_C(); - if (ch_C) - { - ch_C--; - while ( (*ch_C == ' ') || (*ch_C == '\t') || (*ch_C == '\n')) - ch_C--; - ch_C++; - } - errorlevel_i_ |= 1; - error (sz_l); - #endif - } -} - -char const* -My_midi_lexer::here_ch_C() -{ - return source_file_l_->ch_C() + char_count_ ; -} - -int -My_midi_lexer::varint2_i (String str) -{ - int var_i = 0; - - for (int i = 0; i < str.length_i(); i++) - { - Byte byte = str[ i ]; - var_i <<= 7; - var_i += byte & 0x7f; - if (! (byte & 0x80)) - return var_i; - } - cout << "\nvarint2_i:" << String_convert::bin2hex_str (str) << endl; - assert (0); // illegal varint - return 0; -} - -int -My_midi_lexer::close_i() -{ - return 0; -} - diff --git a/mi2mu/my-midi-parser.cc b/mi2mu/my-midi-parser.cc index 2a7e2d77bc..e69de29bb2 100644 --- a/mi2mu/my-midi-parser.cc +++ b/mi2mu/my-midi-parser.cc @@ -1,232 +0,0 @@ -// -// my-midi-parser.cc -- implement My_midi_parser -// -// copyright 1997 Jan Nieuwenhuizen - -#include "string-convert.hh" -#include "duration-convert.hh" -#include "mi2mu-global.hh" -#include "my-midi-lexer.hh" -#include "my-midi-parser.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" -#include "mudela-staff.hh" - -void -yyerror(char const* sz_l) -{ - midi_parser_l_g->error (sz_l); -} - - -My_midi_parser* midi_parser_l_g = 0; - -My_midi_parser::My_midi_parser (String filename_str, Sources *sources_l) -{ - filename_str_ = filename_str; - midi_lexer_p_ = new My_midi_lexer (filename_str_,sources_l); - midi_lexer_l_g = midi_lexer_p_; // ugh - - bar_i_ = 1; - - defined_ch_C_ = 0; - fatal_error_i_ = 0; - - mudela_column_l_ = 0; - mudela_score_p_ = new Mudela_score (1, 1, 1); - - - // ugh, belong to Mudela_{score,staff} - track_i_ = 0; - mudela_staff_l_ = 0; - mudela_key_p_ = 0; - mudela_tempo_p_ = 0; - mudela_meter_p_ = 0; - - reset(); -} - -My_midi_parser::~My_midi_parser() -{ - midi_lexer_l_g = 0; // ugh - - delete midi_lexer_p_; - delete mudela_key_p_; - delete mudela_tempo_p_; - delete mudela_meter_p_; - delete mudela_score_p_; -} - -void -My_midi_parser::reset() -{ -// open_mudela_note_l_list_.clear(); - open_mudela_note_l_list_.junk_links(); - - // ugh - delete mudela_key_p_; - mudela_key_p_ = new Mudela_key (0, 0); - // useconds per 4: 250000 === 60 4 per minute - delete mudela_tempo_p_; - mudela_tempo_p_ = new Mudela_tempo (1000000); - delete mudela_meter_p_; - mudela_meter_p_ = new Mudela_meter (4, 2, 24, 8); - - bar_i_ = 1; - mudela_column_l_ = mudela_score_p_->mudela_column_l (0); - - // ugh - copyright_str_ = ""; - track_name_str_ = ""; - instrument_str_ = ""; -} - -void -My_midi_parser::add_score (Mudela_score* mudela_score_p) -{ - assert (mudela_score_p_); - -#if 0 // ugh, already constructed - mudela_score_p_ = mudela_score_p; - if (!mudela_column_l_) - mudela_column_l_ = mudela_score_p_->mudela_column_l (0); -#endif - - mudela_score_p_->mudela_key_l_ = mudela_key_p_; - mudela_score_p_->mudela_meter_l_ = mudela_meter_p_; - mudela_score_p_->mudela_tempo_l_ = mudela_tempo_p_; - bar_i_ = 1; -} - -void -My_midi_parser::error (char const* sz_l) -{ - midi_lexer_l_g->error (sz_l); - - if (fatal_error_i_) - exit (fatal_error_i_); -} - -void -My_midi_parser::forward (int i) -{ - if (!i) - return; - - Duration dur; - dur.durlog_i_ = -100; - dur.set_ticks (i); - Moment mom = at_mom() + Duration_convert::dur2_mom (dur); - - mudela_column_l_ = mudela_score_p_->mudela_column_l (mom); - - if (i) - { - int bars_i = (int) (mom / mudela_meter_p_->bar_mom()); - if (bars_i > bar_i_) - LOGOUT(NORMAL_ver) << '[' << bar_i_ << ']' << flush; - bar_i_ = bars_i; - } -} - -Moment -My_midi_parser::at_mom() -{ - assert (mudela_column_l_); -// return mudela_column_l_ ? mudela_column_l_->at_mom() : 0; - return mudela_column_l_->at_mom(); -} - -void -My_midi_parser::note_begin (int channel_i, int pitch_i, int dyn_i) -{ - // junk dynamics - (void)dyn_i; - - Mudela_note* p = new Mudela_note (mudela_column_l_, channel_i, pitch_i, dyn_i); -// ugh, score doesn't know about last staff yet... -// mudela_score_p_->add_item (p); - mudela_staff_l_->add_item (p); - open_mudela_note_l_list_.bottom().add (p); -} - -void -My_midi_parser::note_end (int channel_i, int pitch_i, int aftertouch_i) -{ - // junk dynamics - (void)aftertouch_i; - - // find - for (PCursor i (open_mudela_note_l_list_); i.ok(); i++) - { - if ( (i->pitch_i_ == pitch_i) && (i->channel_i_ == channel_i)) - { - i->end_column_l_ = mudela_column_l_; - LOGOUT(DEBUG_ver) << "Note: " << pitch_i; - LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_; - LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n"; - i.remove_p(); - return; - } - } - warning (String ("junking note-end event: ") - + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ') - + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' ')); -} - -void -My_midi_parser::note_end_all() -{ - // find - for (PCursor i (open_mudela_note_l_list_); i.ok(); i++) - { - i->end_column_l_ = mudela_column_l_; - i.remove_p(); - // ugh - if (!i.ok()) - break; - } -} - -int -My_midi_parser::parse() -{ - LOGOUT(NORMAL_ver) << "\nParsing..." << flush; - int i = ::yyparse(); - if (!i) - note_end_all(); - return i; -} - -void -My_midi_parser::set_division_4 (int division_4_i) -{ - division_1_i_ = division_4_i * 4; - // ugh - Duration::division_1_i_s = division_1_i_; - if (division_4_i < 0) - warning ("seconds iso metrical time"); -} - -void -My_midi_parser::set_key (int accidentals_i, int minor_i) -{ - delete mudela_key_p_; - mudela_key_p_ = new Mudela_key (accidentals_i, minor_i); -} - -void -My_midi_parser::set_meter (int num_i, int den_i, int clocks_i, int count_32_i) -{ - delete mudela_meter_p_; - mudela_meter_p_ = new Mudela_meter (num_i, den_i, clocks_i, count_32_i); -} - -void -My_midi_parser::set_tempo (int useconds_per_4_i) -{ - delete mudela_tempo_p_; - mudela_tempo_p_ = new Mudela_tempo (useconds_per_4_i); -} -