From: Jan Nieuwenhuizen Date: Mon, 10 Mar 1997 18:01:32 +0000 (+0100) Subject: partial: 0.0.40.jcn X-Git-Tag: release/0.0.40~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=9eb72e332d38f847196b7330f34221e052feac88;p=lilypond.git partial: 0.0.40.jcn --- diff --git a/m2m/include/lily-stream.hh b/m2m/include/lily-stream.hh deleted file mode 100644 index 8c6622d324..0000000000 --- a/m2m/include/lily-stream.hh +++ /dev/null @@ -1,35 +0,0 @@ -// -// lily-stream.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -// 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 deleted file mode 100644 index fd404e4349..0000000000 --- a/m2m/include/m2m.hh +++ /dev/null @@ -1,57 +0,0 @@ -// -// m2m.hh -- generic m2m include file -// -// copyright 1997 Jan Nieuwenhuizen - -#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 -#include -#include -#include -#include -#include - -#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 deleted file mode 100644 index faaf60e5cd..0000000000 --- a/m2m/include/midi-event.hh +++ /dev/null @@ -1,95 +0,0 @@ -// -// midi-event.hh -- declare midi_event -// -// copyright 1997 Jan Nieuwenhuizen - -#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 deleted file mode 100644 index 4d499daf0a..0000000000 --- a/m2m/include/midi-global.hh +++ /dev/null @@ -1,34 +0,0 @@ -// -// midi-global.hh -- declare global (sic) stuff for m2m -// -// copyright 1997 Jan Nieuwenhuizen - -#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-score.hh b/m2m/include/midi-score.hh deleted file mode 100644 index 08cd69b845..0000000000 --- a/m2m/include/midi-score.hh +++ /dev/null @@ -1,28 +0,0 @@ -// -// midi-score.hh -- declare midi_score -// -// copyright 1997 Jan Nieuwenhuizen - -#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_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 deleted file mode 100644 index 22e110b2e5..0000000000 --- a/m2m/include/midi-track.hh +++ /dev/null @@ -1,38 +0,0 @@ -// -// midi-track.hh -- declare midi_track -// -// copyright 1997 Jan Nieuwenhuizen - -#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& open_voices_r, Moment mom ); - Midi_voice* get_free_midi_voice_l( Moment mom ); - void remove_end_at( PointerList& open_voices_r, Moment mom ); - IPointerList tcol_p_list_; - IPointerList 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 deleted file mode 100644 index cf3df84171..0000000000 --- a/m2m/include/midi-voice.hh +++ /dev/null @@ -1,26 +0,0 @@ -// -// midi-voice.hh -- declare midi_voice -// -// copyright 1997 Jan Nieuwenhuizen - -/// (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_p_list_; -}; - -#endif // MIDI_VOICE_HH - diff --git a/m2m/include/my-midi-lexer.hh b/m2m/include/my-midi-lexer.hh deleted file mode 100644 index 032bf6752b..0000000000 --- a/m2m/include/my-midi-lexer.hh +++ /dev/null @@ -1,43 +0,0 @@ -// -// my-midi-lexer.hh -- declare My_midi_lexer -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MY_MIDI_LEXER_HH -#define MY_MIDI_LEXER_HH - -#include -#include "proto.hh" -// #include "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 deleted file mode 100644 index 6faf128a89..0000000000 --- a/m2m/include/my-midi-parser.hh +++ /dev/null @@ -1,62 +0,0 @@ -// -// my-midi-parser.hh -- declare My_midi_parser -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MY_MIDI_PARSER_HH -#define MY_MIDI_PARSER_HH - -// #include "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 deleted file mode 100644 index 0ed0323a97..0000000000 --- a/m2m/include/track-column.hh +++ /dev/null @@ -1,23 +0,0 @@ -// -// track-column.hh -- declare Track_column -// -// copyright 1997 Jan Nieuwenhuizen - -#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_p_list_; - Moment mom_; -}; - -#endif // TRACK_COLUMN_HH - diff --git a/m2m/lily-stream.cc b/m2m/lily-stream.cc deleted file mode 100644 index 71385ab5e7..0000000000 --- a/m2m/lily-stream.cc +++ /dev/null @@ -1,122 +0,0 @@ -// -// lily-stream.cc -// -// source file of the LilyPond music typesetter -// -// (c) 1997 Jan Nieuwenhuizen - -// 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 deleted file mode 100644 index 8ec23f9f95..0000000000 --- a/m2m/midi-event.cc +++ /dev/null @@ -1,214 +0,0 @@ -// -// midi-event.cc -- implement Midi_event -// -// copyright 1997 Jan Nieuwenhuizen - -#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 deleted file mode 100644 index 488afc0a10..0000000000 --- a/m2m/midi-main.cc +++ /dev/null @@ -1,191 +0,0 @@ -// -// midi-main.cc -- implement silly main() entry point -// should have Root class. -// -// copyright 1997 Jan Nieuwenhuizen - -#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 \n" -// "Contributors\n" - " Jan Nieuwenhuizen \n" -// " Mats Bengtsson \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 deleted file mode 100644 index 541cb8f0f3..0000000000 --- a/m2m/midi-score.cc +++ /dev/null @@ -1,72 +0,0 @@ -// -// midi-score.cc -- implement Midi_score -// -// copyright 1997 Jan Nieuwenhuizen - -#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_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_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 i( midi_track_p_list_.top() ); i.ok(); i++ ) - i->process(); -} - diff --git a/m2m/midi-template.cc b/m2m/midi-template.cc deleted file mode 100644 index 1ffe8d2a1b..0000000000 --- a/m2m/midi-template.cc +++ /dev/null @@ -1,26 +0,0 @@ -// -// midi-template.cc -- implementemplate -// -// copyright 1997 Jan Nieuwenhuizen - -#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 deleted file mode 100644 index 6c18f7a150..0000000000 --- a/m2m/midi-track.cc +++ /dev/null @@ -1,185 +0,0 @@ -// -// midi-track.cc -- implement Midi_track -// -// copyright 1997 Jan Nieuwenhuizen - -#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& open_voices_r, Moment mom ) -{ - for ( PCursor 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 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_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 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 begin_mom(); - return begin_mom; -} - -Moment -Midi_track::next_end_mom( Moment now_mom ) -{ - Moment end_mom = Midi_track::end_mom(); - for ( PCursor i( midi_voice_p_list_.top() ); i.ok(); i++ ) - if ( i->end_mom() > now_mom ) - end_mom = end_mom end_mom(); - return end_mom; -} - -void -Midi_track::process() -{ - for ( PCursor 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 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 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 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& open_voices_r, Moment mom ) -{ - for ( PCursor 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 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 deleted file mode 100644 index 0d5b4b446c..0000000000 --- a/m2m/midi-voice.cc +++ /dev/null @@ -1,62 +0,0 @@ -// -// midi-voice.cc -- implement midi_voice -// -// copyright 1997 Jan Nieuwenhuizen - -#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 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 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 deleted file mode 100644 index 22ebe75372..0000000000 --- a/m2m/my-midi-lexer.cc +++ /dev/null @@ -1,78 +0,0 @@ -// -// my-midi-lexer.cc -- implement My_midi_lexer -// -// copyright 1997 Jan Nieuwenhuizen - -#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 deleted file mode 100644 index ff0f44935e..0000000000 --- a/m2m/my-midi-parser.cc +++ /dev/null @@ -1,155 +0,0 @@ -// -// my-midi-parser.cc -- implement My_midi_parser -// -// copyright 1997 Jan Nieuwenhuizen - -#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 deleted file mode 100644 index 783206fb93..0000000000 --- a/m2m/track-column.cc +++ /dev/null @@ -1,23 +0,0 @@ -// -// track-column.cc -- implement Track_column -// -// copyright 1997 Jan Nieuwenhuizen - -#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_; -} diff --git a/mi2mu/include/lily-stream.hh b/mi2mu/include/lily-stream.hh new file mode 100644 index 0000000000..8c6622d324 --- /dev/null +++ b/mi2mu/include/lily-stream.hh @@ -0,0 +1,35 @@ +// +// lily-stream.hh -- part of LilyPond +// +// copyright 1997 Jan Nieuwenhuizen + +// 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/mi2mu/include/mi2mu.hh b/mi2mu/include/mi2mu.hh new file mode 100644 index 0000000000..0210f523eb --- /dev/null +++ b/mi2mu/include/mi2mu.hh @@ -0,0 +1,56 @@ +// +// mi2mu.hh -- generic mi2mu include file +// +// copyright 1997 Jan Nieuwenhuizen + +#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 +#include +#include +#include +#include +#include + +#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-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/mi2mu/include/midi-event.hh b/mi2mu/include/midi-event.hh new file mode 100644 index 0000000000..3f06353c4a --- /dev/null +++ b/mi2mu/include/midi-event.hh @@ -0,0 +1,96 @@ +// +// midi-event.hh -- declare midi_event +// +// copyright 1997 Jan Nieuwenhuizen + +#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 ); + Moment bar_mom(); + +private: + Real sync_f_; + Duration sync_dur_; + int clocks_1_i_; + int num_i_; + int den_i_; +}; + +#endif // MIDI_EVENT_HH + diff --git a/mi2mu/include/midi-global.hh b/mi2mu/include/midi-global.hh new file mode 100644 index 0000000000..29ba252a83 --- /dev/null +++ b/mi2mu/include/midi-global.hh @@ -0,0 +1,34 @@ +// +// midi-global.hh -- declare global (sic) stuff for mi2mu +// +// copyright 1997 Jan Nieuwenhuizen + +#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/mi2mu/include/midi-score.hh b/mi2mu/include/midi-score.hh new file mode 100644 index 0000000000..08cd69b845 --- /dev/null +++ b/mi2mu/include/midi-score.hh @@ -0,0 +1,28 @@ +// +// midi-score.hh -- declare midi_score +// +// copyright 1997 Jan Nieuwenhuizen + +#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_p_list_; + int format_i_; + int tracks_i_; + int tempo_i_; +}; + +#endif // MIDI_SCORE_HH + diff --git a/mi2mu/include/midi-track.hh b/mi2mu/include/midi-track.hh new file mode 100644 index 0000000000..22e110b2e5 --- /dev/null +++ b/mi2mu/include/midi-track.hh @@ -0,0 +1,38 @@ +// +// midi-track.hh -- declare midi_track +// +// copyright 1997 Jan Nieuwenhuizen + +#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& open_voices_r, Moment mom ); + Midi_voice* get_free_midi_voice_l( Moment mom ); + void remove_end_at( PointerList& open_voices_r, Moment mom ); + IPointerList tcol_p_list_; + IPointerList midi_voice_p_list_; + int number_i_; + +}; + +#endif // MIDI_TRACK_HH + diff --git a/mi2mu/include/midi-voice.hh b/mi2mu/include/midi-voice.hh new file mode 100644 index 0000000000..cf3df84171 --- /dev/null +++ b/mi2mu/include/midi-voice.hh @@ -0,0 +1,26 @@ +// +// midi-voice.hh -- declare midi_voice +// +// copyright 1997 Jan Nieuwenhuizen + +/// (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_p_list_; +}; + +#endif // MIDI_VOICE_HH + diff --git a/mi2mu/include/my-midi-lexer.hh b/mi2mu/include/my-midi-lexer.hh new file mode 100644 index 0000000000..032bf6752b --- /dev/null +++ b/mi2mu/include/my-midi-lexer.hh @@ -0,0 +1,43 @@ +// +// my-midi-lexer.hh -- declare My_midi_lexer +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MY_MIDI_LEXER_HH +#define MY_MIDI_LEXER_HH + +#include +#include "proto.hh" +// #include "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/mi2mu/include/my-midi-parser.hh b/mi2mu/include/my-midi-parser.hh new file mode 100644 index 0000000000..66de991259 --- /dev/null +++ b/mi2mu/include/my-midi-parser.hh @@ -0,0 +1,63 @@ +// +// my-midi-parser.hh -- declare My_midi_parser +// +// copyright 1997 Jan Nieuwenhuizen + +#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 bar_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: + I64 now_i64_; // 31 bits yields tipically about 1000 bars + + static int const CHANNELS_i = 16; + static int const PITCHES_i = 128; + I64 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/mi2mu/include/track-column.hh b/mi2mu/include/track-column.hh new file mode 100644 index 0000000000..0ed0323a97 --- /dev/null +++ b/mi2mu/include/track-column.hh @@ -0,0 +1,23 @@ +// +// track-column.hh -- declare Track_column +// +// copyright 1997 Jan Nieuwenhuizen + +#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_p_list_; + Moment mom_; +}; + +#endif // TRACK_COLUMN_HH + diff --git a/mi2mu/lily-stream.cc b/mi2mu/lily-stream.cc new file mode 100644 index 0000000000..244e36f43b --- /dev/null +++ b/mi2mu/lily-stream.cc @@ -0,0 +1,141 @@ +// +// lily-stream.cc +// +// source file of the LilyPond music typesetter +// +// (c) 1997 Jan Nieuwenhuizen + +// should i be named Mudela_stream? + +#include "mi2mu.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_ = 60; + 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 ) +{ + static String nobreak_str = "\\`'_-.^<>*@"; + while ( str.length_i() ) { + int max_i = wrap_column_i_ - column_i_ - 1; + int i = str.length_i() - 1 8 * indent_i_ ) { + newline(); + if ( comment_mode_bo_ && ( str[ 0 ] != '%' ) ) + str = '%' + str; + continue; + } + else { // cannot break neatly... + i = max_i; + } + } + + String line = str.left_str( i + 1 ); + str = str.mid_str( i + 1, INT_MAX ); + *os_p_ << line; + if ( nl_i != -1 ) + newline(); + else + check_comment( line ); + column_i_ += line.length_i(); + if ( str.length_i() || ( 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 ); + *os_p_ << flush; + 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_ << endl << 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/mi2mu/main.cc b/mi2mu/main.cc new file mode 100644 index 0000000000..4971f451b2 --- /dev/null +++ b/mi2mu/main.cc @@ -0,0 +1,180 @@ +// +// main.cc -- implement silly main() entry point +// should have Root class. +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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 = "mi2mu: "; + 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; // until we have fine output manager... + 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" + "Mi2mu, translate midi to mudela.\n" + "Copyright (C) 1997 by\n" + " Han-Wen Nienhuys \n" +// "Contributors\n" + " Jan Nieuwenhuizen \n" +// " Mats Bengtsson \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[] ) +{ + 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/mi2mu/midi-event.cc b/mi2mu/midi-event.cc new file mode 100644 index 0000000000..2317fdb695 --- /dev/null +++ b/mi2mu/midi-event.cc @@ -0,0 +1,223 @@ +// +// midi-event.cc -- implement Midi_event +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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 ( accidentals_i >= 0 ) + key_i_ = ( ( accidentals_i % 7 )[ "cgdaebf" ] - 'a' - 2 ) % 7; + else + key_i_ = ( ( -accidentals_i % 7 )[ "cfbeadg" ] - 'a' - 2 ) % 7; +} + +String +Midi_key::mudela_str( bool command_mode_bo ) +{ + String str = "key\\"; + if ( !minor_i_ ) + str += String( (char)( ( key_i_ + 2 ) % 7 + 'A' ) ); + else // heu, -2: should be - 1 1/2: A -> fis + str += String( (char)( ( key_i_ + 2 - 2 ) % 7 + 'a' ) ); + if ( !command_mode_bo ) + str = String( '\\' ) + str; + str = String( "%" ) + str + "\n"; // "\key\F" not supported yet... + 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 ( accidental_i && ( accidentals_i_ < 0 ) ) { + accidental_i = - accidental_i; + notename_i = ( notename_i + 1 ) % 7; + } + + String notename_str = (char)( ( ( notename_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_ + 11 - 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; +// huh, is it not per 4? +// seconds_per_1_f_ = (Real)useconds_per_4_i_ * 4 / 1e6; + seconds_per_1_f_ = (Real)useconds_per_4_i_ * 8 / 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; +} + +Moment +Midi_time::bar_mom() +{ + return Moment( num_i_ ) * Duration_convert::dur2_mom( Duration( den_i_ ) ); +} + +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/mi2mu/midi-score.cc b/mi2mu/midi-score.cc new file mode 100644 index 0000000000..ce4e230a23 --- /dev/null +++ b/mi2mu/midi-score.cc @@ -0,0 +1,79 @@ +// +// midi-score.cc -- implement Midi_score +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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; + + int track_i = 0; + Lily_stream lily_stream( filename_str ); + for ( PCursor i( midi_track_p_list_.top() ); i.ok(); i++ ) { + mtor << "track " << track_i++ << ": " << flush; + i->output_mudela( lily_stream ); + lily_stream.newline(); + mtor << endl; + } + + lily_stream << "score {"; + lily_stream.newline(); + + for ( PCursor i( midi_track_p_list_.top() ); i.ok(); i++ ) { + lily_stream << "\tstaff { melodic music { "; + lily_stream << i->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() +{ + int track_i = 0; + for ( PCursor i( midi_track_p_list_.top() ); i.ok(); i++ ) { + mtor << "track " << track_i++ << ": " << flush; + i->process(); + mtor << endl; + } +} + diff --git a/mi2mu/midi-track.cc b/mi2mu/midi-track.cc new file mode 100644 index 0000000000..f94720cf2a --- /dev/null +++ b/mi2mu/midi-track.cc @@ -0,0 +1,200 @@ +// +// midi-track.cc -- implement Midi_track +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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& open_voices_r, Moment mom ) +{ + for ( PCursor i( midi_voice_p_list_.top() ); i.ok(); i++ ) + if ( i->begin_mom() == mom ) { + dtor << "open_voices (" << open_voices_r.size() << "): +1\n"; + 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 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 i( midi_voice_p_list_.top() ); i.ok(); i++ ) + if ( i->end_mom() == mom ) + return *i; + + 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 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 begin_mom(); + return begin_mom; +} + +Moment +Midi_track::next_end_mom( Moment now_mom ) +{ + Moment end_mom = Midi_track::end_mom(); + for ( PCursor i( midi_voice_p_list_.top() ); i.ok(); i++ ) + if ( i->end_mom() > now_mom ) + end_mom = end_mom end_mom(); + return end_mom; +} + +void +Midi_track::process() +{ + int bar_i = 1; + Moment bar_mom = midi_parser_l_g->midi_time_p_->bar_mom(); + + for ( PCursor i( tcol_p_list_.top() ); i.ok(); i++ ) { + int bars_i = (int)( i->mom() / bar_mom ); + if ( bars_i > bar_i ) + mtor << '[' << bar_i << flush; + while ( i->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( i->mom() )->add_event( i->midi_event_p_list_.top().remove_p() ); + if ( bars_i > bar_i ) { + bar_i++; + mtor << ']' << flush; + } + } + + dtor << "ends: " << endl; + int n = 0; + for ( PCursor 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(); + + int bar_i = 1; + Moment bar_mom = midi_parser_l_g->midi_time_p_->bar_mom(); + + PointerList open_voices; + Moment now_mom = 0.0; + Moment then_mom = 0.0; + while ( now_mom < end_mom() ) { + int bars_i = (int)( now_mom / bar_mom ); + if ( bars_i > bar_i ) + mtor << '[' << bar_i << flush; + 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 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 ); + if ( bars_i > bar_i ) { + bar_i++; + mtor << ']' << flush; + } + } + lily_stream_r.tnedni(); + lily_stream_r << "$} % " << name_str_; + lily_stream_r.newline(); +} + +void +Midi_track::remove_end_at( PointerList& open_voices_r, Moment mom ) +{ + for ( PCursor i( open_voices_r.top() ); i.ok(); i++ ) + if ( i->end_mom() <= mom ) { + dtor << "open_voices (" << open_voices_r.size() << "): -1\n"; + i.remove_p(); // remove? // no delete; only a copy + if ( !i.ok() ) + break; + } +} + +Track_column* +Midi_track::tcol_l( Moment mom ) +{ + for ( PCursor i( tcol_p_list_.top() ); i.ok(); i++ ) { + if ( i->mom() == mom ) + return *i; + if ( i->mom() > mom ) { + Track_column* tcol_p = new Track_column( mom ); + i.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/mi2mu/midi-voice.cc b/mi2mu/midi-voice.cc new file mode 100644 index 0000000000..e963be2f1c --- /dev/null +++ b/mi2mu/midi-voice.cc @@ -0,0 +1,62 @@ +// +// midi-voice.cc -- implement midi_voice +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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 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 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/mi2mu/my-midi-lexer.cc b/mi2mu/my-midi-lexer.cc new file mode 100644 index 0000000000..843899567b --- /dev/null +++ b/mi2mu/my-midi-lexer.cc @@ -0,0 +1,78 @@ +// +// my-midi-lexer.cc -- implement My_midi_lexer +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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/mi2mu/my-midi-parser.cc b/mi2mu/my-midi-parser.cc new file mode 100644 index 0000000000..e35369abfd --- /dev/null +++ b/mi2mu/my-midi-parser.cc @@ -0,0 +1,160 @@ +// +// my-midi-parser.cc -- implement My_midi_parser +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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; + bar_i_ = 1; + 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; + bar_i_ = 1; + + 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; + bar_i_ = 1; +} + +void +My_midi_parser::error( char const* sz_l ) +{ + midi_lexer_l_g->error( sz_l ); + + if ( fatal_error_i_ ) + exit( fatal_error_i_ ); +} + +void +My_midi_parser::forward( int i ) +{ + 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 ) +{ + I64 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_ ); + mtor << "\nProcessing..." << endl; + midi_score_p_->process(); + return midi_score_p_->output_mudela( filename_str ); +} + +int +My_midi_parser::parse() +{ + mtor << "\nParsing..." << flush; + 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/mi2mu/template.cc b/mi2mu/template.cc new file mode 100644 index 0000000000..be7a2a2352 --- /dev/null +++ b/mi2mu/template.cc @@ -0,0 +1,26 @@ +// +// template.cc -- implementemplate +// +// copyright 1997 Jan Nieuwenhuizen + +#include "proto.hh" +#include "list.hh" +#include "list.tcc" +#include "cursor.tcc" + +L_instantiate(void *); + +class istream; +class ostream; + +#include "mi2mu.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/mi2mu/track-column.cc b/mi2mu/track-column.cc new file mode 100644 index 0000000000..57b072b3b9 --- /dev/null +++ b/mi2mu/track-column.cc @@ -0,0 +1,23 @@ +// +// track-column.cc -- implement Track_column +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.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_; +} diff --git a/mi2mu/version.cc b/mi2mu/version.cc new file mode 100644 index 0000000000..cb58c6b5b2 --- /dev/null +++ b/mi2mu/version.cc @@ -0,0 +1,18 @@ +// +// version.cc -- implement inexpensive versioning +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mi2mu.hh" +#include "fversion.hh" +#include "version.hh" + +// should simply have Root class... +String +version_str() +{ + return String ( "This is mi2mu " ) + VERSIONSTR + + "/FlowerLib " + FVERSIONSTR + + " of " + __DATE__ + " " + __TIME__; +} +