]> git.donarmstrong.com Git - lilypond.git/commitdiff
partial: 0.0.39-1.jcn
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 6 Mar 1997 18:16:55 +0000 (19:16 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 6 Mar 1997 18:16:55 +0000 (19:16 +0100)
42 files changed:
hdr/binary-source-file.hh [deleted file]
hdr/lyricstaff.hh [deleted file]
hdr/midi-def.hh [deleted file]
hdr/my-midi-lexer.hh [deleted file]
hdr/source-file.hh [deleted file]
hdr/source.hh [deleted file]
lib/binary-source-file.cc [new file with mode: 0644]
lib/duration.cc [new file with mode: 0644]
lib/include/binary-source-file.hh [new file with mode: 0644]
lib/include/duration.hh [new file with mode: 0644]
lib/include/source-file.hh [new file with mode: 0644]
lib/include/source.hh [new file with mode: 0644]
lily/include/lyric-item.hh [new file with mode: 0644]
lily/include/lyric-staff.hh [new file with mode: 0644]
lily/include/midi-def.hh [new file with mode: 0644]
lily/include/midi-item.hh [new file with mode: 0644]
lily/include/midi-stream.hh [new file with mode: 0644]
lily/lyric-walker.cc [new file with mode: 0644]
lily/midi-def.cc [new file with mode: 0644]
lily/midi-item.cc [new file with mode: 0644]
lily/midi-stream.cc [new file with mode: 0644]
m2m/include/lily-stream.hh [new file with mode: 0644]
m2m/include/m2m.hh [new file with mode: 0644]
m2m/include/midi-event.hh [new file with mode: 0644]
m2m/include/midi-global.hh [new file with mode: 0644]
m2m/include/midi-main.hh [new file with mode: 0644]
m2m/include/midi-score.hh [new file with mode: 0644]
m2m/include/midi-track.hh [new file with mode: 0644]
m2m/include/midi-voice.hh [new file with mode: 0644]
m2m/include/my-midi-lexer.hh [new file with mode: 0644]
m2m/include/my-midi-parser.hh [new file with mode: 0644]
m2m/include/track-column.hh [new file with mode: 0644]
m2m/lily-stream.cc [new file with mode: 0644]
m2m/midi-event.cc [new file with mode: 0644]
m2m/midi-main.cc [new file with mode: 0644]
m2m/midi-score.cc [new file with mode: 0644]
m2m/midi-template.cc [new file with mode: 0644]
m2m/midi-track.cc [new file with mode: 0644]
m2m/midi-voice.cc [new file with mode: 0644]
m2m/my-midi-lexer.cc [new file with mode: 0644]
m2m/my-midi-parser.cc [new file with mode: 0644]
m2m/track-column.cc [new file with mode: 0644]

diff --git a/hdr/binary-source-file.hh b/hdr/binary-source-file.hh
deleted file mode 100644 (file)
index 1af3563..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-//  binary-source-file.hh -- declare Binary_source_file
-//
-//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef BINARY_SOURCE_FILE_HH
-#define BINARY_SOURCE_FILE_HH
-
-class Binary_source_file : public Source_file {
-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 );
-};
-
-#endif // BINARY_SOURCE_FILE_HH //
diff --git a/hdr/lyricstaff.hh b/hdr/lyricstaff.hh
deleted file mode 100644 (file)
index fb88c5e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-  lyricstaff.hh -- part of LilyPond
-
-  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-  */
-
-#ifndef LYRICSTAFF_HH
-#define LYRICSTAFF_HH
-
-#include "staff.hh"
-
-/**
-  Hungarian prefix lstaff
- */
-struct Lyric_staff : Staff {
-    virtual void set_output(PScore *);
-    virtual Staff_walker *get_walker_p();
-};
-
-#endif // LYRICSTAFF_HH
-
-
-
-
diff --git a/hdr/midi-def.hh b/hdr/midi-def.hh
deleted file mode 100644 (file)
index 7a559ad..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  midi-def.hh -- declare 
-
-  source file of the LilyPond music typesetter
-
-  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
-*/
-
-
-#ifndef MIDIDEF_HH
-#define MIDIDEF_HH
-#include "proto.hh"
-#include "real.hh"
-#include "string.hh"
-#include "moment.hh"
-
-
-/** 
- */
-struct Midi_def {
-    /// output file name
-    String outfile_str_;
-
-    /// duration of whole note
-    Real whole_seconds_f_;
-
-    Midi_def();
-    Midi_def(Midi_def const& midi_c_r);
-    ~Midi_def();
-
-    Real duration_to_seconds_f(Moment);
-    int get_tempo_i( Moment moment );
-    void set_tempo( Moment moment, int count_per_minute_i );
-    void print() const;
-};
-
-#endif // MIDIDEF_HH //
-
diff --git a/hdr/my-midi-lexer.hh b/hdr/my-midi-lexer.hh
deleted file mode 100644 (file)
index 032bf67..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// my-midi-lexer.hh -- declare My_midi_lexer
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef MY_MIDI_LEXER_HH
-#define MY_MIDI_LEXER_HH
-
-#include <FlexLexer.h>
-#include "proto.hh"
-// #include "fproto.hh"
-#include "varray.hh"
-#include "string.hh"
-
-int yylex();
-void yyerror(const char *s);
-// bool busy_parsing();
-// void kill_lexer();
-// void set_lexer();
-
-/// (midi_lexer)
-class My_midi_lexer : yyFlexLexer {
-public:
-       My_midi_lexer( String filename_str );
-       ~My_midi_lexer();
-
-       int close_i();
-       void error( char const* sz_l );
-       char const* here_ch_c_l();
-       static int varint2_i( String str );
-       int yylex();
-
-private:
-       Input_file* input_file_p_;
-
-public: // ugh
-       int errorlevel_i_;
-};
-
-extern My_midi_lexer* midi_lexer_l_g;
-
-#endif // MY_MIDI_LEXER_HH
-
diff --git a/hdr/source-file.hh b/hdr/source-file.hh
deleted file mode 100644 (file)
index 7f7168e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-//  source-file.hh -- declare Source_file
-//
-//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef SOURCE_FILE_HH
-#define SOURCE_FILE_HH
-
-/// class for reading and mapping a file. 
-class Source_file
-{
-public:
-    /** Ugh! filename gets changed! The path to the opened file may
-       change, since it might be searched in multiple directories.  */
-    Source_file( String& filename_str_r );
-    virtual ~Source_file();
-
-    char const* 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 );
-    off_t length_off();
-    virtual int line_i( char const* pos_ch_c_l );
-    String name_str();
-    String file_line_no_str( char const* ch_c_l );
-
-private:
-    void close();
-    void map();
-    void open();
-    void unmap();
-
-    istream* istream_p_;
-    int fildes_i_;
-    String name_str_;
-    off_t size_off_;
-    caddr_t data_caddr_;
-};
-
-#endif // SOURCE_FILE_HH //
diff --git a/hdr/source.hh b/hdr/source.hh
deleted file mode 100644 (file)
index 6c79b75..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-//  source.hh -- part of LilyPond
-//
-//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef SOURCE_HH
-#define SOURCE_HH
-
-class Source 
-{
-public:
-    Source();
-    ~Source();
-
-    void add( Source_file* sourcefile_p );
-    Source_file* sourcefile_l( char const* ch_c_l );
-
-private:
-    IPointerList<Source_file*> sourcefile_p_iplist_;
-};
-
-
-// ugh
-extern Source* source_l_g;
-
-#endif // SOURCE_HH //
diff --git a/lib/binary-source-file.cc b/lib/binary-source-file.cc
new file mode 100644 (file)
index 0000000..34f6645
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+  binary-source-file.cc -- implement Binary_source_file
+
+  source file of the LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen
+*/
+
+
+#include <limits.h>            // INT_MAX
+#include <assert.h>
+
+#include "proto.hh"
+#include "plist.hh"
+#include "string.hh"
+#include "debug.hh"
+#include "source-file.hh"
+#include "binary-source-file.hh"
+#include "string-convert.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 = String_convert::bin2hex_str( pre_str );
+    for ( int i = 2; i < pre_str.length_i(); i += 3 )
+       pre_str = pre_str.left_str( i ) + " " + pre_str.mid_str( i, INT_MAX );
+    String post_str( (Byte const*)pos_ch_c_l, end_ch_c_l - pos_ch_c_l );
+    post_str = String_convert::bin2hex_str( post_str );
+    for ( int i = 2; i < post_str.length_i(); i += 3 )
+       post_str = post_str.left_str( i ) + " " + post_str.mid_str( i, 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();
+}
+
diff --git a/lib/duration.cc b/lib/duration.cc
new file mode 100644 (file)
index 0000000..b078b78
--- /dev/null
@@ -0,0 +1,247 @@
+//
+// duration.cc -- implement Duration, Plet, Duration_convert, Duration_iterator
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+// split into 4?
+
+#include "proto.hh"
+#include "plist.hh"
+#include "string.hh"
+#include "source-file.hh"
+#include "source.hh"
+#include "moment.hh"
+#include "duration.hh"
+#include "debug.hh"  //ugh
+
+Duration::Duration( int type_i, int dots_i = 0, Plet* plet_l )
+{
+       type_i_ = type_i;
+       dots_i_ = dots_i;
+       plet_p_ = 0;
+       set_plet( plet_l );
+}
+
+Duration::Duration( Duration const& dur_c_r )
+{
+       type_i_ = 0;
+       dots_i_ = 0;
+       plet_p_ = 0;
+       *this = dur_c_r;
+}
+
+Duration::~Duration()
+{
+       delete plet_p_;
+}
+
+Duration const& 
+Duration::operator =( Duration const& dur_c_r )
+{
+       if ( &dur_c_r == this )
+               return *this;
+
+       type_i_ = dur_c_r.type_i_;
+       dots_i_ = dur_c_r.dots_i_;
+       set_plet( dur_c_r.plet_p_ );
+
+       return *this;
+}
+
+void
+Duration::set_plet( Plet* plet_l )
+{
+       delete plet_p_;
+       plet_p_ = 0;
+       if ( plet_l )
+               plet_p_ = new Plet( *plet_l );
+}
+
+Plet::Plet( int iso_i, int type_i )
+{
+       iso_i_ = iso_i;
+       type_i_ = type_i;
+}
+
+Plet::Plet( Plet const& plet_c_r )
+{
+       iso_i_ = plet_c_r.iso_i_;
+       type_i_ = plet_c_r.type_i_;
+}
+
+String 
+Duration_convert::dur2_str( Duration dur )
+{
+       String str( dur.type_i_ );
+       str += String( '.', dur.dots_i_ );
+       if ( dur.plet_p_ )
+               str += String( "*" ) + String( dur.plet_p_->iso_i_ )
+                       + String( "/" ) + String( dur.plet_p_->type_i_ );
+       return str;
+}
+
+int
+Duration_convert::dur2_i( Duration dur, int division_1_i )
+{
+    return dur2_mom( dur ) * Moment( division_1_i );
+}
+
+Moment
+Duration_convert::dur2_mom( Duration dur )
+{
+       if ( !dur.type_i_ )
+               return 0;
+
+       Moment mom = Moment( 1 , dur.type_i_ );
+
+       Moment delta = mom;
+       while ( dur.dots_i_-- ) {
+               delta /= 2.0;
+               mom += delta;
+       }
+
+       return mom * plet_factor_mom( dur );    
+}
+
+Duration
+Duration_convert::mom2_dur( Moment mom )
+{
+       /* this is cute, 
+          but filling an array using Duration_iterator
+          might speed things up, a little
+          */
+       Duration_iterator iter_dur;
+       assert( iter_dur );
+       while ( iter_dur ) {
+               Duration lower_dur = iter_dur++;
+               Duration upper_dur( 0 );
+               if ( iter_dur )
+                       upper_dur = iter_dur();
+               Moment lower_mom = dur2_mom( lower_dur );
+               Moment upper_mom = dur2_mom( upper_dur );
+               if ( mom == lower_mom )
+                       return lower_dur;
+               if ( mom == upper_mom ) // don-t miss last (sic)
+                       return upper_dur;
+               if ( ( mom >= lower_mom ) && ( mom <= upper_mom ) ) {
+                       warning( String( "duration not exact: " ) + String( (Real)mom ) , 0 );
+                       if ( abs( mom - lower_mom ) < abs( mom - upper_mom ) )
+                               return lower_dur;
+                       else
+                               return upper_dur;
+               }
+               lower_dur = upper_dur;
+       }
+       return Duration( 0 );
+}
+
+Moment
+Duration_convert::plet_factor_mom( Duration dur )
+{
+       if ( !dur.plet_p_ )
+               return 1;
+       return Moment( dur.plet_p_->iso_i_, dur.plet_p_->type_i_ );
+}
+
+Real
+Duration_convert::sync_f( Duration dur, Moment mom )
+{
+       return mom / dur2_mom( dur );
+}
+
+Moment
+Duration_convert::i2_mom( int time_i, int division_1_i )
+{
+       if ( !time_i )
+               return Moment( 0 );
+
+       if ( division_1_i > 0 )
+               return Moment( time_i, division_1_i );
+       else 
+               return Moment( -division_1_i, time_i );
+}
+
+Duration_iterator::Duration_iterator()
+{
+       cursor_dur_.type_i_ = 128;
+       cursor_dur_.set_plet( 0 );
+}
+
+Duration 
+Duration_iterator::operator ++(int)
+{
+       return forward_dur();
+}
+
+Duration
+Duration_iterator::operator ()()
+{
+       return dur();
+}
+
+Duration_iterator::operator bool()
+{
+       return ok();
+}
+
+Duration
+Duration_iterator::dur()
+{
+       return cursor_dur_;
+}
+
+Duration
+Duration_iterator::forward_dur()
+{
+       // should do smart table? guessing: 
+       //      duration wholes
+       //      16      0.0625
+       //      32..    0.0703
+       //      8:2/3   0.0833
+       //      16.     0.0938
+       //      8       0.1250
+       //      16..    0.1406
+       //      4:2/3   0.1667
+       //      8.      0.1875
+
+       assert( ok() );
+
+       Duration dur = cursor_dur_;
+
+       if ( !cursor_dur_.dots_i_ && !cursor_dur_.plet_p_ ) {
+               cursor_dur_.type_i_ *= 2;
+               cursor_dur_.dots_i_ = 2;
+       }
+       else if ( cursor_dur_.dots_i_ == 2 ) {
+               assert( !cursor_dur_.plet_p_ );
+               cursor_dur_.dots_i_ = 0;
+               cursor_dur_.type_i_ /= 4;
+               cursor_dur_.set_plet( &Plet( 2, 3 ) );
+       }
+       else if ( cursor_dur_.plet_p_ 
+               && ( cursor_dur_.plet_p_->iso_i_ == 2 )
+               && ( cursor_dur_.plet_p_->type_i_ == 3 ) ) {
+               assert( !cursor_dur_.dots_i_ );
+               cursor_dur_.set_plet( 0 );
+               cursor_dur_.type_i_ *= 2;
+               cursor_dur_.dots_i_ = 1;
+       }
+       else if ( cursor_dur_.dots_i_ == 1 ) {
+               assert( !cursor_dur_.plet_p_ );
+               cursor_dur_.dots_i_ = 0;
+               cursor_dur_.type_i_ /= 2;
+       }
+               
+       // ugh
+       if ( no_triplets_bo_g && cursor_dur_.plet_p_ && ok() )
+               forward_dur();
+
+       return dur;
+}
+
+bool
+Duration_iterator::ok()
+{
+       return ( cursor_dur_.type_i_ 
+               && !( ( cursor_dur_.type_i_ == 1 ) && ( cursor_dur_.dots_i_ > 2 ) ) );
+}
diff --git a/lib/include/binary-source-file.hh b/lib/include/binary-source-file.hh
new file mode 100644 (file)
index 0000000..1af3563
--- /dev/null
@@ -0,0 +1,18 @@
+//
+//  binary-source-file.hh -- declare Binary_source_file
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef BINARY_SOURCE_FILE_HH
+#define BINARY_SOURCE_FILE_HH
+
+class Binary_source_file : public Source_file {
+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 );
+};
+
+#endif // BINARY_SOURCE_FILE_HH //
diff --git a/lib/include/duration.hh b/lib/include/duration.hh
new file mode 100644 (file)
index 0000000..66bbde1
--- /dev/null
@@ -0,0 +1,114 @@
+//
+// duration.hh -- declare Duration, Plet, Duration_convert Duration_iterator
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+// split into 4?
+
+#ifndef DURATION_HH
+#define DURATION_HH
+
+// ugh, to get me in lily lib
+extern bool no_triplets_bo_g;
+
+/// (dur)
+struct Duration {
+       // actually i hate it when other people use default arguments,
+       // because it makes you easily loose track of what-s really
+       // happening; in the routine-s implementation you-re not aware
+       // of this defaultness (who sets this stupid value?).
+       Duration( int type_i = 1, int dots_i = 0, Plet* plet_p = 0 );
+       Duration( Duration const& dur_c_r );
+       ~Duration();
+
+       Duration const& operator =( Duration const& dur_c_r );
+
+       void set_plet( Plet* plet_l ); // handiger: newt zelf
+
+//         int i_;     // balltype -> type!
+       int type_i_;
+       int dots_i_;
+       Plet* plet_p_;
+};
+
+/// (plet)
+struct Plet {
+       Plet( int replace_i, int type_i );
+       Plet( Plet const& plet_c_r );
+
+//         int i_;
+       int iso_i_;  // 2/3; 2 is not duration, maar of count!
+       int type_i_;
+};
+
+/**
+       Duration_convert handles all conversions to -n fro Duration (dur).
+       That is including (integer + division) representation for MIDI,
+       and conversion from unexact time representation (best guess :-).
+
+       A Moment (mom) is a Rational that holds the time fraction 
+       compared to a whole note (before also called wholes).
+
+       SUGGESTION: currently a moment in time is called moment too;
+       let-s typedef Rational When too, so that we get 
+       When Staff_column::when(), Moment Voice_element::mom().
+*/
+struct Duration_convert {
+       /// Most used division in MIDI, all fine with me.
+       static int const division_1_c_i = 384;
+
+       /// Return (integer, division) representation.
+       static int dur2_i( Duration dur, int division_1_i = division_1_c_i );
+       
+       /// Return Moment representation (fraction of whole note).
+       static Moment dur2_mom( Duration dur );
+
+       /// Return Mudela string representation.
+       static String dur2_str( Duration dur );
+
+       /// Return Moment from (integer, division) representation.
+       static Moment i2_mom( int i, int division_1_i = division_1_c_i );
+
+       /// Return Moment (fraction of whole) representation, best guess.
+       static Duration mom2_dur( Moment mom );
+
+       /// Return plet factor (not a Moment: should use Rational?).
+       static Moment plet_factor_mom( Duration dur );
+
+       /** Return synchronisation factor for mom, so that
+           mom2_dur( mom / sync_f ) will return the duration dur.              
+       */ 
+       static Real sync_f( Duration dur, Moment mom );
+};
+
+/// (iter_dur)
+struct Duration_iterator {
+       /// start at shortest: 128:2/3
+       Duration_iterator();
+
+       // **** what about these three here ?
+       /// return forward_dur();
+       Duration operator ++(int); 
+
+       /// return ok()
+       operator bool(); 
+
+       /// return dur()
+       Duration operator ()(); 
+       // ****
+
+       /// return current dur
+       Duration dur();
+
+       /// return dur(), step to next
+       Duration forward_dur();
+
+       /// durations left?
+       bool ok();
+
+private:
+       Duration cursor_dur_;
+};
+
+#endif // DURATION_HH
+
diff --git a/lib/include/source-file.hh b/lib/include/source-file.hh
new file mode 100644 (file)
index 0000000..7f7168e
--- /dev/null
@@ -0,0 +1,40 @@
+//
+//  source-file.hh -- declare Source_file
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef SOURCE_FILE_HH
+#define SOURCE_FILE_HH
+
+/// class for reading and mapping a file. 
+class Source_file
+{
+public:
+    /** Ugh! filename gets changed! The path to the opened file may
+       change, since it might be searched in multiple directories.  */
+    Source_file( String& filename_str_r );
+    virtual ~Source_file();
+
+    char const* 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 );
+    off_t length_off();
+    virtual int line_i( char const* pos_ch_c_l );
+    String name_str();
+    String file_line_no_str( char const* ch_c_l );
+
+private:
+    void close();
+    void map();
+    void open();
+    void unmap();
+
+    istream* istream_p_;
+    int fildes_i_;
+    String name_str_;
+    off_t size_off_;
+    caddr_t data_caddr_;
+};
+
+#endif // SOURCE_FILE_HH //
diff --git a/lib/include/source.hh b/lib/include/source.hh
new file mode 100644 (file)
index 0000000..6c79b75
--- /dev/null
@@ -0,0 +1,26 @@
+//
+//  source.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef SOURCE_HH
+#define SOURCE_HH
+
+class Source 
+{
+public:
+    Source();
+    ~Source();
+
+    void add( Source_file* sourcefile_p );
+    Source_file* sourcefile_l( char const* ch_c_l );
+
+private:
+    IPointerList<Source_file*> sourcefile_p_iplist_;
+};
+
+
+// ugh
+extern Source* source_l_g;
+
+#endif // SOURCE_HH //
diff --git a/lily/include/lyric-item.hh b/lily/include/lyric-item.hh
new file mode 100644 (file)
index 0000000..a5dc27b
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  lyric-item.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef LYRIC_ITEM_HH
+#define LYRIC_ITEM_HH
+
+#include "text-item.hh"
+  
+struct Lyric_item : Text_item {
+    /* *************** */
+    Lyric_item(Lyric_req* lreq_l, int voice_count_i);
+    virtual void do_pre_processing();    
+};
+
+
+#endif // LYRIC_ITEM_HH //
+
diff --git a/lily/include/lyric-staff.hh b/lily/include/lyric-staff.hh
new file mode 100644 (file)
index 0000000..fb88c5e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+  lyricstaff.hh -- part of LilyPond
+
+  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+  */
+
+#ifndef LYRICSTAFF_HH
+#define LYRICSTAFF_HH
+
+#include "staff.hh"
+
+/**
+  Hungarian prefix lstaff
+ */
+struct Lyric_staff : Staff {
+    virtual void set_output(PScore *);
+    virtual Staff_walker *get_walker_p();
+};
+
+#endif // LYRICSTAFF_HH
+
+
+
+
diff --git a/lily/include/midi-def.hh b/lily/include/midi-def.hh
new file mode 100644 (file)
index 0000000..7a559ad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+  midi-def.hh -- declare 
+
+  source file of the LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+
+#ifndef MIDIDEF_HH
+#define MIDIDEF_HH
+#include "proto.hh"
+#include "real.hh"
+#include "string.hh"
+#include "moment.hh"
+
+
+/** 
+ */
+struct Midi_def {
+    /// output file name
+    String outfile_str_;
+
+    /// duration of whole note
+    Real whole_seconds_f_;
+
+    Midi_def();
+    Midi_def(Midi_def const& midi_c_r);
+    ~Midi_def();
+
+    Real duration_to_seconds_f(Moment);
+    int get_tempo_i( Moment moment );
+    void set_tempo( Moment moment, int count_per_minute_i );
+    void print() const;
+};
+
+#endif // MIDIDEF_HH //
+
diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh
new file mode 100644 (file)
index 0000000..6f10572
--- /dev/null
@@ -0,0 +1,108 @@
+//
+//  midiitem.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_ITEM_HH
+#define MIDI_ITEM_HH
+#include "string.hh"
+#include "proto.hh"
+
+struct Midi_item {
+    /* *************** */
+    static String i2varint_str( int i );
+    virtual void output_midi( Midi_stream& midi_stream_r ) const;
+    virtual String str() const = 0;
+};
+
+struct Midi_key : public Midi_item {
+       Midi_key( int accidentals_i, int minor_i );
+       
+       virtual String str() const;
+       
+       int accidentals_i_;
+       int minor_i_;
+};
+
+struct Midi_note : public Midi_item {
+    /* *************** */
+    int const c0_pitch_i_c_ = 60;
+    Byte dynamic_byte_;
+
+    /**
+      Generate a note-event on a channel pitch.
+
+      @param #melreq_l# is the pitch. 
+     */
+    Midi_note( Melodic_req* melreq_l, int channel_i, bool on_b );
+
+    virtual String str() const;
+
+    int channel_i_;
+    int on_b_;
+    int pitch_i_;
+};
+
+struct Midi_duration : public Midi_item {
+    /* *************** */
+    Midi_duration( Real seconds_f );
+
+    virtual String str() const;
+
+    Real seconds_f_;
+};
+
+struct Midi_chunk : Midi_item {
+    /* *************** */
+    Midi_chunk();
+
+    void add( String str );
+    void set( String header_str, String data_str, String footer_str );
+    virtual String str() const;
+
+private:
+    String data_str_;
+    String footer_str_;
+    String header_str_;
+};
+
+struct Midi_header : Midi_chunk {
+    /* *************** */
+    Midi_header( int format_i, int tracks_i, int clocks_per_4_i );
+};
+
+struct Midi_text : Midi_item {
+    /* *************** */
+       enum Type { 
+               TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, 
+               MARKER, CUE_POINT
+       };
+       Midi_text( Midi_text::Type type, String text_str );
+
+       virtual String str() const;
+
+       Type type_;
+       String text_str_;
+};
+
+struct Midi_tempo : Midi_item {
+    /* *************** */
+    Midi_tempo( int per_minute_4_i );
+
+    virtual String str() const;
+
+    int per_minute_4_i_;
+};
+
+struct Midi_track : Midi_chunk {
+    /* *************** */
+    int number_i_;
+    Midi_track( int number_i );
+
+    void add( int delta_time_i, String event );
+//     void add( Moment delta_time_moment, Midi_item& mitem_r );
+    void add( Moment delta_time_moment, Midi_item* mitem_l );
+};
+
+#endif // MIDI_ITEM_HH //
+
diff --git a/lily/include/midi-stream.hh b/lily/include/midi-stream.hh
new file mode 100644 (file)
index 0000000..2444384
--- /dev/null
@@ -0,0 +1,32 @@
+//
+//  midistream.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_STREAM_HH
+#define MIDI_STREAM_HH
+
+#include <iostream.h>
+#include "string.hh"
+
+/// Midi output
+struct Midi_stream {
+    ostream* os_p_;
+    String filename_str_;
+    int clocks_per_4_i_;
+    int tracks_i_;
+    
+    Midi_stream( String filename_str, int tracks_i, int clocks_per_4_i_ );
+    ~Midi_stream();
+
+    Midi_stream& operator <<( String str );
+    Midi_stream& operator <<( Midi_item const& mitem_c_r );
+    Midi_stream& operator <<( int i );
+
+    void header();
+    void open();
+
+//private:
+//    Midi_stream(Midi_stream const&);
+};
+#endif // MIDI_STREAM_HH //
diff --git a/lily/lyric-walker.cc b/lily/lyric-walker.cc
new file mode 100644 (file)
index 0000000..614e258
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+  lyricwalker.cc -- implement Lyric_walker
+
+  source file of the LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "pscore.hh"
+#include "lyric-staff.hh"
+#include "lyric-walker.hh"
+#include "debug.hh"
+#include "lyric-item.hh"
+#include "staff-column.hh"
+
+void
+Lyric_walker::process_requests()
+{
+    allow_break();
+    
+    int req_count=0;
+    for (int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++)  {
+       Lyric_req * lreq_l = ptr()->musicalreq_l_arr_[i]->lreq_l();
+       if (!lreq_l)
+           continue;
+       Item *lp = new Lyric_item(lreq_l,req_count++);
+       ptr()->typeset_musical_item( lp);
+    }
+}
+
+Lyric_walker::Lyric_walker(Lyric_staff* lstaff_l)
+    : Staff_walker(lstaff_l, lstaff_l->pstaff_l_->pscore_l_)
+{
+
+}
+
+
diff --git a/lily/midi-def.cc b/lily/midi-def.cc
new file mode 100644 (file)
index 0000000..5bc6b8f
--- /dev/null
@@ -0,0 +1,64 @@
+//
+// midi-def.cc -- implement midi output
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <math.h>
+#include "misc.hh"
+#include "midi-def.hh"
+#include "debug.hh"
+
+// classes, alphasorted
+//     statics
+//     constructors
+//     destructor
+//     routines, alphasorted
+
+Midi_def::Midi_def()
+{
+    set_tempo( Moment( 1, 4 ), 60 );
+    outfile_str_ = "lelie.midi"; 
+}
+
+Midi_def::Midi_def( Midi_def const& midi_c_r )
+{
+    whole_seconds_f_ = midi_c_r.whole_seconds_f_;
+    outfile_str_ = midi_c_r.outfile_str_;
+}
+
+Midi_def::~Midi_def()
+{
+}
+
+Real
+Midi_def::duration_to_seconds_f( Moment moment )
+{
+    if (!moment)
+       return 0;
+    
+    return Moment( whole_seconds_f_ ) * moment;
+}
+
+int
+Midi_def::get_tempo_i( Moment moment )
+{
+    return Moment( whole_seconds_f_ ) * Moment( 60 ) * moment;
+}
+
+void
+Midi_def::print() const
+{
+#ifndef NPRINT
+    mtor << "Midi {4/min: " << Real( 60 ) / ( whole_seconds_f_ * 4 );
+    mtor << "out: " << outfile_str_;
+    mtor << "}\n";
+#endif
+}
+
+void
+Midi_def::set_tempo( Moment moment, int count_per_minute_i )
+{
+    whole_seconds_f_ = Moment( count_per_minute_i ) / Moment( 60 ) / moment;
+}
diff --git a/lily/midi-item.cc b/lily/midi-item.cc
new file mode 100644 (file)
index 0000000..51ba40d
--- /dev/null
@@ -0,0 +1,228 @@
+//
+// midiitem.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <limits.h>
+#include "proto.hh"
+#include "plist.hh"
+#include "pcol.hh"
+#include "debug.hh"
+#include "misc.hh"
+#include "string.hh"
+#include "string-convert.hh"
+#include "request.hh"
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "midi-item.hh"
+#include "midi-stream.hh"
+
+Midi_chunk::Midi_chunk()
+{
+}
+
+void
+Midi_chunk::add( String str )
+{
+    data_str_ += str;
+}
+
+void
+Midi_chunk::set( String header_str, String data_str, String footer_str )
+{
+    data_str_ = data_str;
+    footer_str_ = footer_str;
+    header_str_ = header_str;
+}
+  
+String
+Midi_chunk::str() const
+{
+    String str = header_str_;
+    String length_str = String_convert::i2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
+    length_str = String_convert::hex2bin_str( length_str );
+    str += length_str;
+    str += data_str_;
+    str += footer_str_;
+    return str;
+}
+
+Midi_duration::Midi_duration( Real seconds_f )
+{
+    seconds_f_ = seconds_f;
+}
+
+String
+Midi_duration::str() const
+{
+    return String( "<duration: " ) + String( seconds_f_ ) + ">";
+}
+
+Midi_header::Midi_header( int format_i, int tracks_i, int clocks_per_4_i )
+{
+    String str;
+       
+    String format_str = String_convert::i2hex_str( format_i, 4, '0' );
+    str += String_convert::hex2bin_str( format_str );
+       
+    String tracks_str = String_convert::i2hex_str( tracks_i, 4, '0' );
+    str += String_convert::hex2bin_str( tracks_str );
+
+    String tempo_str = String_convert::i2hex_str( clocks_per_4_i, 4, '0' );
+    str += String_convert::hex2bin_str( tempo_str );
+
+    set( "MThd", str, "" );
+}
+
+String
+Midi_item::i2varint_str( int i )
+{
+    int buffer_i = i & 0x7f;
+    while ( (i >>= 7) > 0 ) {
+       buffer_i <<= 8;
+       buffer_i |= 0x80;
+       buffer_i += (i & 0x7f);
+    }
+
+    String str;
+    while ( 1 ) {
+       str += (char)buffer_i;
+       if ( buffer_i & 0x80 )
+           buffer_i >>= 8;
+       else
+           break;
+    }
+    return str;
+}
+
+void 
+Midi_item::output_midi( Midi_stream& midi_stream_r ) const
+{
+    midi_stream_r << str();
+}
+
+Midi_key::Midi_key( int accidentals_i, int minor_i )
+{
+       accidentals_i_ = accidentals_i;
+       minor_i_ = minor_i;
+}
+
+String
+Midi_key::str() const
+{
+    String str = "ff5902";
+    str += String_convert::i2hex_str( accidentals_i_, 2, '0' );
+    str += String_convert::i2hex_str( minor_i_, 2, '0' );
+    return String_convert::hex2bin_str( str );
+}
+
+Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo  )
+{
+    assert(melreq_l);
+    pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;   
+    channel_i_ = channel_i;
+
+    // poor man-s staff dynamics:
+    dynamic_byte_ =  (melreq_l)? 0x64 - 0x10 * channel_i_:0;
+    on_b_ = on_bo;
+}
+
+String
+Midi_note::str() const
+{
+    if ( pitch_i_ != INT_MAX ) {
+       Byte status_byte = ( on_b_ ? 0x90 : 0x80 ) + channel_i_;
+       String str = String( (char)status_byte );
+       str += (char)pitch_i_;
+       // poor man-s staff dynamics:
+       str += (char)dynamic_byte_;
+       return str;
+    }
+    return String( "" );
+}
+
+Midi_tempo::Midi_tempo( int per_minute_4_i )
+{
+    per_minute_4_i_ = per_minute_4_i;
+}
+
+String
+Midi_tempo::str() const
+{
+    int useconds_per_4_i = 60 * (int)1e6 / per_minute_4_i_;
+    String str = "ff5103";
+    str += String_convert::i2hex_str( useconds_per_4_i, 6, '0' );
+    return String_convert::hex2bin_str( str );
+}
+
+Midi_text::Midi_text( Midi_text::Type type, String text_str )
+{
+       type_ = type;
+       text_str_ = text_str;
+}
+
+String
+Midi_text::str() const
+{
+       String str = "ff" + String_convert::i2hex_str( type_, 2, '0' );
+       str = String_convert::hex2bin_str( str );
+       str += i2varint_str( text_str_.length_i() );
+       str += text_str_;
+       return str;
+}
+
+Midi_track::Midi_track( int number_i )
+{
+//                4D 54 72 6B     MTrk
+//                00 00 00 3B     chunk length (59)
+//        00      FF 58 04 04 02 18 08    time signature
+//        00      FF 51 03 07 A1 20       tempo
+// FF 59 02 sf mi  Key Signature
+//         sf = -7:  7 flats
+//         sf = -1:  1 flat
+//         sf = 0:  key of C
+//         sf = 1:  1 sharp
+//         sf = 7: 7 sharps
+//         mi = 0:  major key
+//         mi = 1:  minor key
+
+    number_i_ = number_i;
+       
+    char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
+//     "00" "ff51" "0307" "a120"
+// why a key at all, in midi?
+// key: C
+//     "00" "ff59" "02" "00" "00"
+// key: F (scsii-menuetto)
+//                               "00" "ff59" "02" "ff" "00"
+       ;
+
+    String data_str;
+    // only for format 0 (currently using format 1)?
+    data_str += String_convert::hex2bin_str( data_ch_c_l );
+
+    char const* footer_ch_c_l = "00" "ff2f" "00";
+    String footer_str = String_convert::hex2bin_str( footer_ch_c_l );
+
+    set( "MTrk", data_str, footer_str );
+}
+
+void 
+Midi_track::add( int delta_time_i, String event_str )
+{
+    assert(delta_time_i >= 0);
+    Midi_chunk::add( i2varint_str( delta_time_i ) + event_str );
+}
+
+void 
+Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
+{
+    // use convention of 384 clocks per 4
+    // use Duration_convert
+    int delta_time_i = delta_time_moment * Moment( 384 ) / Moment( 1, 4 );
+    add( delta_time_i, mitem_l->str() );
+}
+
diff --git a/lily/midi-stream.cc b/lily/midi-stream.cc
new file mode 100644 (file)
index 0000000..88e5eb2
--- /dev/null
@@ -0,0 +1,90 @@
+//
+// midistream.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <fstream.h>
+#include <time.h>
+#include "string.hh"
+#include "string-convert.hh"
+#include "main.hh"
+#include "misc.hh"
+#include "midi-item.hh"
+#include "midi-stream.hh"
+#include "debug.hh"
+
+Midi_stream::Midi_stream( String filename_str, int tracks_i, int clocks_per_4_i ) 
+{
+    filename_str_ = filename_str;
+    tracks_i_ = tracks_i;
+    clocks_per_4_i_ = clocks_per_4_i;
+    os_p_ = 0;
+    open();
+    header();
+}
+
+Midi_stream::~Midi_stream()
+{
+    delete os_p_;
+}
+
+Midi_stream&
+Midi_stream::operator <<( String str )
+{
+    // still debugging...
+    if ( check_debug )
+       str = String_convert::bin2hex_str( str );
+    // string now 1.0.26-2 handles binary streaming
+    *os_p_ << str;
+    return *this;
+}
+
+Midi_stream&
+Midi_stream::operator <<( Midi_item const& mitem_c_r )
+{
+    mitem_c_r.output_midi( *this );
+    if ( check_debug )
+        *os_p_ << "\n";
+    return *this;
+}
+
+Midi_stream&
+Midi_stream::operator <<( int i )
+{
+    // output binary string ourselves
+    *this << Midi_item::i2varint_str( i );
+    return *this;
+}
+
+void
+Midi_stream::header()
+{
+//    *os_p_ << "% Creator: " << get_version();
+//    *os_p_ << "% Automatically generated, at ";
+//    time_t t(time(0));
+//    *os_p_ << ctime(&t);
+
+//                4D 54 68 64     MThd
+//    String str = "MThd";
+//                00 00 00 06     chunk length
+//                00 01   format 1
+//                00 01   one track
+//                00 60   96 per quarter-note
+
+//    char const ch_c_l = "0000" "0006" "0001" "0001" "0060";
+//    str += String_convert::hex2bin_str( ch_c_l );
+//    *os_p_ << str;
+
+//      *this << Midi_header( 1, 1, tempo_i_ );
+      *this << Midi_header( 1, tracks_i_, clocks_per_4_i_ );
+}
+
+void
+Midi_stream::open()
+{
+    os_p_ = new ofstream( filename_str_ );
+    if ( !*os_p_ )
+       error ("can't open `" + filename_str_ + "\'" );
+}
diff --git a/m2m/include/lily-stream.hh b/m2m/include/lily-stream.hh
new file mode 100644 (file)
index 0000000..8c6622d
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//  lily-stream.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+// should i be named Mudela_stream?
+
+#ifndef LILY_STREAM_HH
+#define LILY_STREAM_HH
+
+/// Lily output
+struct Lily_stream {
+    ostream* os_p_;
+    String filename_str_;
+    int indent_i_;
+    int column_i_;
+    int wrap_column_i_;
+    bool comment_mode_bo_;
+    
+    Lily_stream( String filename_str );
+    ~Lily_stream();
+
+    Lily_stream& operator <<( String str );
+    Lily_stream& operator <<( Midi_event& midi_event_r );
+
+    void check_comment( String str );
+    void header();
+    void indent();
+    void newline();
+    void open();
+    void tnedni();
+};
+
+#endif // LILY_STREAM_HH
+
diff --git a/m2m/include/m2m.hh b/m2m/include/m2m.hh
new file mode 100644 (file)
index 0000000..fd404e4
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// m2m.hh -- generic m2m include file
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef M2M_HH
+#define M2M_HH
+
+// yes, i know this hurts the dependency calc, however, 
+// having includes in headers sucks, and long trial and error
+// include lists also suck.
+// if you want less dependecies, break lib/exe down in smaller
+// modules.
+
+#include <assert.h>
+#include <iostream.h>
+#include <fstream.h>
+#include <limits.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "proto.hh"
+#include "plist.hh"
+#include "debug.hh"
+#ifdef mtor
+#undef mtor
+#endif
+
+#include "string.hh"
+#include "string-convert.hh"
+
+#include "lgetopt.hh"
+
+#include "moment.hh"
+#include "duration.hh"
+#include "input-file.hh"
+#include "source-file.hh"
+#include "source.hh"
+
+// mustn-t do, these get touched!
+// #include "fversion.hh"
+// #include "version.hh"
+
+#include "midi-global.hh"
+
+#include "lily-stream.hh"
+#include "midi-event.hh"
+#include "midi-main.hh"
+#include "midi-score.hh"
+#include "midi-track.hh"
+#include "midi-voice.hh"
+#include "my-midi-lexer.hh"
+#include "my-midi-parser.hh"
+#include "track-column.hh"
+
+#endif // M2M_HH
+
diff --git a/m2m/include/midi-event.hh b/m2m/include/midi-event.hh
new file mode 100644 (file)
index 0000000..faaf60e
--- /dev/null
@@ -0,0 +1,95 @@
+//
+// midi-event.hh -- declare midi_event
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#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();
+       
+       virtual String mudela_str( bool command_mode_bo ) = 0;
+       void output_mudela( Lily_stream& lily_stream_r, bool command_mode_bo );
+       virtual Moment mom();
+};
+
+class Midi_key : public Midi_event {
+public:
+       Midi_key( int accidentals_i, int minor_i );
+
+       String notename_str( int pitch_i );
+       virtual String mudela_str( bool command_mode_bo );
+
+private:
+       int accidentals_i_;
+       int minor_i_;
+       int key_i_;
+};
+
+class Midi_note : public Midi_event {
+public:
+       int const c0_pitch_i_c_ = 60;
+
+       Midi_note( String name_str, Duration dur );
+       virtual Moment mom();
+       virtual String mudela_str( bool command_mode_bo );
+       
+private:
+       bool const simple_plet_bo_ = false;
+       Duration dur_;
+       String name_str_;
+};
+
+class Midi_tempo : public Midi_event {
+public:
+       Midi_tempo( int useconds_per_4_i );
+
+       int get_tempo_i( Moment moment );
+       virtual String mudela_str( bool command_mode_bo );
+
+private:
+       int useconds_per_4_i_;
+       Real seconds_per_1_f_;
+};
+
+class Midi_text : public Midi_event {
+public:
+       enum Type { 
+               TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, 
+               MARKER, CUE_POINT
+       };
+       Midi_text( Midi_text::Type type,  String str );
+       virtual String mudela_str( bool command_mode_bo );
+private:
+       Type type_;
+       String text_str_;
+};
+
+class Midi_time : public Midi_event {
+public:
+       Midi_time( int num_i, int den_i, int division_4_i, int count_32_i );
+
+       Duration i2_dur( int time_i, int division_1_i );
+       int clocks_1_i();
+       virtual String mudela_str( bool command_mode_bo );
+
+private:
+       Real sync_f_;
+       Duration sync_dur_;
+       int clocks_1_i_;
+       int num_i_;
+       int den_i_;
+};
+
+#endif // MIDI_EVENT_HH
+
diff --git a/m2m/include/midi-global.hh b/m2m/include/midi-global.hh
new file mode 100644 (file)
index 0000000..4d499da
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// midi-global.hh -- declare global (sic) stuff for m2m
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_GLOBAL_HH
+#define MIDI_GLOBAL_HH
+
+#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;
+extern bool no_triplets_bo_g;
+void message( String message_str, char const* context_ch_c_l );
+void warning( String message_str, char const* context_ch_c_l );
+void error( String message_str, char const* context_ch_c_l );
+
+String version_str();
+
+#endif // MIDI_GLOBAL_HH
+
diff --git a/m2m/include/midi-main.hh b/m2m/include/midi-main.hh
new file mode 100644 (file)
index 0000000..7392aec
--- /dev/null
@@ -0,0 +1,12 @@
+//
+// midi-main.hh -- global (sic) m2m stuff 
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_MAIN_HH
+#define MIDI_MAIN_HH
+
+#include "midi-global.hh"
+
+#endif // MIDI_MAIN_HH
+
diff --git a/m2m/include/midi-score.hh b/m2m/include/midi-score.hh
new file mode 100644 (file)
index 0000000..08cd69b
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// midi-score.hh -- declare midi_score
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_SCORE_HH
+#define MIDI_SCORE_HH
+
+/// (midi_score)
+class Midi_score {
+public:
+       Midi_score( int format_i, int tracks_i, int tempo_i );
+       ~Midi_score();
+
+       void add_track( Midi_track* midi_track_p );
+
+       int output_mudela( String filename_str );
+       void process();
+
+private:
+       IPointerList<Midi_track*> midi_track_p_list_;
+       int format_i_;
+       int tracks_i_;
+       int tempo_i_;
+};
+
+#endif // MIDI_SCORE_HH
+
diff --git a/m2m/include/midi-track.hh b/m2m/include/midi-track.hh
new file mode 100644 (file)
index 0000000..22e110b
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// midi-track.hh -- declare midi_track
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_TRACK_HH
+#define MIDI_TRACK_HH
+
+/// (midi_track)
+class Midi_track {
+public:
+       Midi_track( int number_i, String copyright_str, String track_name_str, String instrument_str );
+
+       void add_event( Moment mom, Midi_event* midi_event_p );
+       Moment end_mom();
+       String name_str();
+       void output_mudela( Lily_stream& lily_stream_r );
+       Moment next_begin_mom( Moment now_mom );
+       Moment next_end_mom( Moment now_mom );
+       void process();
+       Track_column* tcol_l( Moment mom );
+
+       String copyright_str_;
+       String instrument_str_;
+       String name_str_;
+
+private:
+       void add_begin_at( PointerList<Midi_voice*>& open_voices_r, Moment mom );
+       Midi_voice* get_free_midi_voice_l( Moment mom );
+       void remove_end_at( PointerList<Midi_voice*>& open_voices_r, Moment mom );
+       IPointerList<Track_column*> tcol_p_list_;
+       IPointerList<Midi_voice*> midi_voice_p_list_;
+       int number_i_;
+
+};
+
+#endif // MIDI_TRACK_HH
+
diff --git a/m2m/include/midi-voice.hh b/m2m/include/midi-voice.hh
new file mode 100644 (file)
index 0000000..cf3df84
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// midi-voice.hh -- declare midi_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+/// (midi_voice)
+#ifndef MIDI_VOICE_HH
+#define MIDI_VOICE_HH
+
+class Midi_voice {
+public:
+       Midi_voice( Moment begin_mom );
+
+       void add_event( Midi_event* midi_event_p );
+       Moment begin_mom();
+       Moment end_mom();
+
+       String mudela_str( Moment from_mom, Moment to_mom, bool multiple_bo );
+
+private:
+       Moment begin_mom_;
+       IPointerList<Midi_event*> midi_event_p_list_;
+};
+
+#endif // MIDI_VOICE_HH
+
diff --git a/m2m/include/my-midi-lexer.hh b/m2m/include/my-midi-lexer.hh
new file mode 100644 (file)
index 0000000..032bf67
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// my-midi-lexer.hh -- declare My_midi_lexer
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MY_MIDI_LEXER_HH
+#define MY_MIDI_LEXER_HH
+
+#include <FlexLexer.h>
+#include "proto.hh"
+// #include "fproto.hh"
+#include "varray.hh"
+#include "string.hh"
+
+int yylex();
+void yyerror(const char *s);
+// bool busy_parsing();
+// void kill_lexer();
+// void set_lexer();
+
+/// (midi_lexer)
+class My_midi_lexer : yyFlexLexer {
+public:
+       My_midi_lexer( String filename_str );
+       ~My_midi_lexer();
+
+       int close_i();
+       void error( char const* sz_l );
+       char const* here_ch_c_l();
+       static int varint2_i( String str );
+       int yylex();
+
+private:
+       Input_file* input_file_p_;
+
+public: // ugh
+       int errorlevel_i_;
+};
+
+extern My_midi_lexer* midi_lexer_l_g;
+
+#endif // MY_MIDI_LEXER_HH
+
diff --git a/m2m/include/my-midi-parser.hh b/m2m/include/my-midi-parser.hh
new file mode 100644 (file)
index 0000000..6faf128
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// my-midi-parser.hh -- declare My_midi_parser
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MY_MIDI_PARSER_HH
+#define MY_MIDI_PARSER_HH
+
+// #include "proto.hh"
+// #include "string.hh"
+
+int yyparse();
+
+/// (midi_parser)
+class My_midi_parser {
+public:
+       My_midi_parser( String filename_str );
+       ~My_midi_parser();
+
+       void add_score( Midi_score* midi_score_p );
+       void error( char const* sz_l );
+       int parse();
+       void forward( int i );
+       Moment mom();
+       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_mudela( String filename_str );
+       void reset();
+       void set_division_4( int division_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 );
+
+       int track_i_;
+       String filename_str_;
+       String copyright_str_;
+       String instrument_str_;
+       String track_name_str_;
+
+       Midi_key* midi_key_p_;
+       Midi_tempo* midi_tempo_p_;
+       Midi_time* midi_time_p_;
+
+private:
+       Int64 now_i64_; // 31 bits yields tipically about 1000 bars
+
+       static int const CHANNELS_i = 16;
+       static int const PITCHES_i = 128;
+       Int64 running_i64_i64_a_[ CHANNELS_i ][ PITCHES_i ];
+
+       Midi_score* midi_score_p_;
+       int division_1_i_;
+
+       char const* defined_ch_c_l_;
+       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/m2m/include/track-column.hh b/m2m/include/track-column.hh
new file mode 100644 (file)
index 0000000..0ed0323
--- /dev/null
@@ -0,0 +1,23 @@
+//
+// track-column.hh -- declare Track_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef TRACK_COLUMN_HH
+#define TRACK_COLUMN_HH
+
+/// (tcol)
+class Track_column {
+public:
+       Track_column( Moment mom );
+
+       void add_event( Midi_event* midi_event_p );
+       Moment mom();
+
+//private:
+       IPointerList<Midi_event*> midi_event_p_list_;
+       Moment mom_;
+};
+
+#endif // TRACK_COLUMN_HH
+
diff --git a/m2m/lily-stream.cc b/m2m/lily-stream.cc
new file mode 100644 (file)
index 0000000..71385ab
--- /dev/null
@@ -0,0 +1,122 @@
+//
+// lily-stream.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+// should i be named Mudela_stream?
+
+#include "m2m.hh"
+
+Lily_stream::Lily_stream( String filename_str )
+{
+       filename_str_ = filename_str;
+       os_p_ = 0;
+       indent_i_ = 0;
+       comment_mode_bo_ = false;
+       column_i_ = 0;
+       wrap_column_i_ = 78;
+       open();
+       header();
+}
+
+Lily_stream::~Lily_stream()
+{
+       delete os_p_;
+       if ( indent_i_ )
+               warning( "lily indent level: " + String( indent_i_ ), 0 );
+}
+
+Lily_stream&
+Lily_stream::operator <<( String str )
+{
+       while ( str.length_i() ) {
+               int max_i = wrap_column_i_ - column_i_;
+               String line = str.left_str( max_i );
+
+               while ( max_i && ( max_i < line.length_i() )
+                       && ( isalnum( line[ max_i ] )
+                               || ( line[ max_i ] == '\\' ) ) )
+                       max_i--;
+               if ( max_i )
+                       line = str.left_str( max_i + 1 ); 
+               else // cannot break neatly...
+                       max_i = wrap_column_i_ - column_i_ - 1;
+                       
+               str = str.mid_str( max_i + 1, INT_MAX );
+               *os_p_ << line;
+               check_comment( line );
+               column_i_ += line.length_i();
+               if ( column_i_ >= wrap_column_i_ ) {
+                       //brr.
+                       if ( comment_mode_bo_ )
+                               str = "%" + str;
+                       newline();
+               }
+       }       
+       return *this;
+}
+
+Lily_stream&
+Lily_stream::operator <<( Midi_event& midi_event_r )
+{
+       midi_event_r.output_mudela( *this, false );
+       return *this;
+}
+
+void
+Lily_stream::check_comment( String str )
+{
+       int newline_i = str.index_last_i( '\n' );
+       if ( newline_i != -1 ) {
+               str = str.mid_str( newline_i +1, INT_MAX );
+               comment_mode_bo_ = false;
+       }
+       if ( str.index_i( '%' ) != -1 )
+               comment_mode_bo_ = true;
+}
+
+void
+Lily_stream::header()
+{
+       *os_p_ << "% Creator: " << version_str() << "\n";
+       *os_p_ << "% Automatically generated, at ";
+       time_t t( time( 0 ) );
+       *os_p_ << ctime( &t );
+       *os_p_ << "% from input file: ";
+       *os_p_ << midi_parser_l_g->filename_str_;
+       *os_p_ << "\n\n";    
+}
+
+void
+Lily_stream::indent()
+{
+       indent_i_++;
+       newline();
+}
+
+void
+Lily_stream::newline()
+{
+       *os_p_ << "\n" << String( '\t', indent_i_ );
+       column_i_ = indent_i_ * 8;
+       comment_mode_bo_ = false;
+}
+
+void
+Lily_stream::open()
+{
+       os_p_ = new ofstream( filename_str_ );
+       if ( !*os_p_ )
+               error ( "can't open `" + filename_str_ + "\'", 0 );
+}
+
+void
+Lily_stream::tnedni()
+{
+       assert( indent_i_ > 0 );
+       indent_i_--;
+       newline();
+}
+
diff --git a/m2m/midi-event.cc b/m2m/midi-event.cc
new file mode 100644 (file)
index 0000000..8ec23f9
--- /dev/null
@@ -0,0 +1,214 @@
+//
+// midi-event.cc -- implement Midi_event
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+
+Midi_event::Midi_event()
+{
+}
+
+Moment
+Midi_event::mom()
+{
+       return Moment( 0 );
+}
+
+void
+Midi_event::output_mudela( Lily_stream& lily_stream_r, bool command_mode_bo )
+{
+       lily_stream_r << mudela_str( command_mode_bo ) << String( " " );
+}
+
+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;
+}
+
+String
+Midi_key::mudela_str( bool command_mode_bo )
+{
+       String str = "key\\";
+       if ( !minor_i_ ) 
+               str += String( (char)( key_i_ - 2 + 'A'  ) );
+       else
+               str += String( (char)( key_i_ - 2 + 'a'  ) );
+       if ( !command_mode_bo )
+           str =  String( '\\' ) + str;
+       return str;
+}
+
+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--;
+       String octave_str;
+
+       octave_str += String( '\'', ( pitch_i - Midi_note::c0_pitch_i_c_ ) / 12 );
+       octave_str += String( '`', ( Midi_note::c0_pitch_i_c_ - pitch_i ) / 12 );
+       return octave_str + notename_str;
+}
+
+Midi_note::Midi_note( String name_str, Duration dur )
+{
+       // do i want pitch too?
+       dur_ = dur;
+       name_str_ = name_str;
+}
+
+String
+Midi_note::mudela_str( bool command_mode_bo )
+{
+//     assert( !command_mode_bo );
+// undefined ref to simple_plet_bo_ ??
+//     if ( simple_plet_bo_ )
+//             return name_str_ + Duration_convert::dur2_str( dur_ );
+
+       //ugh
+       String str;
+       if ( dur_.plet_p_ )
+               str += String( "\\plet{ " )
+                       + String_convert::i2dec_str( dur_.plet_p_->iso_i_, 0, 0 )
+                       + "/"
+                       + String_convert::i2dec_str( dur_.plet_p_->type_i_, 0, 0 )
+                       + " } ";
+
+       str += name_str_;
+
+       Duration dur = dur_;
+       dur.set_plet( 0 );
+       str += Duration_convert::dur2_str( dur );
+
+       if ( dur_.plet_p_ )
+               str += String( " \\plet{ 1/1 }" );
+               
+       return str;
+}
+
+Moment
+Midi_note::mom()
+{
+       return Duration_convert::dur2_mom( dur_ );
+}
+
+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;
+}
+
+String
+Midi_tempo::mudela_str( bool command_mode_bo )
+{
+//     assert( command_mode_bo );
+       if ( !command_mode_bo )
+               return "";
+       String str = "tempo 4:";
+       str += String( get_tempo_i( Moment( 1, 4 ) ) );
+       return str;
+}
+
+int
+Midi_tempo::get_tempo_i( Moment moment )
+{
+       return Moment( 60 ) / moment / Moment( seconds_per_1_f_ );
+}
+
+Midi_text::Midi_text( Midi_text::Type type, String text_str )
+{
+       type_ = type;
+       text_str_ = text_str;
+}
+
+String
+Midi_text::mudela_str( bool command_mode_bo )
+{
+       (void)command_mode_bo;
+       if ( !text_str_.length_i() 
+               || ( text_str_.length_i() != (int)strlen( text_str_.ch_c_l() ) ) )
+               return "";
+
+       return "% " + text_str_ + "\n\t";
+}
+
+Midi_time::Midi_time( int num_i, int den_i, int clocks_4_i, int count_32_i )
+       : sync_dur_( 8 )
+{
+       sync_f_ = 1.0;
+       if ( count_32_i != 8 )
+               warning( String( "#32 in quarter: " ) + String( count_32_i ), 0 );
+       num_i_ = num_i;
+       den_i_ = 2 << den_i;
+       clocks_1_i_ = clocks_4_i * 4; 
+}
+
+int
+Midi_time::clocks_1_i()
+{
+       return clocks_1_i_;
+}
+
+Duration
+Midi_time::i2_dur( int time_i, int division_1_i )
+{
+       Moment mom = Duration_convert::i2_mom( time_i, division_1_i );
+       mom /= sync_f_;
+
+       dtor << "\n% (" << time_i << ", " << mom << "): "
+               << sync_f_ << endl;
+
+       Duration dur = Duration_convert::mom2_dur( mom );
+       if ( !dur.type_i_ ) {
+               vtor << "\n% resyncing(" << time_i << ", " << mom << "): "
+                       << sync_f_ << " -> ";
+               mom *= sync_f_;
+               sync_f_ = Duration_convert::sync_f( sync_dur_, mom );
+               vtor << sync_f_ << endl;
+               mom /= sync_f_;
+               dur = Duration_convert::mom2_dur( mom );
+       }
+
+       return dur;
+}
+
+String
+Midi_time::mudela_str( bool command_mode_bo )
+{
+       String str = "meter { "
+               + String( num_i_ ) + "*" + String( den_i_ ) 
+               + " }";
+       if ( !command_mode_bo )
+           str =  String( '\\' ) + str;
+       return str;
+}
+
diff --git a/m2m/midi-main.cc b/m2m/midi-main.cc
new file mode 100644 (file)
index 0000000..488afc0
--- /dev/null
@@ -0,0 +1,191 @@
+//
+// midi-main.cc -- implement silly main() entry point
+// should have Root class.
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+#include "fversion.hh"
+#include "version.hh"
+
+Source source;
+Source* source_l_g = &source;
+
+Verbose level_ver = NORMAL_ver;
+
+// ugh
+bool no_triplets_bo_g = false;
+
+//ugh
+char const* defined_ch_c_l = 0;
+
+// ugh, another global
+String
+find_file( String str )
+{
+    return str;
+}
+
+// ugh, copied from warn.cc, cannot use
+void
+message( String message_str, char const* context_ch_c_l )
+{
+    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(": ");
+    }
+    str += message_str;
+    if ( sourcefile_l ) {
+       str += ":\n";
+       str += sourcefile_l->error_str( context_ch_c_l );
+    }
+//    if ( busy_parsing() )
+//     cerr << endl;
+    cerr << str << endl;
+}
+
+void
+warning( String message_str, char const* context_ch_c_l )
+{
+    message( "warning: " + message_str, context_ch_c_l );
+}
+
+void
+error( String message_str, char const* context_ch_c_l )
+{
+    message( message_str, context_ch_c_l );
+    // since when exits error again?
+    // i-d say: error: errorlevel |= 1; -> no output upon error
+    //          warning: recovery -> output (possibly wrong)
+    if ( midi_lexer_l_g )
+        midi_lexer_l_g->errorlevel_i_ |= 1;
+}
+
+void
+help()
+{
+    btor <<
+       "--debug, -d            be really verbose\n"
+       "--help, -h             this help\n"
+        "--include=DIR, -I DIR add DIR to search path\n"
+        "--no-triplets, -n     assume no triplets\n"
+       "--output=FILE, -o FILE set FILE as default output\n"
+       "--quiet, -q            be quiet\n"
+       "--verbose, -v          be verbose\n"
+       "--warranty, -w         show warranty & copyright\n"
+       ;
+}
+
+void
+identify()
+{
+       mtor << version_str() << 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";
+}
+
+// should simply have Root class...
+String
+version_str()
+{
+       return String ( "This is m2m " ) + VERSIONSTR 
+               + "/FlowerLib " + FVERSIONSTR
+               + " of " +  __DATE__ + " " + __TIME__;
+}
+
+int
+main( int argc_i, char* argv_sz_a[] )
+{
+       Long_option_init long_option_init_a[] = {
+               0, "debug", 'd',
+               0, "help", 'h',
+//             1, "include", 'I',
+               0, "no-triplets", 'n',
+               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 'n':
+                               no_triplets_bo_g = true;
+                               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;
+               if ( !output_str.length_i() ) {
+                       output_str = String( arg_sz ) + ".ly";
+                       // i-m sure there-s already some routine for this
+                       int name_i; // too bad we can-t declare local to if
+                       if ( ( name_i = output_str.index_last_i( '/' ) ) != -1 )
+                               output_str = output_str.mid_str( name_i + 1, INT_MAX );
+               }
+               error_i = midi_parser.output_mudela( output_str );
+               if ( error_i )
+                       return error_i;
+       }
+       return 0;
+}
diff --git a/m2m/midi-score.cc b/m2m/midi-score.cc
new file mode 100644 (file)
index 0000000..541cb8f
--- /dev/null
@@ -0,0 +1,72 @@
+//
+// midi-score.cc -- implement Midi_score
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+
+Midi_score::Midi_score( int format_i, int tracks_i, int tempo_i )
+{
+       format_i_ = format_i;
+       tracks_i_ = tracks_i;
+       tempo_i_ = tempo_i;
+}
+
+Midi_score::~Midi_score()
+{
+}
+
+void
+Midi_score::add_track( Midi_track* midi_track_p )
+{
+       midi_track_p_list_.bottom().add( midi_track_p );
+}
+
+int
+Midi_score::output_mudela( String filename_str )
+{
+       mtor << "Lily output to " << filename_str << " ..." << endl;
+
+       Lily_stream lily_stream( filename_str );
+       for ( PCursor<Midi_track*> midi_track_l_pcur( midi_track_p_list_.top() ); midi_track_l_pcur.ok(); midi_track_l_pcur++ ) {
+               midi_track_l_pcur->output_mudela( lily_stream );
+               lily_stream.newline();
+       }
+
+       lily_stream << "score {";
+       lily_stream.newline();
+
+       for ( PCursor<Midi_track*> midi_track_l_pcur( midi_track_p_list_.top() ); midi_track_l_pcur.ok(); midi_track_l_pcur++ ) {
+               lily_stream << "\tstaff { melodic music { ";
+               lily_stream << midi_track_l_pcur->name_str();
+               lily_stream << " } }";
+               lily_stream.newline();
+       }
+
+       lily_stream.indent();
+               lily_stream << "commands {";
+               lily_stream.indent();
+                       midi_parser_l_g->midi_time_p_->output_mudela( lily_stream, true );
+                       lily_stream.tnedni();
+               lily_stream << "}";
+               lily_stream.newline();
+               lily_stream << "midi {";
+                       lily_stream.indent();
+                       midi_parser_l_g->midi_tempo_p_->output_mudela( lily_stream, true );
+                       lily_stream.tnedni();
+               lily_stream << "}";
+               lily_stream.tnedni();
+
+       lily_stream << "}";
+       lily_stream.newline();
+
+       return 0;
+}
+
+void
+Midi_score::process()
+{
+       for ( PCursor<Midi_track*> i( midi_track_p_list_.top() ); i.ok(); i++ ) 
+               i->process();
+}
+
diff --git a/m2m/midi-template.cc b/m2m/midi-template.cc
new file mode 100644 (file)
index 0000000..1ffe8d2
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// midi-template.cc -- implementemplate
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "proto.hh"
+#include "list.hh"
+#include "list.tcc"
+#include "cursor.tcc"
+
+L_instantiate(void *);
+
+class istream;
+class ostream;
+
+#include "m2m.hh"
+#include "plist.hh"
+#include "plist.tcc"
+
+IPL_instantiate(Midi_event);
+IPL_instantiate(Midi_track);
+PL_instantiate(Midi_voice);
+IPL_instantiate(Midi_voice);
+IPL_instantiate(Source_file);
+IPL_instantiate(Track_column);
+
diff --git a/m2m/midi-track.cc b/m2m/midi-track.cc
new file mode 100644 (file)
index 0000000..6c18f7a
--- /dev/null
@@ -0,0 +1,185 @@
+//
+// midi-track.cc -- implement Midi_track
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+
+Midi_track::Midi_track( int number_i, String copyright_str, String track_name_str, String instrument_str )
+{
+       number_i_ = number_i;
+       copyright_str_ = copyright_str;
+       instrument_str_ = instrument_str;
+       if ( track_name_str.length_i() )
+               name_str_ = track_name_str;
+       else
+               name_str_ = String( "track" ) + String( number_i_ );
+       tcol_p_list_.bottom().add( new Track_column( Moment( 0 ) ) );
+}
+
+void
+Midi_track::add_begin_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
+{
+       for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
+               if ( i->begin_mom() == mom )
+                       open_voices_r.bottom().add( *i );
+}
+
+void
+Midi_track::add_event( Moment mom, Midi_event* midi_event_p )
+{
+       if ( ! midi_event_p )
+               return;
+       tcol_l( mom - midi_event_p->mom() )->add_event( midi_event_p );
+}
+
+// too much red tape?
+String
+Midi_track::name_str()
+{
+       return name_str_;
+}
+
+Moment
+Midi_track::end_mom()
+{
+       // heu..
+       Moment mom = 0.0;
+       for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
+               mom = i->end_mom() >? mom;
+       return mom;
+}
+
+Midi_voice*
+Midi_track::get_free_midi_voice_l( Moment mom )
+{
+       for ( PCursor<Midi_voice*> midi_voice_l_pcur( midi_voice_p_list_.top() ); midi_voice_l_pcur.ok(); midi_voice_l_pcur++ )
+               if ( midi_voice_l_pcur->end_mom() == mom )
+                       return *midi_voice_l_pcur;
+
+       Midi_voice* midi_voice_p = new Midi_voice( mom );
+       Midi_voice* midi_voice_l = midi_voice_p;
+       midi_voice_p_list_.bottom().add( midi_voice_p );
+       return midi_voice_l; 
+}
+
+Moment
+Midi_track::next_begin_mom( Moment now_mom )
+{
+//     Moment begin_mom = Midi_track::end_mom() + 1;
+       Moment begin_mom = Midi_track::end_mom();
+       for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
+//             if ( i->begin_mom() >= now_mom )
+               if ( i->begin_mom() > now_mom )
+                       begin_mom = begin_mom <? i->begin_mom();
+       return begin_mom;
+}
+
+Moment
+Midi_track::next_end_mom( Moment now_mom )
+{
+       Moment end_mom = Midi_track::end_mom();
+       for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
+               if ( i->end_mom() > now_mom )
+                       end_mom = end_mom <? i->end_mom();
+       return end_mom;
+}
+
+void
+Midi_track::process()
+{
+       for ( PCursor<Track_column*> tcol_l_pcur( tcol_p_list_.top() ); tcol_l_pcur.ok(); tcol_l_pcur++ )
+               while ( tcol_l_pcur->midi_event_p_list_.size() ) 
+                       // shit, where has the T* PCursor::remove() gone??
+                       // i don-t want to get and delete, 
+                       // i want to (re)move!
+                       // is it renamed: get vs add/insert ?? (put/remove :-)  
+                       get_free_midi_voice_l( tcol_l_pcur->mom() )->add_event( tcol_l_pcur->midi_event_p_list_.top().remove_p() );
+
+       dtor << "ends: " << endl;
+       int n = 0;
+       for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
+               vtor << "voice " << n++ << ": " << i->end_mom() << endl;
+       dtor << ":sdne" << endl;
+}
+
+
+void
+Midi_track::output_mudela( Lily_stream& lily_stream_r )
+{
+       lily_stream_r << name_str_ << " = music { $";
+       lily_stream_r.indent();
+       lily_stream_r << "% midi copyright:" << copyright_str_;
+       lily_stream_r.newline();
+       lily_stream_r << "% instrument:" << instrument_str_;
+       lily_stream_r.newline();
+
+       PointerList<Midi_voice*> open_voices;
+       Moment now_mom = 0.0;
+       Moment then_mom = 0.0;
+       while ( now_mom < end_mom() ) {
+               add_begin_at( open_voices, now_mom );
+
+               Moment begin_mom = next_begin_mom( now_mom ); 
+               Moment end_mom = next_end_mom( now_mom ); 
+               if ( ( begin_mom > now_mom ) && ( begin_mom < end_mom ) )
+                       then_mom = begin_mom;
+               else 
+                       then_mom = end_mom;
+
+               dtor << "begin: " << begin_mom << " end: " << end_mom << endl;
+               dtor << "slice: " << now_mom << ", " << then_mom << endl;
+
+               if ( open_voices.size() > 1 )
+                       lily_stream_r << "{ ";
+               for ( PCursor<Midi_voice*> i( open_voices.top() ); i.ok(); i++ )
+                       lily_stream_r << i->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
+               if ( open_voices.size() > 1 )
+                       lily_stream_r << "} ";
+               now_mom = then_mom;
+
+               remove_end_at( open_voices, now_mom );
+       }
+       lily_stream_r.tnedni();
+       lily_stream_r << "$} % " << name_str_;
+       lily_stream_r.newline();
+}
+
+void
+Midi_track::remove_end_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
+{
+       for ( PCursor<Midi_voice*> i( open_voices_r.top() ); i.ok(); i++ )
+               if ( i->end_mom() == mom ) {
+                       i.remove_p();  // remove? // no delete; only a copy
+                       if ( !i.ok() )
+                               break;
+               }
+//                     i.del();  // remove? // no delete; only a copy
+// plist is breendet
+// duh, del and get will do a ++, but will fail if they render list empty
+//             if ( i->end_mom() == mom ) {
+//                     if ( i->size() > 1 )
+//                             i.del();
+//                     else
+//                             i.junk(); // what-s in a name? (sic)
+//             }
+}
+
+Track_column*
+Midi_track::tcol_l( Moment mom )
+{
+       for ( PCursor<Track_column*> tcol_l_pcur( tcol_p_list_.top() ); tcol_l_pcur.ok(); tcol_l_pcur++ ) {
+               if ( tcol_l_pcur->mom() == mom )
+                       return *tcol_l_pcur;
+               if ( tcol_l_pcur->mom() > mom ) {
+                       Track_column* tcol_p = new Track_column( mom );
+                       tcol_l_pcur.insert( tcol_p );
+                       return tcol_p;
+               }
+       }
+
+       Track_column* tcol_p = new Track_column( mom );
+       tcol_p_list_.bottom().add( tcol_p );
+       return tcol_p;
+}
+
diff --git a/m2m/midi-voice.cc b/m2m/midi-voice.cc
new file mode 100644 (file)
index 0000000..0d5b4b4
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// midi-voice.cc -- implement midi_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+
+Midi_voice::Midi_voice( Moment begin_mom )
+{
+       begin_mom_ = begin_mom;
+}
+
+void
+Midi_voice::add_event( Midi_event* midi_event_p )
+{
+       midi_event_p_list_.bottom().add( midi_event_p );
+}
+
+Moment 
+Midi_voice::begin_mom()
+{
+       return begin_mom_;
+}
+
+Moment 
+Midi_voice::end_mom()
+{
+       Moment now_mom = begin_mom_;
+       dtor << now_mom << ", ";
+       for ( PCursor<Midi_event*> i( midi_event_p_list_.top() ); i.ok(); i++ ) {
+               dtor << now_mom << ", ";
+               now_mom += i->mom();
+       }
+       dtor << endl;
+       return now_mom;
+}
+
+String 
+Midi_voice::mudela_str( Moment from_mom, Moment to_mom, bool multiple_bo )
+{
+       String str;
+
+       if ( begin_mom() >= to_mom )
+               return "";
+       if ( end_mom() <= from_mom )
+               return "";
+       
+       Moment now_mom = begin_mom();
+       PCursor<Midi_event*> i( midi_event_p_list_.top() );
+       for ( ; i.ok() && now_mom < from_mom ; i++ )
+               now_mom += i->mom();
+       
+       for ( ; i.ok() && now_mom < to_mom ; i++ ) {
+               now_mom += i->mom();
+               str += i->mudela_str( false ) + " ";
+       }
+       
+       if ( str.length_i() && multiple_bo )
+               str = "\\music{ " + str + "} ";
+       return str;
+}
+
diff --git a/m2m/my-midi-lexer.cc b/m2m/my-midi-lexer.cc
new file mode 100644 (file)
index 0000000..22ebe75
--- /dev/null
@@ -0,0 +1,78 @@
+//
+// my-midi-lexer.cc -- implement My_midi_lexer
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.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 )
+{
+       midi_lexer_l_g = this;
+       input_file_p_ = new Input_file( filename_str );
+       switch_streams( input_file_p_->is );
+       errorlevel_i_ = 0;
+}
+
+My_midi_lexer::~My_midi_lexer()
+{
+       delete input_file_p_;
+       midi_lexer_l_g = 0;
+}
+
+void
+My_midi_lexer::error( char const* sz_l )
+{
+    if ( !input_file_p_ ) {
+//     *mlog << "error at EOF" << sz_l << '\n';
+       cerr << "error at EOF" << sz_l << '\n';
+    } else {
+       char const* ch_c_l = here_ch_c_l();
+       if ( ch_c_l ) {
+           ch_c_l--;
+           while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) )
+                   ch_c_l--;
+           ch_c_l++;
+       }
+       errorlevel_i_ |= 1;
+//     ::error( sz_l, ch_c_l );
+       ::error( sz_l, ch_c_l );
+    }
+}
+
+char const*
+My_midi_lexer::here_ch_c_l()
+{
+    return input_file_p_->sourcefile_l_->ch_c_l() + yyin->tellg();
+}
+
+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/m2m/my-midi-parser.cc b/m2m/my-midi-parser.cc
new file mode 100644 (file)
index 0000000..ff0f449
--- /dev/null
@@ -0,0 +1,155 @@
+//
+// my-midi-parser.cc -- implement My_midi_parser
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.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 )
+{
+       midi_parser_l_g = this;
+       filename_str_ = filename_str;
+       midi_lexer_p_ = new My_midi_lexer( filename_str_ );
+       defined_ch_c_l_ = 0;
+       fatal_error_i_ = 0;
+       midi_key_p_ = 0;
+       midi_score_p_ = 0;
+       midi_tempo_p_ = 0;
+       midi_time_p_ = 0;
+       track_i_ = 0;
+       reset();
+}
+
+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_;
+       delete midi_score_p_;
+}
+
+void
+My_midi_parser::reset()
+{
+       delete midi_key_p_;
+       midi_key_p_ = new Midi_key( 0, 0 );
+       // useconds per 4: 250000 === 60 4 per minute
+       delete midi_tempo_p_;
+       midi_tempo_p_ = new Midi_tempo( 250000 );
+       delete midi_time_p_;
+       midi_time_p_ = new Midi_time( 4, 4, 384, 8 );
+       now_i64_ = 0;
+
+       copyright_str_ = "";
+       track_name_str_ = "";
+       instrument_str_ = "";
+
+       for ( int i = 0; i < CHANNELS_i; i++ )
+               for ( int j = 0; j < PITCHES_i; j++ )
+//                     running_i64_i64_a_[ i ][ j ] = -1;
+                       running_i64_i64_a_[ i ][ j ] = 0;
+}
+
+void
+My_midi_parser::add_score( Midi_score* midi_score_p )
+{
+       assert( !midi_score_p_ );
+       midi_score_p_ = midi_score_p;
+       track_i_ = 0;
+}
+
+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 )
+{
+       now_i64_ += i;
+}
+
+Moment
+My_midi_parser::mom()
+{
+       return Duration_convert::i2_mom( now_i64_, division_1_i_ );
+}
+
+void
+My_midi_parser::note_begin( int channel_i, int pitch_i, int dyn_i )
+{
+       // one pitch a channel at time!
+       // heu, what about { < c2 >  < c4 d4 > }
+//     assert( running_i64_i64_a_[ channel_i ][ pitch_i ]  == -1 );
+       running_i64_i64_a_[ channel_i ][ pitch_i ] = now_i64_;
+}
+
+Midi_event*
+My_midi_parser::note_end_midi_event_p( int channel_i, int pitch_i, int dyn_i )
+{
+       Int64 start_i64 = running_i64_i64_a_[ channel_i ][ pitch_i ];
+
+//     running_i64_i64_a_[ channel_i ][ pitch_i ] = -1;
+//     assert( start_i64 != -1 ); // did we start?
+
+       return new Midi_note( midi_key_p_->notename_str( pitch_i ), midi_time_p_->i2_dur( now_i64_ - start_i64, division_1_i_ ) );
+}
+
+int
+My_midi_parser::output_mudela( String filename_str )
+{
+       assert( midi_score_p_ );
+       midi_score_p_->process();
+       return midi_score_p_->output_mudela( filename_str );
+}
+
+int
+My_midi_parser::parse()
+{
+       return ::yyparse();
+}
+
+void
+My_midi_parser::set_division_4( int division_4_i )
+{
+       division_1_i_ = division_4_i * 4;
+       if ( division_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 );
+}
+
diff --git a/m2m/track-column.cc b/m2m/track-column.cc
new file mode 100644 (file)
index 0000000..783206f
--- /dev/null
@@ -0,0 +1,23 @@
+//
+// track-column.cc -- implement Track_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "m2m.hh"
+
+Track_column::Track_column( Moment mom )
+{
+       mom_ = mom;
+}
+
+void 
+Track_column::add_event( Midi_event* midi_event_p )
+{
+       midi_event_p_list_.bottom().add( midi_event_p );
+}
+
+Moment
+Track_column::mom()
+{
+       return mom_;
+}