]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 0.0.36 release/0.0.36
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 25 Feb 1997 20:56:16 +0000 (21:56 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 25 Feb 1997 20:56:16 +0000 (21:56 +0100)
36 files changed:
Documentation/README.pod
Documentation/faq.pod
NEWS
Sources.make
Variables.make
flower/string-convert.cc [new file with mode: 0644]
flower/string-convert.hh [new file with mode: 0644]
hdr/midi-event.hh
hdr/midi-main.hh
hdr/midiitem.hh
hdr/midioutput.hh
hdr/midistream.hh
hdr/midiwalker.hh
hdr/my-midi-parser.hh
hdr/proto.hh
hdr/sourcefile.hh
input/Makefile
input/midi.ly
input/pavane.ly [deleted file]
input/pavane.tex [deleted file]
input/standchen.ly
input/wohltemperirt.ly
src/binary-source-file.cc [new file with mode: 0644]
src/inputfile.cc
src/midi-event.cc
src/midi-lexer.l
src/midi-main.cc
src/midi-parser.y
src/midi-track.cc
src/midiitem.cc
src/midioutput.cc
src/midistream.cc
src/midiwalker.cc
src/my-midi-lexer.cc
src/my-midi-parser.cc
src/sourcefile.cc

index 7126e8edc115a10dd09a0c6082e65bb80bf89bd4..96c5ea4dd5a641570cb3c6f26cc78840b9845622 100644 (file)
@@ -224,30 +224,9 @@ Do:
        configure
        make
 
-You might want to edit Variables.make to tailor the compilation flags.
-why G++ >= 2.7? LilyPond & FlowerLib uses:
-
-=over 5
-
-=item *
-builtin bool
-
-=item *
-typeof
-
-=item *
-operator <?, operator >?
-
-=item *
-the new for-scope
-
-=item   *
-class Rational (libg++)
-
-=item *
-named return values
-
-=back
+You probably want to edit Variables.make to tailor the compilation
+flags. If you're not into debugging C++, then you should go for no
+debugging and C<-O2>
 
 =head1 AUTHORS
 
index b0096fd73a879dcab7ed03e993072b67b20c6e10..d54266f053612be28755fbe1aa96ed15401ca207 100644 (file)
@@ -34,7 +34,6 @@ Q: Why GPL?
 
 A: Yes.
 
-
 Q: Why shouldn't I put all commands (\clef, \meter) inside the music?
 
 A: You should do what you like, but at some time we will enable
@@ -50,3 +49,32 @@ A: If it is reasonable, I'll add XXXX to the TODO list. In general
 finding a cute syntax (such as YYYY) isn't very hard. The complicated
 issue how to adapt the internals to do XXXX. The parser is really  a
 simple front end to the complicated internals. 
+
+Q: Why do I need g++ >= 2.7?
+
+A: By using g++ LilyPond is portable to all platforms which support
+g++ (there are quite a few). Not having to support other compilers
+saves us a *lot* of trouble. LilyPond & FlowerLib uses:
+
+=over 5
+
+=item *
+builtin bool
+
+=item *
+typeof
+
+=item *
+operator <?, operator >?
+
+=item *
+the new for-scope
+
+=item   *
+class Rational (libg++)
+
+=item *
+named return values
+
+=back
+
diff --git a/NEWS b/NEWS
index bd29eda5ceabebc9160092b9171b1df56ae12c08..785c5bf38d15439f9a5641976b41c670ace27037 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,15 @@
+pl 36
+       - Jan's patches:
+       - do MIDI rests cleanly.
+       - lily/m2m: time and tempo fixed for metric timing
+Internal
+       - Midi_tempo
+       - m2m parses more midi stuff (all of bach-wtc); timing??
+       - m2m recognises some commandline options
+Examples
+       - fixed midi.ly
+
+*******
 pl 35
        - Register_group
 Bugfix
@@ -14,6 +26,11 @@ Internal
        - junked Midi_staff, Staff_column children, Midi_walker
        - Midi_output
 
+pl 33-1
+       - m2m parses midi
+Internal
+       - Binary_source_file
+       - Source_file::error_str simplified
 *******
 pl33
 Examples
index b255d37e543ba33d9ab326a59db0692aaf3a7fcd..014621714925a3ee3084789d08c437bb1919efd6 100644 (file)
@@ -34,7 +34,9 @@ hdr=bar.hh barreg.hh beam.hh boxes.hh break.hh clefreg.hh clefitem.hh\
        tstream.hh voice.hh\
        voiceregs.hh voicegroupregs.hh walkregs.hh
 
-mycc=bar.cc barreg.cc beam.cc boxes.cc break.cc calcideal.cc clefreg.cc\
+mycc=bar.cc barreg.cc beam.cc \
+       binary-source-file.cc\
+       boxes.cc break.cc calcideal.cc clefreg.cc\
        clefitem.cc colhpos.cc  commandrequest.cc\
        complexstaff.cc complexwalker.cc \
        debug.cc dimen.cc\
@@ -84,6 +86,7 @@ stablecc=request.cc bar.cc boxes.cc break.cc  \
 # m2m headers
 #
 mym2mhh=\
+ binary-source-file.hh\
  midi-event.hh\
  midi-main.hh\
  midi-score.hh\
@@ -96,6 +99,7 @@ mym2mhh=\
 # m2m source
 #
 mym2mcc=\
+ binary-source-file.cc\
  midi-event.cc\
  midi-main.cc\
  midi-score.cc\
index ea71398c058979c79ad34f01f0707c1a6577748d..886b6eb256a6267a4be6dd82c1e63f41e80112d0 100644 (file)
@@ -3,7 +3,7 @@
 # version info
 MAJVER=0
 MINVER=0
-PATCHLEVEL=35
+PATCHLEVEL=36
 
 
 
@@ -19,7 +19,7 @@ DEBUGFLAG=-g
 # CXX=g++
 
 # turn off -pipe if linker doesn't support it
-EXTRACXXFLAGS=-pipe -Wall -W   -Wmissing-prototypes -DSTRING_UTILS_INLINED
+EXTRACXXFLAGS=-pipe -Wall -W   -Wmissing-prototypes -DSTRING_UTILS_INLINED -O
 
 #
 # -lefence = ElectricFence.
diff --git a/flower/string-convert.cc b/flower/string-convert.cc
new file mode 100644 (file)
index 0000000..ccd62a0
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+  PROJECT: FlowerSoft C++ library
+  FILE   : string-convert.cc
+
+--*/
+
+
+#include <assert.h>
+#include "string.hh"
+
+String
+String_convert::bin2hex_str( String bin_str )
+{
+    String str;
+    Byte const* byte_c_l = bin_str.byte_c_l();
+    for ( int i = 0; i < bin_str.length_i(); i++ ) {
+       str += (char)nibble2hex_byte( *byte_c_l >> 4 );
+       str += (char)nibble2hex_byte( *byte_c_l++ );
+    }
+    return str;
+}
+
+int
+String_convert::bin2_i( String bin_str )
+{
+    assert( bin_str.length_i() <= 4 );
+
+    int result_i = 0;
+    for ( int i = 0; i < bin_str.length_i(); i++ ) {
+       result_i <<= 8;
+       result_i += (Byte)bin_str[ i ];
+    }
+    return result_i;
+}
+
+// breendet imp from String
+int
+String_convert::dec2_i( String dec_str )
+{
+    if ( !dec_str.length_i() )
+       return 0;
+
+    long l = 0;
+    int conv = sscanf( dec_str.ch_c_l(), "%ld", &l );
+    assert( conv );
+
+    return (int)l;
+}
+
+// breendet imp from String
+double
+String_convert::dec2_f( String dec_str )
+{
+    if ( !dec_str.length_i() )
+       return 0;
+    double d = 0;
+    int conv = sscanf( dec_str.ch_c_l(), "%lf", &d );
+    assert( conv );
+    return d;
+}
+
+int
+String_convert::hex2bin_i( String hex_str, String& bin_str_r )
+{
+    if ( hex_str.length_i() % 2 )
+        hex_str = "0" + hex_str;
+
+    bin_str_r = "";
+    Byte const* byte_c_l= hex_str.byte_c_l();
+    int i = 0;
+    while ( i < hex_str.length_i() ) {   
+        int high_i = hex2nibble_i( *byte_c_l++ );
+        int low_i = hex2nibble_i( *byte_c_l++ );
+        if ( high_i < 0 || low_i < 0 )
+            return 1; // illegal char
+        bin_str_r += String( (char)( high_i << 4 | low_i ), 1 );
+        i += 2;
+    }
+    return 0;
+}
+
+String 
+String_convert::hex2bin_str( String hex_str )
+{
+    String str;
+//  silly, asserts should alway be "on"!
+//    assert( !hex2bin_i( hex_str, str ) );
+    int error_i = hex2bin_i( hex_str, str );
+    assert( !error_i );
+    return str;
+}
+
+int 
+String_convert::hex2nibble_i( Byte byte )
+{
+    if ( byte >= '0' && byte <= '9' )
+        return byte - '0';
+    if ( byte >= 'A' && byte <= 'F' )
+        return byte - 'A' + 10;
+    if ( byte >= 'a' && byte <= 'f')
+        return byte - 'a' + 10;
+    return -1;
+}
+    
+String 
+String_convert::i2dec_str( int i, int length_i, char ch )
+{
+    char fill_ch = ch;
+    if ( fill_ch)
+        fill_ch = '0';
+
+    // ugh
+    String dec_str( i );
+    
+    // ugh
+    return String( fill_ch, length_i - dec_str.length_i() ) + dec_str;
+}
+
+String 
+String_convert::i2hex_str( int i, int length_i, char ch )
+{
+    String str;
+    if ( !i )
+       str = "0";
+    while ( i ) {
+       str = ( i % 16 )["0123456789abcdef"] + str;
+       i /= 16;
+    }
+    if ( str.length_i() < length_i )
+       str = String( ch, length_i - str.length_i() ) + str;
+    return str;
+}
+
+Byte
+String_convert::nibble2hex_byte( Byte byte )
+{
+    if ( ( byte & 0x0f ) <= 9 )
+       return ( byte & 0x0f ) + '0';
+    else
+       return ( byte & 0x0f ) - 10 + 'a';
+}
diff --git a/flower/string-convert.hh b/flower/string-convert.hh
new file mode 100644 (file)
index 0000000..b96af44
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+  PROJECT: FlowerSoft C++ library
+  FILE   : string-convert.hh
+
+*/
+
+#ifndef STRING_CONVERT_HH
+#define STRING_CONVERT_HH
+
+///
+#define functor class // :-)
+/**
+       The functor String_convert handles all conversions to/from String (some 
+       time, anyway).
+       The class is quite empty from data view.
+  */
+functor String_convert {
+       static int hex2bin_i( String hex_str, String& bin_str_r );
+       static int hex2nibble_i( Byte byte );
+       static Byte nibble2hex_byte( Byte byte );
+public:
+       static String bin2dec_str( String dec_str );
+       static String bin2hex_str( String bin_str );
+       static String dec2bin_str( String str );
+       static int bin2_i( String str );
+       static int dec2_i( String dec_str );
+       static double dec2_f( String dec_str );
+       static int hex2int_i( String str );
+       static String hex2bin_str( String str );
+       static String i2hex_str( int i, int length_i, char ch );
+       static String i2dec_str( int i, int length_i, char ch );
+};
+
+#endif // __STRING_CONVERT_HH //
index c9ab0336ea38e419340fe865f15f2c5a0ef71d40..a566dc50f730b275fbef15819c34d24180e31fa9 100644 (file)
@@ -6,13 +6,72 @@
 #ifndef MIDI_EVENT_HH
 #define MIDI_EVENT_HH
 
+
+// should these:
+// * be Midi_items
+// * be Voice_elements/requests
+// * get a name-change
+// ?
+
 /// (midi_event)
 class Midi_event {
 public:
        Midi_event();
-       ~Midi_event();
+       virtual ~Midi_event();
+       
+       String mudela_str();
+
+protected:
+       String mudela_str_;
+
+private:
+};
+
+class Midi_key : public Midi_event {
+public:
+       Midi_key( int accidentals_i, int minor );
+       virtual ~Midi_key();
+
+       String notename_str( int pitch_i );
+
+private:
+       int accidentals_i_;
+       int minor_i_;
+       int key_i_;
+};
+
+class Midi_note : public Midi_event {
+public:
+//     Midi_note( Midi_key* midi_key_l, Midi_tempo* midi_tempo_l, Midi_time* midi_time_l, int pitch_i, Real duration_f );
+       Midi_note( Midi_key* midi_key_l, Midi_time* midi_time_l, int clocks_per_whole_i, int pitch_i, Real duration_f );
+       virtual ~Midi_note();
+
+};
+
+class Midi_tempo : public Midi_event {
+public:
+       Midi_tempo( int useconds_per_4_i );
+       virtual ~Midi_tempo();
+
+       int get_tempo_i( Moment moment );
+
+private:
+       int useconds_per_4_i_;
+       Real seconds_per_1_f_;
+};
+
+class Midi_time : public Midi_event {
+public:
+       Midi_time( int num_i, int den_i, int clocks_i, int count_32_i );
+       virtual ~Midi_time();
+
+       String duration_str( int usecond24th_per_clock_i, Real delta_time_f );
+       int whole_clocks_i();
 
 private:
+       int whole_clocks_i_;
+       int num_i_;
+       int den_i_;
 };
 
 #endif // MIDI_EVENT_HH
index 2812bb82b4db9b40caaf570874db9649fb5cc8ee..4eb86c27d2d0c58797f1fddacaa25d519190d64c 100644 (file)
@@ -2,8 +2,22 @@
 // midi-main.hh -- global (sic) m2m stuff 
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
 #include "string.hh"
+
+#define monitor_p_g &cout
+enum Verbose { QUIET_ver, BRIEF_ver, NORMAL_ver, VERBOSE_ver, DEBUG_ver };
+extern Verbose level_ver;
+#ifdef NPRINT
+#define dtor if ( 0 ) *monitor_p_g
+#define mtor if ( 0 ) *monitor_p_g
+#else
+#define dtor if ( level_ver >= DEBUG_ver ) *monitor_p_g
+#define vtor if ( level_ver >= VERBOSE_ver ) *monitor_p_g
+#define mtor if ( level_ver >= NORMAL_ver ) *monitor_p_g
+#define btor if ( level_ver >= BRIEF_ver ) *monitor_p_g
+#define qtor if ( level_ver >= QUIET_ver ) *monitor_p_g
+#endif
+
 extern Source* source_l_g;
 void message( String message_str, char const* context_ch_c_l );
 void warning( String message_str, char const* context_ch_c_l );
index d30e6448fc6c6cfc339d6cc05caada003e6a3e9a..486637c367a56c8f62df81264635bf0ed1698214 100644 (file)
@@ -23,11 +23,10 @@ struct Midi_note : public Midi_item {
     /**
       Generate a note-event on a channel pitch.
 
-      @param #melreq_l# the pitch. If null, then output a silent C
-      #on_b# turn on?
+      @param #melreq_l# is the pitch. 
      */
     Midi_note( Melodic_req* melreq_l, int channel_i, bool on_b );
-       
+
     virtual String str();
 
     int channel_i_;
@@ -60,7 +59,16 @@ private:
 
 struct Midi_header : Midi_chunk {
     /* *************** */
-    Midi_header( int format_i, int tracks_i, int tempo_i );
+    Midi_header( int format_i, int tracks_i, int clocks_per_4_i );
+};
+
+struct Midi_tempo : Midi_item {
+    /* *************** */
+    Midi_tempo( int tempo_i );
+
+    virtual String str();
+
+    int tempo_i_;
 };
 
 struct Midi_track : Midi_chunk {
index fed37feffa107f19352186cef1c74a5e1daa658b..34d7f7b039b1128291ba27bdae3da6640aac89b7 100644 (file)
@@ -15,5 +15,7 @@ struct Midi_output {
     Midi_stream*    midi_stream_l_;
     Midi_output(Score* score_l, Midi_def* );
     void do_staff(Staff*st_l, int count);
+
+    Midi_def* midi_l_;
 };
 #endif // MIDIOUTPUT_HH
index 34e9c9b523b30c8773438d6e0a6d662cdefd1123..769cd23250b4bdfe51aaaf59cdcc608ccbc0e9fb 100644 (file)
 struct Midi_stream {
     ostream* os_p_;
     String filename_str_;
-    int tempo_i_;
+    int clocks_per_4_i_;
     int tracks_i_;
     
-    Midi_stream( String filename_str, int tracks_i, int tempo_i );
+    Midi_stream( String filename_str, int tracks_i, int clocks_per_4_i_ );
     ~Midi_stream();
 
     Midi_stream& operator <<( String str );
index 3673ae080b5bca9bfcc374df626aa195c9911be2..839ba11a7f893848d31e68fe0b25664ce49112ec 100644 (file)
@@ -26,6 +26,8 @@ class Midi_walker : public PCursor<Staff_column*> {
 
     /* *************** */
     void do_stop_notes(Moment);
+    
+    void output_event(Midi_item&, Moment);
 public:
     
     Midi_walker(Staff*, Midi_track*);
index 68b238a795039d37ee08c93739b5ee410b7cf818..fd7e088654495c0f975c233288251ba9a896a864 100644 (file)
@@ -9,7 +9,6 @@
 #include "proto.hh"
 #include "varray.hh"
 #include "string.hh"
-// #include "plist.hh"
 
 int yyparse();
 
@@ -21,9 +20,29 @@ public:
        void add_score( Midi_score* midi_score_p );
        void error( char const* sz_l );
        int parse();
+       void forward( Real f );
+       void note_begin( int channel_i, int pitch_i, int dyn_i );
+       Midi_event* note_end_midi_event_p( int channel_i, int pitch_i, int dyn_i );
+       int output( String filename_str );
+       void set_division( int clocks_per_4_i );
+       void set_key( int accidentals_i, int minor_i );
+       void set_tempo( int useconds_i );
+       void set_time( int num_i, int den_i, int clocks_i, int count_32_i );
 
 private:
+       Real now_f_;
+       Real step_f_;
+
+       static int const CHANNELS_i = 16;
+       static int const PITCHES_i = 128;
+       Real running_f_f_a_[ CHANNELS_i ][ PITCHES_i ];
+
        Array<Midi_score*> midi_score_p_array_;
+       int clocks_per_whole_i_;
+       Midi_key* midi_key_p_;
+       Midi_tempo* midi_tempo_p_;
+       Midi_time* midi_time_p_;
+
        char const* defined_ch_c_l_;
        int fatal_error_i_;
        My_midi_lexer* midi_lexer_p_;
index 8146e81a6318ad0dd3925e6df2ad9aa4b7bfff54..0f2a007c7929a7668895156560155df8c0e50c9a 100644 (file)
@@ -66,12 +66,17 @@ struct Meter;
 struct Meter_register;
 struct Midi_def;
 struct Midi_duration;
+struct Midi_event;
 struct Midi_header;
 struct Midi_item;
+struct Midi_key;
+struct Midi_note;
 struct Midi_output;
 struct Midi_pitch;
 struct Midi_staff;
 struct Midi_stream;
+struct Midi_tempo;
+struct Midi_time;
 struct Midi_track;
 struct Midi_walker;
 struct Mixed_qp;
index 36c7aaa575590b64ccdc76ec65df622c918ddac0..251efd517e91ea126f611df5cc5176f5d1743ccb 100644 (file)
@@ -13,15 +13,18 @@ public:
     /**
       @return path to opened file.
      */
-    Source_file( String &filename_str );
-    ~Source_file();
+    // jcn: ugh! filename gets changed!, why?
+    Source_file( String& filename_str );
+    virtual ~Source_file();
+
     char const* ch_c_l();
-    String error_str( char const* pos_ch_c_l );
+    virtual String error_str( char const* pos_ch_c_l );
     istream* istream_l();
     bool in_b( char const* pos_ch_c_l );
-    int line_i( char const* pos_ch_c_l );
+    off_t length_off();
+    virtual int line_i( char const* pos_ch_c_l );
     String name_str();
-    String file_line_no_str(const char *ch_c_l );
+    String file_line_no_str( char const* ch_c_l );
 
 private:
     void close();
index 5e7ff852495c8f35250a72c5814c284722528b5b..92dfaf11c5ed391866ad03e27046627a01b9e58d 100644 (file)
@@ -1,12 +1,12 @@
 default: ;
 
-DISTFILES=Makefile  kortjakje.ly pavane.ly  maartje.ly\
+DISTFILES=Makefile  kortjakje.ly maartje.ly\
        cadenza.ly scales.ly standchen.ly twinkle.ly\
        wohltemperirt.ly\
        error.ly midi.ly plet.ly\
        martien.ly mlalt.ly mlvio1.ly mlvio2.ly mlcello.ly\
        coriolan-alto.ly rhythm.ly \
-       standchen.tex pavane.tex scsii-menuetto.tex scsii-menuetto.ly\
+       standchen.tex  scsii-menuetto.tex scsii-menuetto.ly\
        martien.tex
 
 
index bdb0a48d3896af3cf4d4be6d5dffd9b35ec892e5..38e5073778c2d9438fb495a3df4b63e05f3211cb 100644 (file)
@@ -30,11 +30,11 @@ bass_staf = staff {
 score {
        staff { mstaf }
        staff { bass_staf }
+       commands {
+               meter { 2 * 4}
+       }
        midi {
                tempo 4:120
        }
-       commands {
-               meter { 2 * 4 }
-       }
 }
 
diff --git a/input/pavane.ly b/input/pavane.ly
deleted file mode 100644 (file)
index bb7fd64..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-% Pavane pour une Infante d\'efunte
-% by Maurice Ravel
-%
-% Ravel deceased in 1937, so copyright on the music will pass in 2008.
-%
-% The purpose of this file is to demonstrate features of LilyPond; 
-% I hope this citation isn't beyond the bounds of "fairness"
-%
-%
-% (there is an accompanying LaTeX file, pavane.tex)
-%
-
-horn =
-music {
-       $
-       \octave { ' }
-       \key{  fis cis }
-       \duration { 8 }
-
-% 1
-       d2(( [)d e cis `b]              |       
-       `a4 [`b cis] [cis `b] )`b4      |
-       fis2(( [)fis g e d]             |
-       cis4 [d e(] [)e fis d cis]      |
-       `b4 [cis d(] [)d e cis `b]      |
-       )cis2 r2^"c\'edez"              |
-       r4 fis2 fis4                    |
-       fis2^"en mesure" (()[fis e a fis]|
-       fis4-- e4-- d4-- )e4--          |
-       `b2()[`b^"un peu retenu" `a( d cis]|
-% 11
-       )`b [`fis^"en \'elargissant"-- `a-- `b--] cis4-- `b4--|
-       `fis2 r2                        |
-       cis4^"1er mouvement"( d4^"tr\`es lontain" ()[d cis d e]
-       \octave {  }
-       |       a4 )gis2.       |
-       a4 (b4()[b a b 'cis]    |
-       fis4 e4 )cis2           |
-       e4( fis4 () [fis e fis gis]     |
-       cis4 `b4())`b8 r8 r4^"tr\`es soutenu"   |
-
- \meter {2 *4} r4 r4   |
- \meter {4 *4}
-       'cis4_"\dyn ppp"( 'd4 () ['d 'cis 'd 'e] |
-       a4 )gis2.       |
-       a4 (b4()[b a b 'cis]    |
-       fis4 e4 )cis2   |
-       e4_"\dyn pp"( fis4()[fis e fis gis]     |
-       cis4_"\dyn mf" `b4())`b8 r8 r4^"un peu plus lent"       |
-       r1      |
-       r2 r4 r4 %^\fermata
-%% cut 'n paste.
-       \octave { ' }
-       | d2^"Reprenez le mouvement"( ([)d e cis `b]    |
-       `a4 [`b cis] [cis `b] )`b4      |
-       fis2(( [)fis g e d]     |
-       cis4 [d e(] [)e fis d cis]      |
-       `b4 [cis d(] [)d e cis `b]      |
-       )cis2 r2^"c\'edez"      |
-       r4 fis2 fis4    |
-       fis2(^"en mesure"()[fis e a fis]        |
-       fis4-- e4-- d4-- e4--   |
-       `b2() [`b `a-. d-. cis-.]       |
-       )`b-. [`fis^"large" `a `b] cis4 `b4     `fis2 r2        |
-
-       %% mark B
-       r1^"1er mouvement"      
-       \duration {8}
-       | r2 [c-.( e-. c-. )`a-. ]      
-       \octave{}       |
-       |        [c e a ]2/3  b4-> () [b c-- e-- a--]   |
-       b4. b8()g2      |
-       r1      |
-       r2              [f a f d] 
-       |  [f a 'c]2/3  'e4-^ () ['e f-> a-> 'c->]      |
-       'e4._"sf" 'e8()'c4 r4 |
-       r1      |
-       \meter {2 *4}
-       r4 r4-\fermata
-       \meter {4 *4}
-
-       \octave { ' }
-       |d2(( [)d e cis `b]     |
-       `a4 [`b cis] [cis `b] )`b4      |
-       fis2( ([)fis g e d]     |
-       cis4 [d e(] [)e fis d cis]      |
-       `b4 [cis d(] [)d e cis `b]      |
-       )cis2 r2^"c\'edez"      |
-       r4 fis2 fis4    |
-       fis2(()[fis e a fis]    |
-       fis4-- e4-- d4-- e4--   
-       \octave{ }      
-       | b2()[b a 'd 'cis]     |
-       )b [fis a b ] 'cis4 b4  |
-       fis2 r2 |
-       r1-\fermata     
-       $
-}
-score {
-       staff { melodic music { horn }
-       }
-       paper {
-               output "pavane.out"
-               unitspace 1.5 cm
-               geometric 1.4
-               width 12cm
-       }
-       commands  {
-               meter {4 *4}
-               skip {39*1}
-               bar "|:"
-               skip {10*1}
-               bar ":|"
-               skip {13*1}
-               bar "||"
-       }
-       midi { tempo 4:70 }
-}
diff --git a/input/pavane.tex b/input/pavane.tex
deleted file mode 100644 (file)
index 69a1362..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-\documentclass{article}         %UGH
-\usepackage{a4}
-\begin{document}
-\input lilyponddefs
-\input titledefs
-\def\interscoreline{\vskip12pt}
-\title{Pavane pour une Infante d\'efunte}
-\composer{Maurice Ravel}
-\instrument{Cor en Fa}
-\maketit
-\input pavane.out
-\end{document}
index 4d104f84ee7c378d64a6c79b8da1c5374496f6fb..41abb47413138c3815fffcb1ecbb781d83913b1c 100644 (file)
@@ -487,6 +487,6 @@ score {
                output "standchen.out"
        }
        midi {
-               tempo 4:50
+               tempo 4:80
        }
 }
index 7d615a4d1bfdeae4f2515eb01d1f5a9f83bf6d98..32de885acf3508014610420c8d538980c678bc84 100644 (file)
@@ -69,7 +69,7 @@ score {
        }
        paper {}
        midi {
-               tempo 4:80
+               tempo 4:90
        }
 }
 
diff --git a/src/binary-source-file.cc b/src/binary-source-file.cc
new file mode 100644 (file)
index 0000000..8335a13
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// binary-source-file.cc
+//
+
+#include <limits.h>            // INT_MAX
+#include <assert.h>
+
+#include "proto.hh"
+#include "plist.hh"
+#include "string.hh"
+#include "debug.hh"
+#include "sourcefile.hh"
+#include "binary-source-file.hh"
+
+Binary_source_file::Binary_source_file( String& filename_str )
+       : Source_file( filename_str )
+{
+}
+
+Binary_source_file::~Binary_source_file()
+{
+}
+
+String
+Binary_source_file::error_str( char const* pos_ch_c_l )
+{
+    assert( this );
+    if ( !in_b( pos_ch_c_l ) )
+       return "";
+
+    char const* begin_ch_c_l = pos_ch_c_l - 8 >? ch_c_l();
+    char const* end_ch_c_l = pos_ch_c_l + 7 <? ch_c_l() + length_off();
+
+    String pre_str( (Byte const*)begin_ch_c_l, pos_ch_c_l - begin_ch_c_l );
+    pre_str = StringConversion::bin2hex_str( pre_str );
+    for ( int i = 2; i < pre_str.length_i(); i += 3 )
+       pre_str = pre_str.left( i ) + " " + pre_str.mid( i + 1, INT_MAX );
+    String post_str( (Byte const*)pos_ch_c_l, end_ch_c_l - pos_ch_c_l );
+    post_str = StringConversion::bin2hex_str( post_str );
+    for ( int i = 2; i < post_str.length_i(); i += 3 )
+       post_str = post_str.left( i ) + " " + post_str.mid( i + 1, INT_MAX );
+
+    String str = pre_str
+       + String( '\n' )
+       + String( ' ', pre_str.length_i() + 1 ) 
+       + post_str;
+    return str;
+}
+
+int
+Binary_source_file::line_i( char const* pos_ch_c_l )
+{
+    if ( !in_b( pos_ch_c_l ) )
+       return 0;
+
+    return pos_ch_c_l - ch_c_l();
+}
+
index 7faefd2c9bd8cc543d9696b0596731940bc3f1a9..2245c8dbe0136426257bf3f5419fbc6b2a57ea69 100644 (file)
@@ -13,6 +13,7 @@
 #include "inputfile.hh"
 #include "debug.hh"
 #include "sourcefile.hh"
+#include "binary-source-file.hh"
 #include "source.hh"
 
 Input_file::Input_file(String s)
@@ -26,7 +27,12 @@ Input_file::Input_file(String s)
                sourcefile_l_ = 0;
        }
        else {
-               Source_file* sourcefile_p = new Source_file( pf );
+               Source_file* sourcefile_p = 0;
+               // ugh, very dirty, need to go away
+               if ( ( pf.right( 3 ).lower() == "mid" ) || ( pf.right( 4 ).lower() == "midi" ) )
+                   sourcefile_p = new Binary_source_file( pf );
+               else
+                   sourcefile_p = new Source_file( pf );
                source_l_g->add( sourcefile_p );
                sourcefile_l_ = sourcefile_p;
                is = sourcefile_l_->istream_l();
index 2e295a5b13a94b1b0faf6781048b18da8e6fd01a..850379271c376b5575370154384d70d44b57e80c 100644 (file)
@@ -3,7 +3,16 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include "proto.hh"
+
+#include "plist.hh"      // all for midi-main.hh
+#include "string.hh"
+#include "source.hh"
+#include "sourcefile.hh"
+#include "midi-main.hh"  // *tors
+
+#include "moment.hh"
 #include "midi-event.hh"
 
 Midi_event::Midi_event()
@@ -14,3 +23,210 @@ Midi_event::~Midi_event()
 {
 }
 
+String
+Midi_event::mudela_str()
+{
+       return mudela_str_;
+}
+
+Midi_key::Midi_key( int accidentals_i, int minor_i )
+{
+       accidentals_i_ = accidentals_i;
+       minor_i_ = minor_i;
+       if ( !minor_i_ )
+               key_i_ = ( ( accidentals_i % 7 )[ "cgdaebf" ] - 'a' + 2 ) % 7;
+       else
+               key_i_ = ( ( -accidentals_i % 7 )[ "fbeadg" ] - 'a' + 2 ) % 7;
+       mudela_str_ = String( "\\key\\" );
+       if ( !minor_i_ ) 
+               mudela_str_ += String( (char)( key_i_ - 2 + 'A'  ) );
+       else
+               mudela_str_ += String( (char)( key_i_ - 2 + 'a'  ) );
+}
+
+String
+Midi_key::notename_str( int pitch_i )
+{
+       // this may seem very smart,
+       // but it-s only an excuse not to read a notename table
+
+       // major scale: do-do
+       // minor scale: la-la ( = + 5 )
+       static int notename_i_a[ 12 ] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
+       int notename_i = notename_i_a[ ( minor_i_ * 5 + pitch_i ) % 12 ];
+       
+       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 ( accidentals_i_ < 0 ) {
+               accidental_i = - accidental_i;
+               notename_i = ( notename_i + 1 ) % 7;
+       }
+
+       String notename_str = (char)( ( ( notename_i + key_i_ - 2 ) % 7 ) + 'a' );
+       while ( accidental_i-- > 0 )
+               notename_str += "is";
+       accidental_i++;
+       while ( accidental_i++ < 0 )
+               if ( ( notename_str == "a" ) || ( notename_str == "e" ) )
+                       notename_str += "s";
+               else
+                       notename_str += "es";
+       accidental_i--;
+       return notename_str;
+}
+
+Midi_key::~Midi_key()
+{
+}
+
+Midi_note::Midi_note( Midi_key* midi_key_l, Midi_time* midi_time_l, int clocks_per_whole_i, int pitch_i, Real delta_time_f )
+{
+       mudela_str_ = midi_key_l->notename_str( pitch_i );
+       mudela_str_ += midi_time_l->duration_str( clocks_per_whole_i, delta_time_f );
+}
+
+Midi_note::~Midi_note()
+{
+}
+
+Midi_tempo::Midi_tempo( int useconds_per_4_i )
+{
+       useconds_per_4_i_ = useconds_per_4_i;
+       seconds_per_1_f_ = (Real)useconds_per_4_i_ * 4 / 1e6;
+       mudela_str_ = "\\Tempo: ";
+       mudela_str_ += String( useconds_per_4_i_ );
+       mudela_str_ += String( ": " ) 
+               + String( get_tempo_i( Moment( 1, 4 ) ) )
+               + String( " 4 per minute" );
+}
+
+Midi_tempo::~Midi_tempo()
+{
+}
+
+int
+Midi_tempo::get_tempo_i( Moment moment )
+{
+       return Moment( 60 ) / moment / Moment( seconds_per_1_f_ );
+}
+
+Midi_time::Midi_time( int num_i, int den_i, int clocks_i, int count_32_i )
+{
+//     we should warn, at least!
+//     assert( count_32_i == 8 );
+       if ( count_32_i != 8 )
+               warning( String( "#32 in quarter: " ) + String( count_32_i ), 0 );
+       num_i_ = num_i;
+       den_i_ = 2 << den_i;
+       // huh?, see midiitem.cc; reasonably for fugue1.midi
+//     whole_clocks_i_ = clocks_i * 4 * 10; 
+       whole_clocks_i_ = clocks_i * 4; 
+//     whole_clocks_i_ = clocks_i; 
+       mudela_str_ = "\\Time: ";
+       mudela_str_ += String( num_i_ ) + "/" + String( den_i_ )
+               + ", " + String( whole_clocks_i_ )
+               + ": " + String( count_32_i );
+}
+
+Midi_time::~Midi_time()
+{
+}
+
+String
+Midi_time::duration_str( int clocks_per_whole_i, Real delta_time_f )
+{
+       dtor << "(" << delta_time_f;
+       String str;
+
+       Moment delta_time_moment = 1.0;
+       if ( delta_time_f ) {
+               // 288/96*.25 = .75
+               // 96/96*.25 = .25
+               // 24/96*.25 = 0.0625
+//             delta_time_moment = Moment( delta_time_f ) / Moment( whole_clocks_i() );
+               if ( clocks_per_whole_i > 0 )
+                       delta_time_moment = Moment( delta_time_f ) / Moment( clocks_per_whole_i );
+               else 
+                       delta_time_moment = Moment( -clocks_per_whole_i ) / Moment( delta_time_f );
+       }               
+
+       dtor << ", " << (Real)delta_time_moment << "): ";
+
+       static Real sync_f = 1;
+       delta_time_moment = delta_time_moment / sync_f;
+
+       double dummy_f;
+       if ( ( sync_f == 1 ) 
+               && ( abs( modf( (Real)delta_time_moment / ( (Real)1 / 64 / 3 ), &dummy_f ) ) ) > 1e-6 ) {
+               sync_f = (Real)delta_time_moment / 0.125;
+               delta_time_moment = (Real)delta_time_moment / sync_f;
+               mtor << "\nsyncing: " << sync_f << ", "
+//                     << (Real)sync_f / usecond24th_per_clock_i << endl;
+                       << (Real)whole_clocks_i() << endl;
+       }
+
+       static bool must_resync_bo = false;
+       if ( ( (Real)delta_time_moment / 0.125 > 16 )
+               || ( (Real)delta_time_moment / 0.125 < ( (Real)1 / 16 ) ) ) 
+               must_resync_bo = true;
+       
+       if ( must_resync_bo ) {
+               must_resync_bo = false;
+               delta_time_moment = delta_time_moment * sync_f;
+               sync_f = (Real)delta_time_moment / 0.125;
+               delta_time_moment = (Real)delta_time_moment / sync_f;
+               mtor << "\nresyncing: " << sync_f << ", "
+//                     << (Real)sync_f / usecond24th_per_clock_i << endl;
+                       << (Real)whole_clocks_i() << endl;
+       }
+
+       if ( !delta_time_moment ) 
+               return "0";
+
+       // output of modf: double 
+       double duration_f = 0;
+       Real rest_f = modf( ( Moment( 1 ) / delta_time_moment ), &duration_f );
+       int dots_i = 0;
+       int plet_type_i = 0;
+       if ( rest_f ) {
+               // output of modf: double 
+               double dots_f = 0;
+               Real dots_rest_f = modf( rest_f * 3, &dots_f );
+               if ( !dots_rest_f )
+                       dots_i = (int)rint( dots_f );
+               else if ( abs( dots_rest_f - rint( dots_rest_f ) ) < 1e-8 )
+                       dots_i = (int)rint( dots_rest_f );
+               // try 3plet
+               else if ( !modf( (Real)3 * delta_time_moment / 2, &duration_f ) )
+                       plet_type_i = 3;
+               // try 6plet
+               else if ( !modf( (Real)6 * delta_time_moment / 2, &duration_f ) )
+                       plet_type_i = 6;
+               else {
+//                     str += String( "\n*" ) + String( (int)( 1 / rest_f ) );
+                       str += String( "\n*" ) + String( rest_f );
+                       must_resync_bo = true;
+               }
+       }
+
+       if ( dots_i ) {
+               for ( int i = dots_i; i ; i-- )
+                       delta_time_moment *= (Real)2 / 3;
+               modf( ( Moment( 1 ) / delta_time_moment ), &duration_f );
+       }
+
+       str += String( (int)( duration_f ) );
+       if ( dots_i )
+               str += String( '.', dots_i );
+       if ( plet_type_i )
+               str += String( "/" ) + String( plet_type_i );
+
+       return str;
+}
+
+int
+Midi_time::whole_clocks_i()
+{
+       return whole_clocks_i_;
+}
+
index d95696dbb5a10c24237404e56f3bac0241e53039..dfbafd5fbf6eb688de5a0770a13953404a59183c 100644 (file)
@@ -1,17 +1,14 @@
 %{
 // midi-lexer.l
 
-#include <stdio.h>
+//#include <stdio.h>
 
 #include "string.hh"
 #include "proto.hh"
+#include "midi-main.hh"
 #include "my-midi-lexer.hh"
 #include "midi-parser.hh"
 
-#ifndef MIDI_LEX_DEBUG
-#define puts( x )
-#endif
-
 %}
 
 %option c++
@@ -40,10 +37,17 @@ VARINT              {INT7_8SET}{0,3}{INT7_8UNSET}
 HEADER         MThd
 TRACK          MTrk
 
-RUNNING_STATUS [\x30-\x4f]
+XRUNNING_STATUS        [\x30-\x4f]
+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]
@@ -69,7 +73,7 @@ SSME          [\0x7f][\x03]
 %%
 
 {HEADER}/{INT32}       { // using /{INT32}; longer match than {INT32}
-       puts( "lex: header" );
+       dtor << "lex: header" << endl;
        yy_push_state( int16 ); 
        yy_push_state( int16 ); 
        yy_push_state( int16 ); 
@@ -78,14 +82,18 @@ SSME                [\0x7f][\x03]
 }
 
 {TRACK}/{INT32}        { // using /{INT32}; longer match than {INT32}
-       puts( "lex: track" );
+       dtor << "lex: track" << endl;
        yy_push_state( track ); 
        yy_push_state( int32 ); 
        return TRACK;
 }
-
+{INT8} {
+       error( String( "top level: illegal byte: " )
+               + StringConversion::bin2hex_str( String( *YYText() ) ) );
+       exit( 1 );
+}
 <int32>{INT32} {
-       puts( "lex: int32" );
+       dtor << "lex: int32" << endl;
        assert( YYLeng() == 4 );
        String str( (Byte const*)YYText(), YYLeng() );
        yylval.i = StringConversion::bin2int_i( str );
@@ -93,7 +101,7 @@ SSME         [\0x7f][\x03]
        return INT32;
 }
 <int16>{INT16} {
-       puts( "lex: int16" );
+       dtor << "lex: int16" << endl;
        assert( YYLeng() == 2 );
        String str( (Byte const*)YYText(), YYLeng() );
        yylval.i = StringConversion::bin2int_i( str );
@@ -101,7 +109,7 @@ SSME                [\0x7f][\x03]
        return INT16;
 }
 <int8>{INT8}   {
-       puts( "lex: int8" );
+       dtor << "lex: int8" << endl;
        assert( YYLeng() == 1 );
 //     yylval.byte = *(Byte*)YYText();
        yylval.i = *(Byte*)YYText();
@@ -110,80 +118,189 @@ SSME             [\0x7f][\x03]
 }
 
 <track>{VARINT} {
-       puts( "lex: track: varint" );
        String str( (Byte const*)YYText(), YYLeng() );
        yylval.i = My_midi_lexer::varint2int_i( str );
+       dtor << String( "lex: track: varint(" ) 
+               + String( yylval.i ) + "): "
+               + StringConversion::bin2hex_str( str ) << endl;
        yy_push_state( event ); 
        return VARINT;
 }
-
+<track>{INT8}  {
+       error( String( "track: illegal byte: " ) 
+               + StringConversion::bin2hex_str( String( *YYText() ) ) );
+       exit( 1 );
+}
 <event>{RUNNING_STATUS}        {
-       yylval.byte = *(Byte*)YYText();
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       dtor << String ( "lex: running status: " ) + String( yylval.i ) << endl;
        yy_pop_state(); 
+//     yy_push_state( int8 );
        yy_push_state( int8 );
        return RUNNING_STATUS;
 }
+<event>{DATA_ENTRY}    {
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       dtor << String ( "lex: undefined data entry: " ) + String( yylval.i ) << endl;
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       return DATA_ENTRY;
+}
+<event>{ALL_NOTES_OFF} {
+       dtor << "lex: all note off" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       dtor << String ( "lex: all notes off: " ) + String( yylval.i ) << endl;
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       yy_push_state( int8 );
+       return ALL_NOTES_OFF;
+}
 <event>{NOTE_OFF}      {
-       puts( "lex: note off" );
-       yylval.byte = *(Byte*)YYText();
+       dtor << "lex: note off" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
        yy_pop_state(); 
        yy_push_state( int8 );
        yy_push_state( int8 );
        return NOTE_OFF;
 }
 <event>{NOTE_ON}       {
-       puts( "lex: note on" );
-       yylval.byte = *(Byte*)YYText();
+       dtor << "lex: note on" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
        yy_pop_state(); 
        yy_push_state( int8 );
        yy_push_state( int8 );
        return NOTE_ON;
 }
+<event>{POLYPHONIC_AFTERTOUCH} {
+       dtor << "lex: polyphonic aftertouch" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       yy_push_state( int8 );
+       return POLYPHONIC_AFTERTOUCH;
+}
+<event>{CONTROLMODE_CHANGE}    {
+       dtor << "lex: controlmode change" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       yy_push_state( int8 );
+       return CONTROLMODE_CHANGE;
+}
 <event>{PROGRAM_CHANGE}        {
-       yylval.byte = *(Byte*)YYText();
+       dtor << "lex: program change" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
        yy_pop_state(); 
        yy_push_state( int8 );
        return PROGRAM_CHANGE;
 }
+<event>{CHANNEL_AFTERTOUCH}    {
+       dtor << "lex: channel aftertouch" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       yy_push_state( int8 );
+       return CHANNEL_AFTERTOUCH;
+}
+<event>{PITCHWHEEL_RANGE} {
+       dtor << "lex: pitchwheel range" << endl;
+//     yylval.byte = *(Byte*)YYText();
+       yylval.i = *(Byte*)YYText();
+       yy_pop_state(); 
+       yy_push_state( int8 );
+       yy_push_state( int8 );
+       return PITCHWHEEL_RANGE;
+}
+<event>{SYSEX_EVENT1} {        // len data
+       dtor << "lex: sysex1" << endl;
+       yy_pop_state(); 
+       yy_push_state( data );
+       return SYSEX_EVENT1;
+}
+<event>{SYSEX_EVENT2} {        // len data
+       dtor << "lex: sysex2" << endl;
+       yy_pop_state(); 
+//     yy_push_state( int8 ); //?
+       yy_push_state( data );
+       return SYSEX_EVENT2;
+}
 <event>{META_EVENT}    {
+       dtor << "lex: meta" << endl;
        yy_push_state( meta_event );
        return META_EVENT;
 }
-
+<event>{INT8}  {
+       error( String( "event: illegal byte: " ) 
+               + StringConversion::bin2hex_str( String( *YYText() ) ) );
+       exit( 1 );
+}
 <meta_event>{SEQUENCE} {       // ssss sequence number
+       dtor << "lex: sequence" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( int16 );
        return SEQUENCE;
 }
 <meta_event>{TEXT}     {               // len data
+       dtor << "lex: text" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return TEXT;
 }
 <meta_event>{COPYRIGHT}        {
+       dtor << "lex: copyright" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return COPYRIGHT;
 }
 <meta_event>{TRACK_NAME}       {
+       dtor << "lex: track name" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return TRACK_NAME;
 }
 <meta_event>{INSTRUMENT_NAME}  {
+       dtor << "lex: instrument name" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return INSTRUMENT_NAME;
 }
 <meta_event>{LYRIC}    {
+       dtor << "lex: lyric" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return LYRIC;
 }
 <meta_event>{MARKER}   {
+       dtor << "lex: marker" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return MARKER;
 }
 <meta_event>{CUE_POINT}        {
+       dtor << "lex: cue point" << endl;
+       yy_pop_state();
+       yy_pop_state();
        yy_push_state( data );
        return CUE_POINT;
 }
 <meta_event>{TEMPO}    {       // tttttt usec
-       puts( "lex: tempo" );
+       dtor << "lex: tempo" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_push_state( int8 );
@@ -192,6 +309,7 @@ SSME                [\0x7f][\x03]
        return TEMPO;
 }
 <meta_event>{SMPTE_OFFSET}     {               // hr mn se fr ff
+       dtor << "lex: smpte offset" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_push_state( int8 );
@@ -202,7 +320,7 @@ SSME                [\0x7f][\x03]
        return SMPTE_OFFSET;
 }
 <meta_event>{TIME}     {               // nn dd cc bb
-       puts( "lex: time" );
+       dtor << "lex: time" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_push_state( int8 );
@@ -212,7 +330,7 @@ SSME                [\0x7f][\x03]
        return TIME;
 }
 <meta_event>{KEY}      {       // sf mi
-       puts( "lex: key" );
+       dtor << "lex: key" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_push_state( int8 );
@@ -220,24 +338,32 @@ SSME              [\0x7f][\x03]
        return KEY;
 }
 <meta_event>{SSME}     {       // len data
+       dtor << "lex: smme" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_push_state( data );
        return SSME;
 }
 <meta_event>{END_OF_TRACK} {
-       puts( "lex: end of track" );
+       dtor << "lex: end of track" << endl;
        yy_pop_state();
        yy_pop_state();
        yy_pop_state();
        return END_OF_TRACK;
 }
 <meta_event>{INT8} {
-       yylval.byte = *(Byte*)YYText();
+       warning( String( "meta_event: unimplemented event: " )
+               + StringConversion::bin2hex_str( String( *YYText() ) ),
+               *this->here_ch_c_l() );
+       yy_pop_state();
+       yy_pop_state();
+       yy_push_state( int8 ); 
+       yy_push_state( int8 );
        return INT8;
 }
 
 <data>{VARINT} {
+       dtor << "lex: data" << endl;
        String str( (Byte const*)YYText(), YYLeng() );
        int i = My_midi_lexer::varint2int_i( str );
        String* str_p = new String;
@@ -245,10 +371,13 @@ SSME              [\0x7f][\x03]
                *str_p += (char)yyinput();
        yylval.str_p = str_p;
        yy_pop_state();
-       yy_pop_state();
        return DATA;
 }
-
+<data>{INT8}   {
+       error( String( "data: illegal byte: " )
+               + StringConversion::bin2hex_str( String( *YYText() ) ) );
+       exit( 1 );
+}
 
 <<EOF>> {
 //     mtor << "<<EOF>>";
index 3735517f1345e000f8dbe155af861455b19c6eaa..5b6ecb3e2d73c4d68ea8fe599286d2b68e3eecd6 100644 (file)
@@ -7,10 +7,14 @@
 #include <iostream.h>
 #include "proto.hh"
 #include "plist.hh"
+#include "version.hh"
+#include "fversion.hh"
 #include "string.hh"
+#include "lgetopt.hh"
 #include "source.hh"
 #include "sourcefile.hh"
 #include "midi-main.hh"
+#include "moment.hh"
 #include "midi-event.hh"
 #include "midi-track.hh"
 #include "my-midi-lexer.hh"
 Source source;
 Source* source_l_g = &source;
 
+Verbose level_ver = NORMAL_ver;
+
 //ugh
 char const* defined_ch_c_l = 0;
 
+// ugh, another global
 String
 find_file( String str )
 {
@@ -32,7 +39,7 @@ find_file( String str )
 void
 message( String message_str, char const* context_ch_c_l )
 {
-    String str = "lilypond: ";
+    String str = "m2m: ";
     Source_file* sourcefile_l = source_l_g->sourcefile_l( context_ch_c_l );
     if ( sourcefile_l ) {
        str += sourcefile_l->file_line_no_str(context_ch_c_l) + String(": ");
@@ -64,11 +71,110 @@ error( String message_str, char const* context_ch_c_l )
         midi_lexer_l_g->errorlevel_i_ |= 1;
 }
 
+void
+help()
+{
+    btor <<
+       "--debug, -d            be really verbose\n"
+       "--help, -h             This help\n"
+        "--include, -I         add to file search path.\n"
+       "--output, -o           set default output\n"
+       "--quiet, -q            be quiet\n"
+       "--verbose, -v          be verbose\n"
+       "--warranty, -w         show warranty & copyright\n"
+       ;
+}
+
+void
+identify()
+{
+       mtor << "This is m2m "  << VERSIONSTR << "/FlowerLib " << FVERSIONSTR
+               << " of " << __DATE__ << " " << __TIME__ << endl;
+}
+    
+void 
+notice()
+{
+    mtor <<
+       "\n"
+       "M2m, translate midi to mudela.\n"
+       "Copyright (C) 1997 by\n"
+       "  Han-Wen Nienhuys <hanwen@stack.nl>\n"
+//     "Contributors\n"
+       "  Jan Nieuwenhuizen <jan@digicash.com>\n"
+//     "  Mats Bengtsson <matsb@s3.kth.se>\n"
+       "\n"
+       "    This program is free software; you can redistribute it and/or\n"
+       "modify it under the terms of the GNU General Public License version 2\n"
+       "as published by the Free Software Foundation.\n"
+       "\n"
+       "    This program is distributed in the hope that it will be useful,\n"
+       "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+       "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
+       "General Public License for more details.\n"
+       "\n"
+       "    You should have received a copy (refer to the file COPYING) of the\n"
+       "GNU General Public License along with this program; if not, write to\n"
+       "the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,\n"
+       "USA.\n";
+}
+
 int
 main( int argc_i, char* argv_sz_a[] )
 {
-       if ( !argc_i )
-               return 2;
-       My_midi_parser midi_parser( argv_sz_a[ 1 ] );
-       return midi_parser.parse();
+       long_option_init long_option_init_a[] = {
+               0, "debug", 'd',
+               0, "help", 'h',
+//             1, "include", 'I',
+               1, "output", 'o',
+               0, "quiet", 'q',
+               0, "verbose", 'v',
+               0, "warranty", 'w',
+               0,0,0
+       };
+       Getopt_long getopt_long( argc_i, argv_sz_a, long_option_init_a );
+       identify();
+
+       String output_str;
+       while ( long_option_init* long_option_init_p = getopt_long() )
+               switch ( long_option_init_p->shortname ) {
+                       case 'd':
+                               level_ver = DEBUG_ver;
+                               break;
+                       case 'h':
+                               help();
+                               exit( 0 );
+                               break;
+//                     case 'I':
+//                             path->push( getopt_long.optarg );
+//                             break;
+                       case 'o':
+                               output_str = getopt_long.optarg;
+                               break;
+                       case 'q':
+                               level_ver = QUIET_ver;
+                               break;
+                       case 'v':
+                               level_ver = VERBOSE_ver;
+                               break;
+                       case 'w':
+                               notice();
+                               exit( 0 );
+                               break;
+                       default:
+                               assert( 0 );
+                               break;
+               }
+
+       char* arg_sz = 0;
+       while ( ( arg_sz = getopt_long.get_next_arg() ) ) {
+               My_midi_parser midi_parser( arg_sz );
+               int error_i = midi_parser.parse();
+               if ( error_i )
+                       return error_i;
+               error_i = midi_parser.output( output_str );
+               if ( error_i )
+                       return error_i;
+       }
+       return 0;
 }
index 519266f1fbb77694dca6472574bef27c06c829e9..56680f4b773771ded5de455f35f97e4beab3d1cd 100644 (file)
@@ -2,8 +2,16 @@
 
 #include <iostream.h>
 
+#include "proto.hh"         // ugh, these all for midi-main.hh 
+#include "plist.hh"
+#include "string.hh"
+#include "sourcefile.hh"
+#include "source.hh"
+#include "midi-main.hh"    // *tors
+
 #include "my-midi-lexer.hh"
 #include "my-midi-parser.hh"
+#include "moment.hh"
 #include "midi-event.hh"
 #include "midi-track.hh"
 #include "midi-score.hh"
 %token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME
 
 %token<i> INT8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT
-%token<i> RUNNING_STATUS NOTE_OFF NOTE_ON PROGRAM_CHANGE
+%token<i> RUNNING_STATUS DATA_ENTRY ALL_NOTES_OFF
+%token<i> NOTE_OFF NOTE_ON 
+%token<i> POLYPHONIC_AFTERTOUCH CONTROLMODE_CHANGE PROGRAM_CHANGE 
+%token<i> CHANNEL_AFTERTOUCH PITCHWHEEL_RANGE
 %token<str_p> DATA
 
+%type <i> varint
 %type <midi_score_p> header midi_score
 %type <midi_track_p> track
 %type <midi_event_p> event
-%type <midi_event_p> the_event meta_event text_event midi_event sysex_event
-%type <midi_event_p> running_status note_off note_on program_change
+%type <midi_event_p> the_event meta_event the_meta_event text_event midi_event sysex_event
+%type <midi_event_p> running_status data_entry all_notes_off
+%type <midi_event_p> note_off note_on
+%type <midi_event_p> polyphonic_aftertouch controlmode_change program_change
+%type <midi_event_p> channel_aftertouch pitchwheel_range
 
 %%
 
@@ -60,6 +75,7 @@ midi_score:
 header:        
        HEADER INT32 INT16 INT16 INT16 {
                $$ = new Midi_score( $3, $4, $5 );
+               midi_parser_l_g->set_division( $5 );
        }
        ;
 
@@ -73,12 +89,25 @@ track:
        ;
 
 event: 
-       VARINT the_event {
+       varint the_event {
+               if ( $2 && $2->mudela_str().length_i() ) {
+                       if ( ( $2->mudela_str()[ 0 ] >= 'a' ) 
+                               && $2->mudela_str()[ 0 ] <= 'g' ) 
+                               qtor << $2->mudela_str() << " ";
+                       else
+                               vtor << $2->mudela_str() << " ";
+               }
        }
        ;
        
+varint:
+       VARINT {
+               midi_parser_l_g->forward( $1 );
+       }
+       ;
+
 the_event: 
-       meta_event {
+       meta_event { 
        }
        | midi_event {
        }
@@ -88,86 +117,165 @@ the_event:
 
 meta_event:
        META_EVENT the_meta_event {
-       };
+               $$ = $2;
+       }
+       |
+       META_EVENT INT8 INT8 INT8 {
+               $$ = 0;
+       }
+       ;
 
 the_meta_event:
        SEQUENCE INT16 {
        }
        | text_event DATA {
+               $$ = 0;
+               vtor << *$2 << endl;
+               delete $2;
        }
        | END_OF_TRACK {
+               $$ = 0;
        }
        | TEMPO INT8 INT8 INT8 { 
+               $$ = new Midi_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
+               vtor << $$->mudela_str() << endl; // ?? waai not at event:
+               midi_parser_l_g->set_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
        }
        | SMPTE_OFFSET INT8 INT8 INT8 INT8 INT8 { 
+               $$ = 0;
        }
        | TIME INT8 INT8 INT8 INT8 { 
+               $$ = new Midi_time( $2, $3, $4, $5 );
+               vtor << $$->mudela_str() << endl; // ?? waai not at event:
+               midi_parser_l_g->set_time( $2, $3, $4, $5 );
        }
        | KEY INT8 INT8 { 
+               $$ = new Midi_key( $2, $3 );
+               midi_parser_l_g->set_key( $2, $3  );
        }
        | SSME DATA {
+               $$ = 0;
+               delete $2;
        }
        ;
 
 text_event: 
        TEXT {
+               vtor << endl << "Text: ";
        }
        | COPYRIGHT {
+               vtor << endl << "Copyright: ";
        }
        | TRACK_NAME {
+               vtor << endl << "Track  name: ";
        }
        | INSTRUMENT_NAME {
+               vtor << endl << "Instrument  name: ";
        }
        | LYRIC {
+               vtor << endl << "Lyric: ";
        }
        | MARKER {
+               vtor << endl << "Marker: ";
        }
        | CUE_POINT {
+               vtor << endl << "Cue point: ";
        }
        ;
 
 midi_event: 
        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 {
+       RUNNING_STATUS INT8 { //INT8 {
+               $$ = 0;
+       }
+       ;
+
+data_entry:
+       DATA_ENTRY INT8 {
+               $$ = 0;
+       }
+       ;
+
+all_notes_off:
+       ALL_NOTES_OFF INT8 INT8 {
+               $$ = 0;
        }
        ;
 
 note_off:
        NOTE_OFF INT8 INT8 {
+               int i = $1;
+               i = i & ~0x80;
+               $$ = midi_parser_l_g->note_end_midi_event_p( $1 & ~0x80, $2, $3 );
        }
        ;
 
 note_on:
        NOTE_ON INT8 INT8 {
-               int pitch_i = $2;
-               // assuming key of C
-               String notename_str = ( pitch_i % 12 )[ "ccddeffggaab" ];
-               static int accidental_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
-               int accidental_i = accidental_i_a[ pitch_i % 12 ];
-               if ( accidental_i == 1 )
-                       notename_str += "is";
-               cout << "note(" << pitch_i << "): " << notename_str << endl;
+               int i = $1;
+               i = i & ~0x90;
+               $$ = 0;
+               midi_parser_l_g->note_begin( $1 & ~0x90, $2, $3 );
+       }
+       ;
+
+polyphonic_aftertouch:
+       POLYPHONIC_AFTERTOUCH INT8 INT8 {
+               $$ = 0;
+       }
+       ;
+
+controlmode_change:
+       CONTROLMODE_CHANGE INT8 INT8 {
+               $$ = 0;
        }
        ;
 
 program_change:
-       PROGRAM_CHANGE {
+       PROGRAM_CHANGE INT8 {
+               $$ = 0;
+       }
+       ;
+
+channel_aftertouch:
+       CHANNEL_AFTERTOUCH INT8 INT8 {
+               $$ = 0;
+       }
+       ;
+
+pitchwheel_range:
+       PITCHWHEEL_RANGE INT8 INT8 {
+               $$ = 0;
        }
        ;
 
 sysex_event:
-       SYSEX_EVENT1 {
+       SYSEX_EVENT1 DATA {
+               $$ = 0;
        }
-       | SYSEX_EVENT2 {
+       | SYSEX_EVENT2 DATA { // INT8 ?
+               $$ = 0;
        }
        ;
index 99390c33460b6dce3f4152f7db6388c196defdd2..77abf04e1c8f76e3e779da579dd091da9bf9e98d 100644 (file)
@@ -4,6 +4,8 @@
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
 #include "proto.hh"
+#include "string.hh"
+#include "moment.hh"
 #include "midi-event.hh"
 #include "midi-track.hh"
 
index b86eb95f1b09bbca1db49837906992544e9fbb32..0ce9ead5e0357c58e14db154da7c888642e239a6 100644 (file)
@@ -57,7 +57,7 @@ Midi_duration::str()
     return String( "<duration: " ) + String( seconds_f_ ) + ">";
 }
 
-Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i )
+Midi_header::Midi_header( int format_i, int tracks_i, int clocks_per_4_i )
 {
     String str;
        
@@ -67,7 +67,7 @@ Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i )
     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' );
+    String tempo_str = StringConversion::int2hex_str( clocks_per_4_i, 4, '0' );
     str += StringConversion::hex2bin_str( tempo_str );
 
     set( "MThd", str, "" );
@@ -103,12 +103,8 @@ Midi_item::output_midi( Midi_stream& midi_stream_r )
 
 Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo  )
 {
-
-    if (!melreq_l )
-       pitch_i_ = INT_MAX-1;   // any pitch. 
-    else
-        pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
-    
+    assert(melreq_l);
+    pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;   
     channel_i_ = channel_i;
 
     // poor man-s staff dynamics:
@@ -130,6 +126,20 @@ Midi_note::str()
     return String( "" );
 }
 
+Midi_tempo::Midi_tempo( int tempo_i )
+{
+    tempo_i_ = tempo_i;
+}
+
+String
+Midi_tempo::str()
+{
+    int useconds_per_4_i = 60 * (int)1e6 / tempo_i_;
+    String str = "ff5103";
+    str += StringConversion::int2hex_str( useconds_per_4_i, 6, '0' );
+    return StringConversion::hex2bin_str( str );
+}
+
 Midi_track::Midi_track( int number_i )
 {
 //                4D 54 72 6B     MTrk
@@ -149,7 +159,7 @@ Midi_track::Midi_track( int number_i )
     number_i_ = number_i;
        
     char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
-       "00" "ff51" "0307" "a120"
+//     "00" "ff51" "0307" "a120"
 // why a key at all, in midi?
 // key: C
        "00" "ff59" "02" "00" "00"
@@ -177,10 +187,8 @@ Midi_track::add( int delta_time_i, String 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 );
+    // use convention of 384 clocks per 4
+    int delta_time_i = delta_time_moment * Moment( 384 ) / Moment( 1, 4 );
     add( delta_time_i, mitem_l->str() );
 }
 
index d84649fd4949b92ca2759e81c1649c5fc35650ad..f1e5e6b4128ba7b0838f886ba757c4d511dc3062 100644 (file)
 
 Midi_output:: Midi_output(Score* score_l, Midi_def* midi_l )
 {
+    midi_l_ = midi_l;
+
     Midi_stream midi_stream(midi_l->outfile_str_,
                            score_l->staffs_.size(),
-                           midi_l->get_tempo_i(Moment(1, 4)));
+                           384 );
+// oeps, not tempo, but clocks per 4 (384 convention)
+// must set tempo in tempo request
+//                         midi_l->get_tempo_i(Moment(1, 4)));
 
     midi_stream_l_ = &midi_stream;
     int track_i=0;
@@ -38,6 +43,8 @@ void
 Midi_output::do_staff(Staff*st_l,int track_i)
 {
     Midi_track midi_track( track_i );
+    Midi_tempo midi_tempo( midi_l_->get_tempo_i( Moment( 1, 4 ) ) );
+    midi_track.add( Moment( 0.0 ), &midi_tempo );
     for (Midi_walker w (st_l, &midi_track); w.ok(); w++)
        w.process_requests();
 
index 73fe2e4733742cc1877cfcd810f9c6dfe68aa12f..84b105d27dc823282b1d3e3ef6c6c56dc83dca14 100644 (file)
 #include "midistream.hh"
 #include "debug.hh"
 
-Midi_stream::Midi_stream( String filename_str, int tracks_i, int tempo_i ) 
+Midi_stream::Midi_stream( String filename_str, int tracks_i, int clocks_per_4_i ) 
 {
     filename_str_ = filename_str;
     tracks_i_ = tracks_i;
-    tempo_i_ = tempo_i;
+    clocks_per_4_i_ = clocks_per_4_i;
     open();
     header();
 }
@@ -75,7 +75,7 @@ Midi_stream::header()
 //    *os_p_ << str;
 
 //      *this << Midi_header( 1, 1, tempo_i_ );
-      *this << Midi_header( 1, tracks_i_, tempo_i_ );
+      *this << Midi_header( 1, tracks_i_, clocks_per_4_i_ );
 }
 
 void
index 036a227686fb8f2eb64d1b7d4639f0dda226f932..b8350bc2cc85d7dcd2c024253d43f20edfaba652 100644 (file)
@@ -21,6 +21,7 @@ Midi_walker::Midi_walker(Staff *st_l, Midi_track* track_l)
     track_l_ = track_l;
     last_moment_= 0;
 }
+
 /**
   output notestop events for all notes which end before #max_moment#
  */
@@ -32,12 +33,18 @@ Midi_walker::do_stop_notes(Moment max_moment)
        Melodic_req * req_l = stop_notes.get();
        
        Midi_note note(req_l, track_l_->number_i_, false);
-       
-       Moment delta_t = stop_moment-last_moment_ ;
-       last_moment_ += delta_t;
-       track_l_->add(delta_t, &note );
+       output_event(note, stop_moment);
     }
 }
+/** advance the track to #now#, output the item, and adjust current
+  "moment".  */
+void
+Midi_walker::output_event(Midi_item &i, Moment now)
+{
+    Moment delta_t = now - last_moment_ ;
+    last_moment_ += delta_t;
+    track_l_->add(delta_t, &i );    
+}
 
 void
 Midi_walker::process_requests()
@@ -46,13 +53,15 @@ Midi_walker::process_requests()
     for ( int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++ )  {
 
        Rhythmic_req *n = ptr()->musicalreq_l_arr_[i]->rhythmic();
-       if ( !n || !(n->note() || n->rest()) )
+       if ( !n)
+           continue;
+       Note_req * note_l = n->note();
+       if (!note_l)
            continue;
        
-       Midi_note note(n->melodic(), track_l_->number_i_, true);
-       stop_notes.enter(n->melodic(), n->duration() + ptr()->when() );
-       Moment dt = 0;
-       track_l_->add(dt, &note);
+       Midi_note note(note_l, track_l_->number_i_, true);
+       stop_notes.enter(note_l, n->duration() + ptr()->when() );
+       output_event(note, ptr()->when());
     }
 }
 
index 70c860bcf5afc73ce2c41dc8989d9f6f61c79cc1..a070992f534f0dfab6435eaa178e8d8ecd610b21 100644 (file)
@@ -19,7 +19,7 @@ My_midi_lexer* midi_lexer_l_g;
 My_midi_lexer::My_midi_lexer( String filename_str )
 {
        input_file_p_ = new Input_file( filename_str );
-       switch_streams( input_file_p_->is );
+       switch_streams( input_file_p_->is );
        midi_lexer_l_g = this;
        errorlevel_i_ = 0;
 }
@@ -56,17 +56,20 @@ My_midi_lexer::here_ch_c_l()
     return input_file_p_->sourcefile_l_->ch_c_l() + yyin->tellg();
 }
 
-#if 0 // ?? huh
-int
-My_midi_lexer::yylex()
-{
-       return 0;
-}
-#endif
-
 int
 My_midi_lexer::varint2int_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 << "\nvarint2int:" << StringConversion::bin2hex_str( str ) << endl;
+       assert( 0 ); // illegal varint
        return 0;
 }
 
index 51dda6bd15e592257f94640554d6cee4d1407c3a..cd12082239c7e3bdb33b0751eb756b9c2e0044fa 100644 (file)
@@ -3,6 +3,17 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include "proto.hh"
+
+#include "plist.hh"        // ugh
+#include "string.hh"
+#include "sourcefile.hh"
+#include "source.hh"
+#include "midi-main.hh"    // *tors
+
+#include "my-midi-lexer.hh"
+#include "my-midi-parser.hh"
+#include "midi-event.hh"
 #include "my-midi-lexer.hh"
 #include "my-midi-parser.hh"
 
@@ -19,14 +30,37 @@ My_midi_parser::My_midi_parser( String filename_str )
 {
        midi_lexer_p_ = new My_midi_lexer( filename_str );
        midi_parser_l_g = this;
+
+       midi_key_p_ = new Midi_key( 0, 0 );
+//     midi_tempo_p_ = new Midi_tempo( 384 ); // wiellie dunno!
+       // 07A120 == 500000
+       midi_tempo_p_ = new Midi_tempo( 0x07a120 ); // wiellie dunno!
+       midi_time_p_ = new Midi_time( 4, 4, 0x24, 8 );
+
        defined_ch_c_l_ = 0;
        fatal_error_i_ = 0;
+       now_f_ = 0;
+       step_f_ = 0;
+
+       for ( int i = 0; i < CHANNELS_i; i++ )
+               for ( int j = 0; j < PITCHES_i; j++ )
+                       running_f_f_a_[ i ][ j ] = 0;
 }
 
 My_midi_parser::~My_midi_parser()
 {
        delete midi_lexer_p_;
        midi_parser_l_g = 0;
+       delete midi_key_p_;
+       delete midi_tempo_p_;
+       delete midi_time_p_;
+}
+
+void
+My_midi_parser::add_score( Midi_score* midi_score_p )
+{
+       midi_score_p_array_.push( midi_score_p );
+       cout << endl;
 }
 
 void
@@ -38,6 +72,39 @@ My_midi_parser::error( char const* sz_l )
                exit( fatal_error_i_ );
 }
 
+void
+My_midi_parser::forward( Real f )
+{
+       // ugh
+       if ( f )
+               step_f_ = f;
+       now_f_ += step_f_;
+}
+
+void
+My_midi_parser::note_begin( int channel_i, int pitch_i, int dyn_i )
+{
+       // one pitch a channel at time!
+       //  heu, what if start at t = 0?
+//     assert( !running_f_f_a_[ channel_i ][ pitch_i ] );
+       running_f_f_a_[ channel_i ][ pitch_i ] = now_f_;
+}
+
+Midi_event*
+My_midi_parser::note_end_midi_event_p( int channel_i, int pitch_i, int dyn_i )
+{
+       Real start_f = running_f_f_a_[ channel_i ] [ pitch_i ];
+       // did we start? -> heu, don-t know: what if start at t = 0?
+//     assert( start_f ); 
+       return new Midi_note( midi_key_p_, midi_time_p_, clocks_per_whole_i_, pitch_i, now_f_ - start_f );
+}
+
+int
+My_midi_parser::output( String filename_str )
+{
+       return 0;
+}
+
 int
 My_midi_parser::parse()
 {
@@ -45,8 +112,31 @@ My_midi_parser::parse()
 }
 
 void
-My_midi_parser::add_score( Midi_score* midi_score_p )
+My_midi_parser::set_division( int clocks_per_4_i )
 {
-       midi_score_p_array_.push( midi_score_p );
+       clocks_per_whole_i_ = clocks_per_4_i * 4;
+       if ( clocks_per_4_i < 0 )
+               warning( "seconds iso metrical time" , 0 );
+}
+
+void
+My_midi_parser::set_key( int accidentals_i, int minor_i )
+{
+       delete midi_key_p_;
+       midi_key_p_ = new Midi_key( accidentals_i, minor_i );
+}
+
+void
+My_midi_parser::set_tempo( int useconds_i )
+{
+       delete midi_tempo_p_;
+       midi_tempo_p_ = new Midi_tempo( useconds_i );
+}
+
+void
+My_midi_parser::set_time( int num_i, int den_i, int clocks_i, int count_32_i )
+{
+       delete midi_time_p_;
+       midi_time_p_ = new Midi_time( num_i, den_i, clocks_i, count_32_i );
 }
 
index 0775719160a45d969a5d32b4f0fe7e11fef43844..eac2b1f84a6454385608c7c65be96c356e9d06f2 100644 (file)
@@ -34,6 +34,7 @@ Source_file::Source_file( String &filename_str )
 
     open();
     map();
+    // ugh!?, should call name_str() ! 
     filename_str = name_str_;
 }
 
@@ -83,15 +84,17 @@ Source_file::error_str( char const* pos_ch_c_l )
        }
     end_ch_c_l--;
 
-// String( char const* p, int length ) is missing!?
-//    String line_str( begin_ch_c_l, end_ch_c_l - begin_ch_c_l );
-
+#if 1
+//    String( char const* p, int length ) is missing!?
+    String line_str( (Byte const*)begin_ch_c_l, end_ch_c_l - begin_ch_c_l );
+#else
     int length_i = end_ch_c_l - begin_ch_c_l;
     char* ch_p = new char[ length_i + 1 ];
     strncpy( ch_p, begin_ch_c_l, length_i );
     ch_p[ length_i ] = 0;
     String line_str( ch_p );
     delete ch_p;
+#endif
 
     int error_col_i = 0;
     char const* scan_ch_c_l = begin_ch_c_l;
@@ -129,6 +132,12 @@ Source_file::istream_l()
     return istream_p_;
 }
 
+off_t
+Source_file::length_off()
+{
+    return size_off_;
+}
+
 int
 Source_file::line_i( char const* pos_ch_c_l )
 {
@@ -191,8 +200,8 @@ Source_file::unmap()
     }
 }
 String
-Source_file::file_line_no_str(const char *cch_c_l )
+Source_file::file_line_no_str(char const *ch_c_l )
 {
     return name_str() + ": "
-       + String( line_i( cch_c_l ) );
+       + String( line_i( ch_c_l ) );
 }