From: Jan Nieuwenhuizen Date: Fri, 9 Jul 1999 12:54:17 +0000 (+0200) Subject: partial: 1.1.55.jcn X-Git-Tag: release/1.1.55~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c0c6d3c94c67e65cd90a3f5a746faec73823b981;p=lilypond.git partial: 1.1.55.jcn --- diff --git a/mi2mu/include/mi2mu-global.hh b/mi2mu/include/mi2mu-global.hh deleted file mode 100644 index 4ed873fb54..0000000000 --- a/mi2mu/include/mi2mu-global.hh +++ /dev/null @@ -1,33 +0,0 @@ -// -// mi2mu-global.hh -- declare global (sic) stuff for mi2mu -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MI2MU_GLOBAL_HH -#define MI2MU_GLOBAL_HH - -#include "string.hh" -#include "proto.hh" - -#define monitor_p_g &cout -enum Verbose { QUIET_ver, BRIEF_ver, NORMAL_ver, VERBOSE_ver, DEBUG_ver }; -extern Verbose level_ver; -#if 0 // NPRINT - // not what i want, all output goes through tors. - // set verbosity level. - #define LOGOUT(threshold) if (0) *monitor_p_g -#else - #define LOGOUT(threshold) if (level_ver >= threshold) *monitor_p_g -#endif - -extern Sources* source_l_g; -// huh? -void message (String message_str); //, char const* context_ch_C); -void warning (String message_str); //, char const* context_ch_C); -void error (String message_str); //, char const* context_ch_C); - -String mi2mu_version_str(); -extern bool no_timestamps_b_g;; - -#endif // MI2MU_GLOBAL_HH - diff --git a/mi2mu/include/midi-parser.hh b/mi2mu/include/midi-parser.hh deleted file mode 100644 index 9dca4db212..0000000000 --- a/mi2mu/include/midi-parser.hh +++ /dev/null @@ -1,106 +0,0 @@ -/* - midi-parser.hh -- declare Midi_parser - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - - -#ifndef MIDI_PARSER_HH -#define MIDI_PARSER_HH - -// must, gcc 2.7.2{,.1} hits ico on midi-track-parser.cc:134 (@Midi_note) -#define INLINES - -#ifdef INLINES - -#define next_byte() (inline_next_byte (__FUNCTION__)) -#define peek_byte() (inline_peek_byte (__FUNCTION__)) -#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) - -#else - -#define next_byte()\ - ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ - *info_l_->byte_L_++\ - : (Byte const)exit (__FUNCTION__": unexpected EOF"))); - -#define peek_byte()\ - ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ - *info_l_->byte_L_\ - : (Byte const)exit (__FUNCTION__": unexpected EOF"))); - -#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) - -#endif - -#include "proto.hh" -#include "moment.hh" -#include "mi2mu-proto.hh" - -struct Midi_parser_info -{ - Midi_parser_info(); - int division_1_i_; - int format_i_; - int tracks_i_; - int errorlevel_i_; - Byte const* byte_L_; - Byte const* end_byte_L_; - Source_file* source_l_; - Mudela_score* score_l_; - Moment bar_mom_; -}; - -#include "string.hh" - -class Midi_parser -{ -public: - Midi_parser (); - - Midi_parser_info* info_l_; - -protected: - Byte const* inline_forward_byte_L (char const* fun, int n) - { - if (info_l_->byte_L_ + n < info_l_->end_byte_L_ ) - { - Byte const* p = info_l_->byte_L_; - info_l_->byte_L_ += n; - return p; - } - exit (String (fun) + ": unexpected EOF"); - return 0; - } - -#ifdef INLINES - Byte inline_next_byte (char const* fun) - { - if (info_l_->byte_L_ < info_l_->end_byte_L_) - return *info_l_->byte_L_++; - exit (String (fun) + ": unexpected EOF"); - return 0; - } - - Byte inline_peek_byte (char const* fun) - { - if (info_l_->byte_L_ < info_l_->end_byte_L_) - return *info_l_->byte_L_; - exit (String (fun) + ": unexpected EOF"); - return 0; - } -#endif - - int get_i (int); - String get_str (int); - unsigned get_u (int); - int get_var_i (); - int exit (String); - void error (String); - String message (String); - void warning (String); -}; - -#endif // MIDI_PARSER_HH diff --git a/mi2mu/include/midi-score-parser.hh b/mi2mu/include/midi-score-parser.hh deleted file mode 100644 index 0dc9823705..0000000000 --- a/mi2mu/include/midi-score-parser.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - midi-score-parser.hh -- declare - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - - -#ifndef MIDI_SCORE_PARSER_HH -#define MIDI_SCORE_PARSER_HH - -#include "midi-parser.hh" -#include "proto.hh" -#include "mi2mu-proto.hh" -#include "parray.hh" - -class Midi_score_parser : public Midi_parser -{ -public: - Mudela_score* parse (String filename_str, Sources*); - -private: - void open (String filename_str, Sources*); - - void parse_header (); - // why the #*&$#{%) has Link_array another behaviour than Link_list?? - // int find_earliest_i (Link_array& tracks); - int find_earliest_i (Link_array& tracks); - Mudela_score* parse_score (); -}; - -#endif // MIDI_SCORE_PARSER_HH diff --git a/mi2mu/include/midi-track-parser.hh b/mi2mu/include/midi-track-parser.hh deleted file mode 100644 index d873e198df..0000000000 --- a/mi2mu/include/midi-track-parser.hh +++ /dev/null @@ -1,44 +0,0 @@ -/* - midi-track-parser.hh -- declare - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - - -#ifndef MIDI_TRACK_PARSER_HH -#define MIDI_TRACK_PARSER_HH - -#include "proto.hh" -#include "cons.hh" -#include "moment.hh" -#include "mi2mu-proto.hh" -#include "midi-parser.hh" - -class Midi_track_parser : public Midi_parser -{ -public: - - Midi_track_parser (Midi_parser_info* info_l, int i); - ~Midi_track_parser (); - - Moment at_mom (); - Mudela_staff* parse (Mudela_column* col_l); - -private: - bool eot (); - void note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ); - void note_end_all (Mudela_column* col_l) ; - void parse_delta_time (); - Mudela_item* parse_event (Mudela_column* col_l); - void parse_header (); - - Moment at_mom_; - Byte running_byte_; - Cons_list open_note_l_list_; - Mudela_staff* mudela_staff_p_; - Midi_parser_info* track_info_p_; -}; - -#endif // MIDI_TRACK_PARSER_HH diff --git a/mi2mu/include/mudela-column.hh b/mi2mu/include/mudela-column.hh deleted file mode 100644 index a09cebb469..0000000000 --- a/mi2mu/include/mudela-column.hh +++ /dev/null @@ -1,29 +0,0 @@ -// -// mudela-column.hh -- declare Mudela_column -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MUDELA_COLUMN_HH -#define MUDELA_COLUMN_HH - -#include "proto.hh" -#include "mi2mu-proto.hh" -#include "moment.hh" -#include "cons.hh" - -/// (mudela_column) -class Mudela_column -{ -public: - Mudela_column (Mudela_score* mudela_score_l, Moment mom); - - void add_item (Mudela_item* mudela_item_l); - Moment at_mom (); - - Cons_list mudela_item_l_list_; - Moment at_mom_; - Mudela_score* mudela_score_l_; -}; - -#endif // MUDELA_COLUMN_HH - diff --git a/mi2mu/include/mudela-item.hh b/mi2mu/include/mudela-item.hh deleted file mode 100644 index e1b52b7368..0000000000 --- a/mi2mu/include/mudela-item.hh +++ /dev/null @@ -1,130 +0,0 @@ -// -// mudela-item.hh -- declare mudela_item -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MUDELA_ITEM_HH -#define MUDELA_ITEM_HH - -#include "mi2mu-proto.hh" -#include "string.hh" -#include "moment.hh" -#include "duration.hh" - -// should these: -// * be Mudela_items -// * be Voice_elements/requests -// * get a name-change -// ? - -/// (mudela_item) -class Mudela_item -{ -public: - Mudela_item (Mudela_column* mudela_column_l); - virtual ~Mudela_item (); - - virtual Moment at_mom (); - virtual Moment duration_mom (); - void output (Mudela_stream& mudela_stream_r); - virtual String str () = 0; - - Mudela_column* mudela_column_l_; -}; - -class Mudela_key : public Mudela_item -{ -public: - Mudela_key (int accidentals_i, int minor_i); - - String notename_str (int pitch_i); - virtual String str (); - - //private: - int accidentals_i_; - int minor_i_; -}; - -class Mudela_time_signature : public Mudela_item -{ -public: - Mudela_time_signature (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 (); - int den_i (); - int num_i (); - virtual String str (); - Moment bar_mom (); - -private: - Real sync_f_; - Duration sync_dur_; - int clocks_1_i_; - int num_i_; - int den_i_; -}; - -class Mudela_note : public Mudela_item -{ -public: - Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pitch_i, int dyn_i); - - Duration duration (); - virtual Moment duration_mom (); - virtual String str (); - - // int const c0_pitch_i_c_ = 60; // huh? - static int const c0_pitch_i_c_ = 48; - - static bool const simple_plet_b_s = false; - int channel_i_; - int pitch_i_; - Mudela_column* end_column_l_; -}; - -class Mudela_skip : public Mudela_item -{ -public: - Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom); - - Duration duration (); - virtual Moment duration_mom (); - virtual String str (); - -private: - Moment mom_; -}; - - -class Mudela_tempo : public Mudela_item -{ -public: - Mudela_tempo (int useconds_per_4_i); - - int get_tempo_i (Moment moment); - virtual String str (); - int useconds_per_4_i (); - -private: - int useconds_per_4_i_; - Moment seconds_per_1_mom_; -}; - -class Mudela_text : public Mudela_item -{ -public: - enum Type { - TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, - MARKER, CUE_POINT - }; - Mudela_text (Mudela_text::Type type, String str); - virtual String str (); - - //private: - Type type_; - String text_str_; -}; - -#endif // MUDELA_ITEM_HH - diff --git a/mi2mu/include/mudela-score.hh b/mi2mu/include/mudela-score.hh deleted file mode 100644 index 8e75d028cc..0000000000 --- a/mi2mu/include/mudela-score.hh +++ /dev/null @@ -1,51 +0,0 @@ -// -// mudela-score.hh -- declare Mudela_score -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MUDELA_SCORE_HH -#define MUDELA_SCORE_HH - -#include "mi2mu-proto.hh" -#include "proto.hh" -#include "cons.hh" -#include "parray.hh" - -/// (mudela_score) -class Mudela_score { -public: - Mudela_score (int format_i, int tracks_i, int tempo_i); - ~Mudela_score (); - - void add_item (Mudela_item* mudela_item_p); - void add_staff (Mudela_staff* mudela_staff_p); - - Mudela_column* find_column_l (Moment mom); - Mudela_column* get_column_l (Moment mom); - - void output (String filename_str); - void process (); - - // ugh - Mudela_key* mudela_key_l_; - Mudela_time_signature* mudela_time_signature_l_; - Mudela_tempo* mudela_tempo_l_; - Mudela_staff * last_staff_l_; -private: - void filter_tempo (); - void quantify_columns (); - void quantify_durations (); - void settle_columns (); - - Cons_list mudela_staff_p_list_; - Link_array column_l_array_; - - // ugh, ugh, ugh -public: - int format_i_; - int tracks_i_; - int tempo_i_; -}; - -#endif // MUDELA_SCORE_HH - diff --git a/mi2mu/include/mudela-staff.hh b/mi2mu/include/mudela-staff.hh deleted file mode 100644 index 8c0afa044a..0000000000 --- a/mi2mu/include/mudela-staff.hh +++ /dev/null @@ -1,43 +0,0 @@ -// -// mudela-staff.hh -- declare mudela_staff -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MUDELA_STAFF_HH -#define MUDELA_STAFF_HH - -#include "mi2mu-proto.hh" -#include "proto.hh" -#include "cons.hh" -#include "string.hh" - -/// (mudela_staff) -class Mudela_staff -{ -public: - Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str); - - void add_item (Mudela_item* mudela_item_p); - void eat_voice (Cons_list& items); - String id_str (); - String name_str (); - void output (Mudela_stream& mudela_stream_r); - void process (); - - String copyright_str_; - String instrument_str_; - String name_str_; - Mudela_key* mudela_key_l_; - Mudela_time_signature* mudela_time_signature_l_; - Mudela_tempo* mudela_tempo_l_; - int number_i_; - -private: - void output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i); - - Cons_list mudela_voice_p_list_; - Cons_list mudela_item_p_list_; -}; - -#endif // MUDELA_STAFF_HH - diff --git a/mi2mu/include/mudela-stream.hh b/mi2mu/include/mudela-stream.hh deleted file mode 100644 index 6953a961cd..0000000000 --- a/mi2mu/include/mudela-stream.hh +++ /dev/null @@ -1,41 +0,0 @@ -// -// mudela-stream.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -// should i be named Mudela_stream? - -#ifndef MUDELA_STREAM_HH -#define MUDELA_STREAM_HH - -#include "mi2mu-proto.hh" -#include "string.hh" -#include "scalar.hh" - -/// Lily output -class Mudela_stream { -public: - Mudela_stream (String filename_str); - ~Mudela_stream(); - - Mudela_stream& operator << (Scalar s); - Mudela_stream& operator << (Mudela_item& mudela_item_r); - -private: - void handle_pending_indent(); - void header(); - void open(); - void output (String str); - void output_wrapped (String str); - - ostream* os_p_; - String filename_str_; - int indent_i_; - int column_i_; - int pending_indent_i_; - int wrap_column_i_; - bool comment_mode_b_; -}; - -#endif // MUDELA_STREAM_HH - diff --git a/mi2mu/include/mudela-voice.hh b/mi2mu/include/mudela-voice.hh deleted file mode 100644 index db196da9e6..0000000000 --- a/mi2mu/include/mudela-voice.hh +++ /dev/null @@ -1,26 +0,0 @@ -// -// mudela-voice.hh -- declare Mudela_voice -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MUDELA_VOICE_HH -#define MUDELA_VOICE_HH - -#include "mi2mu-proto.hh" -#include "cons.hh" - -/// (mudela_voice) -class Mudela_voice -{ -public: - Mudela_voice (Mudela_staff* mudela_staff_l); - void add_item (Mudela_item* mudela_item_l); - void output (Mudela_stream& mudela_stream_r); - -private: - Mudela_staff* mudela_staff_l_; - Cons_list mudela_item_l_list_; -}; - -#endif // MUDELA_VOICE_HH - diff --git a/mi2mu/main.cc b/mi2mu/main.cc deleted file mode 100644 index 26e0c66b8e..0000000000 --- a/mi2mu/main.cc +++ /dev/null @@ -1,271 +0,0 @@ -// -// main.cc -- implement silly main () entry point -// should have Root class. -// -// copyright 1997 Jan Nieuwenhuizen - -#include -#include -#include "config.hh" -#include "string-convert.hh" -#include "getopt-long.hh" -#include "file-path.hh" -#include "duration-convert.hh" -#include "source.hh" - -#include "mi2mu-global.hh" -#include "midi-score-parser.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" - -#if HAVE_GETTEXT -#include -#endif - - -// ugh -String filename_str_g; - -// ugh -Mudela_score* mudela_score_l_g = 0; - -bool no_timestamps_b_g = false; - -Sources source; - -static File_path path; - -Verbose level_ver = NORMAL_ver; - -void -usage() -{ - cout << _f ("Usage: %s [OPTION]... [FILE]", "mi2mu"); - cout << '\n'; - cout << _ ("Translate midi-file to mudela"); - cout << '\n'; - cout << '\n'; - cout << _ ("Options:"); - cout << '\n'; - cout << _ ( - " -b, --no-quantify write exact durations, e.g.: a4*385/384\n" - ); - cout << _ ( - " -D, --debug enable debugging output\n" - ); - cout << _ ( - " -h, --help this help\n" - ); - cout << _ ( - " -I, --include=DIR add DIR to search path\n" - ); - cout << _ ( - " -k, --key=ACC[:MINOR] set key: ACC +sharps/-flats; :1 minor\n" - ); - cout << _ ( - " -n, --no-silly assume no plets or double dots, smallest is 32\n" - ); - cout << _ ( - " -o, --output=FILE set FILE as default output\n" - ); - cout << _ ( - " -p, --no-plets assume no plets\n" - ); - cout << _ ( - " -q, --quiet be quiet\n" - ); - cout << _ ( - " -T, --no-timestamps don't timestamp the output\n" - ); - cout << _ ( - " -s, --smallest=N assume no shorter (reciprocal) durations than N\n" - ); - cout << _ ( - " -v, --verbose be verbose\n" - ); - cout << _ ( - " -w, --warranty show warranty and copyright\n" - ); - cout << _ ( - " -x, --no-double-dots assume no double dotted notes\n" - ); - ; -} - -void -identify() -{ - LOGOUT(NORMAL_ver) << mi2mu_version_str() << endl; -} - -void -notice() -{ - LOGOUT(NORMAL_ver) << '\n'; - LOGOUT(NORMAL_ver) << _ ("Mi2mu, translate midi to mudela"); - LOGOUT(NORMAL_ver) << '\n'; - LOGOUT(NORMAL_ver) << _f ("Copyright (c) %s by", "1997, 1998"); - LOGOUT(NORMAL_ver) << '\n'; - LOGOUT(NORMAL_ver) << " " + _ ("Han-Wen Nienhuys ") + "\n"; - LOGOUT(NORMAL_ver) << " " + _ ("Jan Nieuwenhuizen ") + "\n"; - LOGOUT(NORMAL_ver) << '\n'; - LOGOUT(NORMAL_ver) << _ ( - " This program is free software; you can redistribute it and/or\n" - "modify it under the terms of the GNU General Public License version 2\n" - "as published by the Free Software Foundation.\n" - "\n" - " This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" - "General Public License for more details.\n" - "\n" - " You should have received a copy (refer to the file COPYING) of the\n" - "GNU General Public License along with this program; if not, write to\n" - "the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,\n" - "USA.\n"); -} - -int -main (int argc_i, char* argv_sz_a[]) -{ - -#if HAVE_GETTEXT - setlocale (LC_ALL, ""); /* enable locales */ - setlocale (LC_NUMERIC, "C"); /* musn't have comma's in output */ - String name (PACKAGE); - name.to_lower (); - bindtextdomain (name.ch_C (), DIR_LOCALEDIR); - textdomain (name.ch_C ()) ; -#endif - - bool key_override_b = false; - Mudela_key key (0, 0); - - Long_option_init long_option_init_a[] = - { - {0, "no-quantify", 'b'}, - {0, "debug", 'D'}, - {0, "help", 'h'}, - {1, "key", 'k'}, - {0, "no-silly", 'n'}, - {1, "output", 'o'}, - {0, "no-plets", 'p'}, - {0, "quiet", 'q'}, - {1, "smallest", 's'}, - {0, "no-timestamps", 'T'}, - {0, "verbose", 'v'}, - {0, "warranty", 'w'}, - {0, "no-double-dots", 'x'}, - {0,0,0} - }; - Getopt_long getopt_long (argc_i, argv_sz_a, long_option_init_a); - - String output_str; - while (Long_option_init const* long_option_init_p = getopt_long()) - switch (long_option_init_p->shortname) - { - case 'b': - Duration_convert::no_quantify_b_s = true; - break; - case 'D': - level_ver = DEBUG_ver; - break; - case 'h': - identify(); - usage(); - exit (0); - break; -// case 'I': -// path->push (getopt_long.optional_argument_ch_C_); -// break; - case 'k': - { - String str = getopt_long.optional_argument_ch_C_; - int i = str.index_i (':'); - i = (i >=0 ? i : str.length_i ()); - key.accidentals_i_ = String_convert::dec2_i (str.left_str (i)); - key.minor_i_ = (int)(bool)String_convert::dec2_i (str.cut_str (i + 1, str.length_i ())); - key_override_b = true; - break; - } - case 'n': - Duration_convert::no_double_dots_b_s = true; - Duration_convert::no_triplets_b_s = true; - Duration_convert::no_smaller_than_i_s = 5; - break; - case 'o': - output_str = getopt_long.optional_argument_ch_C_; - break; - case 'p': - Duration_convert::no_triplets_b_s = true; - break; - case 'q': - level_ver = QUIET_ver; - break; - case 'T': - no_timestamps_b_g = true; - break; - case 's': - { - int i = String_convert::dec2_i (getopt_long.optional_argument_ch_C_); - if (!i) - { - identify(); - usage(); - exit (2); //usage - } - Duration_convert::no_smaller_than_i_s = - Duration_convert::i2_type(i); - } - break; - case 'v': - level_ver = VERBOSE_ver; - break; - case 'w': - identify(); - notice(); - exit (0); - break; - case 'x': - Duration_convert::no_double_dots_b_s = true; - break; - default: - assert (0); - break; - } - - // flag -q must be checked first - identify(); - - path.add (""); - source.set_binary (true); - source.set_path (&path); - - char const* arg_sz = 0; - while ( (arg_sz = getopt_long.get_next_arg ())) - { - filename_str_g = arg_sz; - Midi_score_parser midi_parser; - Mudela_score* score_p = midi_parser.parse (arg_sz, &source); - - if (!score_p) - return 1; - - // if given on command line: override - if (key_override_b || !score_p->mudela_key_l_) - score_p->mudela_key_l_ = &key; - mudela_score_l_g = score_p; - score_p->process(); - - if (!output_str.length_i ()) - { - String d, dir, base, ext; - split_path (arg_sz, d, dir, base, ext); - output_str = base + ext + ".ly"; - } - - score_p->output (output_str); - delete score_p; - } - return 0; -} diff --git a/mi2mu/mi2mu-version.cc b/mi2mu/mi2mu-version.cc deleted file mode 100644 index 113512d363..0000000000 --- a/mi2mu/mi2mu-version.cc +++ /dev/null @@ -1,20 +0,0 @@ -// -// version.cc -- implement inexpensive versioning -// -// copyright 1997 Jan Nieuwenhuizen - -#include -#include "config.hh" -#include "version.hh" - -#define VERSION_SZ MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL "." MY_PATCH_LEVEL - -static char *s = "mi2mu " VERSION_SZ; - - -const char * -mi2mu_version_sz() -{ - return s; -} - diff --git a/mi2mu/midi-parser.cc b/mi2mu/midi-parser.cc deleted file mode 100644 index eafd50c004..0000000000 --- a/mi2mu/midi-parser.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - midi-parser.cc -- implement Midi_parser[_info] - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - -#include -#include "string-convert.hh" -#include "source-file.hh" -#include "mi2mu-global.hh" -#include "midi-parser.hh" - -Midi_parser_info::Midi_parser_info () -{ - division_1_i_ = 0; - format_i_ = 0; - tracks_i_ = 0; - errorlevel_i_ = 0; - byte_L_ = 0; - end_byte_L_ = 0; - score_l_ = 0; -} - -Midi_parser::Midi_parser () -{ - info_l_ = 0; -} - -int -Midi_parser::exit (String str) -{ - error (str); - ::exit (1); - return 0; -} - -void -Midi_parser::error (String str) -{ - ::message (message (str)); -} - -int -Midi_parser::get_i (int n) -{ - assert (n <= (int)sizeof(int)); - return String_convert::bin2_i (get_str (n)); -} - -unsigned -Midi_parser::get_u (int n) -{ - assert (n <= (int)sizeof(int)); - return String_convert::bin2_i (get_str (n)); -} - -String -Midi_parser::get_str (int n) -{ - assert (n >= 0); - if (!n) - warning (_ ("zero length string encountered")); - - Byte const* p = forward_byte_L (n); - return String (p, n); -} - -int -Midi_parser::get_var_i () -{ - int var_i = 0; - - while (1) - { - Byte byte = next_byte (); - var_i <<= 7; - var_i += byte & 0x7f; - if (!(byte & 0x80)) - return var_i; - } - exit ("get_var_i:"); - return 0; -} - -String -Midi_parser::message (String str) -{ - return String ("mi2mu: ") - + info_l_->source_l_->name_str () + ": " - + String_convert::i2dec_str (info_l_->source_l_->line_i ((char const*)info_l_->byte_L_), 0, 0) + ": " - + str + "\n" - + info_l_->source_l_->error_str ((char const*)info_l_->byte_L_); -} - -void -Midi_parser::warning (String str) -{ - ::message (message (String (_ ("warning: ")) + str)); -} diff --git a/mi2mu/midi-score-parser.cc b/mi2mu/midi-score-parser.cc deleted file mode 100644 index c20fe468e2..0000000000 --- a/mi2mu/midi-score-parser.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - midi-score-parser.cc -- implement - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - -#include "moment.hh" -#include "source-file.hh" -#include "source.hh" -#include "mi2mu-global.hh" -#include "midi-score-parser.hh" -#include "midi-track-parser.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" - - -void -Midi_score_parser::open (String filename_str, Sources* sources_l) -{ - info_l_->source_l_ = sources_l->get_file_l (filename_str); - if (!info_l_->source_l_) - ::error (_f ("can't find file: `%s\'", filename_str)); - info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C (); - info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1; -} - -Mudela_score* -Midi_score_parser::parse (String filename_str, Sources* sources_l) -{ - Midi_parser_info info; - info_l_ = &info; - open (filename_str, sources_l); - parse_header (); - return parse_score (); -} - -void -Midi_score_parser::parse_header () -{ - String str = get_str (4); - if ( str != "MThd" ) - exit (_ ("MIDI header expected")); - - int length_i = get_i (4); - // is this signed? - if (length_i < 6) - exit (_ ("Invalid header length")); - info_l_->format_i_ = get_i (2); - if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1) - exit (_("Invalid midi format")); - info_l_->tracks_i_ = get_i (2); - if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 ) - exit (_("Invalid number of tracks")); - info_l_->division_1_i_ = get_i (2) * 4; - if (info_l_->division_1_i_ < 0) - exit (_f ("can't handle %s", _ ("non-metrical time"))); - // ugh - Duration::division_1_i_s = info_l_->division_1_i_; - forward_byte_L (length_i - 6); -} - -int -Midi_score_parser::find_earliest_i (Link_array& tracks) -{ - int earliest_i = 0; - Moment earliest_mom = infinity_mom; - for (int i = 0; i < tracks.size(); i++) - { - if ( tracks [i]->at_mom () < earliest_mom ) - { - earliest_mom = tracks [i]->at_mom (); - earliest_i = i; - } - } - return earliest_i; -} - -Mudela_score* -Midi_score_parser::parse_score () -{ - int current_bar_i = 0; - Mudela_time_signature m4 (4, 2, 24, 8); - Moment bar4_mom = m4.bar_mom (); - - Mudela_score* score_p = new Mudela_score( 1, 1, 1 ); - info_l_->score_l_ = score_p; - - Link_array tracks; - for (int i = 0; i < info_l_->tracks_i_; i++) - tracks.push (new Midi_track_parser (info_l_, i)); - - LOGOUT (NORMAL_ver) << _ ("Parsing...\n"); - while (tracks.size ()) - { - int i = find_earliest_i (tracks); - Moment at_mom = tracks [i]->at_mom (); - Mudela_column* column_l = score_p->get_column_l (at_mom); - Mudela_staff* staff_p = tracks [i]->parse (column_l); - if ( staff_p ) - { - score_p->add_staff (staff_p); - delete tracks [i]; - tracks.del (i); - } - - // brr, musta have some progress - for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++) - info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_; - - int bar_i = (int) (at_mom - / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1; - if (bar_i > current_bar_i) - { - LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; - current_bar_i = bar_i; - } - } - return score_p; -} diff --git a/mi2mu/midi-track-parser.cc b/mi2mu/midi-track-parser.cc deleted file mode 100644 index 49840ec77c..0000000000 --- a/mi2mu/midi-track-parser.cc +++ /dev/null @@ -1,360 +0,0 @@ -/* - midi-track-parser.cc -- implement - - source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Jan Nieuwenhuizen -*/ - -#include -#include "string-convert.hh" -#include "mi2mu-global.hh" -#include "midi-track-parser.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" -#include "mudela-staff.hh" - -Midi_track_parser::Midi_track_parser (Midi_parser_info* info_l, int i) -{ - info_l_ = info_l; - at_mom_ = 0; - track_info_p_ = 0; - mudela_staff_p_ = new Mudela_staff (i, "", "", ""); - parse_header (); - parse_delta_time (); -} - -Midi_track_parser::~Midi_track_parser () -{ - delete mudela_staff_p_; - delete track_info_p_; -} - -Moment -Midi_track_parser::at_mom () -{ - return at_mom_; -} - -bool -Midi_track_parser::eot () -{ - if ( info_l_->byte_L_ < info_l_->end_byte_L_ ) - return false; - return true; -} - -void -Midi_track_parser::note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ) -{ - // junk dynamics - (void)aftertouch_i; - - assert (col_l); - - for (Cons** pp = &open_note_l_list_.head_; *pp;) - { - Cons* i = *pp; - if ((i->car_->pitch_i_ == pitch_i) && (i->car_->channel_i_ == channel_i)) - { - i->car_->end_column_l_ = col_l; - delete open_note_l_list_.remove_cons (pp); - return; - } - else - pp = &i->next_; - } - warning (_f ("junking note-end event: channel = %d, pitch = %d", - channel_i, pitch_i)); -} - -void -Midi_track_parser::note_end_all (Mudela_column* col_l) -{ - // find - assert (col_l); - for (Cons* i = open_note_l_list_.head_; i; i = i->next_) - { - i->car_->end_column_l_ = col_l; - } - // UGH UGH. MEMORY LEAK. - open_note_l_list_.init (); -} - -Mudela_staff* -Midi_track_parser::parse (Mudela_column* col_l) -{ - Moment mom = at_mom (); - while (!eot () && (mom == at_mom ())) - { - Mudela_item* p = parse_event (col_l); - if (p) - mudela_staff_p_->add_item (p); - } - - if (!eot()) - return 0; - - // catch-all - note_end_all (col_l); - - Mudela_staff* p = mudela_staff_p_; - mudela_staff_p_ = 0; - return p; -} - -void -Midi_track_parser::parse_delta_time () -{ - if (eot ()) - return; - int delta_i = get_var_i (); - at_mom_ += Moment (delta_i, info_l_->division_1_i_); -} - -Mudela_item* -Midi_track_parser::parse_event (Mudela_column* col_l) -{ - Byte byte = peek_byte (); - // RUNNING_STATUS [\x00-\x5f] - if (byte <= 0x5f) - { - if (running_byte_ <= 0x5f) - exit (_ ("invalid running status")); - /* - 'running status' rather means 'missing status'. - we'll just pretend we read the running status byte. - */ - byte = running_byte_; - } - else - byte = next_byte (); - - Mudela_item* item_p = 0; - // DATA_ENTRY [\x60-\x79] - if ((byte >= 0x60) && (byte <= 0x79)) - { - next_byte (); - } - // ALL_NOTES_OFF [\x7a-\x7f] - else if ((byte >= 0x7a) && (byte <= 0x7f)) - { - next_byte (); - next_byte (); - note_end_all (col_l); - } - // NOTE_OFF [\x80-\x8f] - else if ((byte >= 0x80) && (byte <= 0x8f)) - { - running_byte_ = byte; - int channel_i = byte & ~0x90; - int pitch_i = (int)next_byte (); - int dyn_i = (int)next_byte (); - note_end (col_l, channel_i, pitch_i, dyn_i); - } - // NOTE_ON [\x90-\x9f] - else if ((byte >= 0x90) && (byte <= 0x9f)) - { - running_byte_ = byte; - int channel_i = byte & ~0x90; - int pitch_i = (int)next_byte (); - int dyn_i = (int)next_byte (); - /* - sss: some broken devices encode NOTE_OFF as - NOTE_ON with zero volume - */ - if (dyn_i) - { - Mudela_note* p = new Mudela_note (col_l, channel_i, pitch_i, dyn_i); - item_p = p; - open_note_l_list_.append (new Cons (p, 0)); - } - else - { - note_end (col_l, channel_i, pitch_i, dyn_i); - } - } - - // POLYPHONIC_AFTERTOUCH [\xa0-\xaf] - else if ((byte >= 0xa0) && (byte <= 0xaf)) - { - running_byte_ = byte; - next_byte (); - next_byte (); - } - // CONTROLMODE_CHANGE [\xb0-\xbf] - else if ((byte >= 0xb0) && (byte <= 0xbf)) - { - running_byte_ = byte; - next_byte (); - next_byte (); - } - // PROGRAM_CHANGE [\xc0-\xcf] - else if ((byte >= 0xc0) && (byte <= 0xcf)) - { - running_byte_ = byte; - next_byte (); - } - // CHANNEL_AFTERTOUCH [\xd0-\xdf] - else if ((byte >= 0xd0) && (byte <= 0xdf)) - { - running_byte_ = byte; - next_byte (); - next_byte (); - } - // PITCHWHEEL_RANGE [\xe0-\xef] - else if ((byte >= 0xe0) && (byte <= 0xef)) - { - running_byte_ = byte; - next_byte (); - next_byte (); - } - // SYSEX_EVENT1 [\xf0] - else if (byte == 0xf0) - { - int length_i = get_var_i (); - String str = get_str (length_i); - } - // SYSEX_EVENT2 [\xf7] - else if (byte == 0xf7) - { - int length_i = get_var_i (); - String str = get_str (length_i); - } - // META_EVENT [\xff] - else if (byte == 0xff) - { - // SEQUENCE [\x00][\x02] - byte = next_byte (); - if (byte == 0) - { - next_byte (); - get_i (2); - } - // YYTEXT [\x01] - // YYCOPYRIGHT [\x02] - // YYTRACK_NAME [\x03] - // YYINSTRUMENT_NAME [\x04] - // YYLYRIC [\x05] - // YYMARKER [\x06] - // YYCUE_POINT [\x07] - else if ((byte >= 0x01) && (byte <= 0x07)) - { - // LOGOUT (DEBUG_ver) << "\n% Text(" << (int)byte << "):" << flush; - int length_i = get_var_i (); - String str = get_str (length_i); - // LOGOUT (DEBUG_ver) << str << endl; - Mudela_text::Type t = (Mudela_text::Type)byte; - Mudela_text* p = new Mudela_text (t, str); - item_p = p; - if (t == Mudela_text::COPYRIGHT) - mudela_staff_p_->copyright_str_ = p->text_str_; - else if (t == Mudela_text::TRACK_NAME) - mudela_staff_p_->name_str_ = p->text_str_; - else if (t == Mudela_text::INSTRUMENT_NAME) - mudela_staff_p_->instrument_str_ = p->text_str_; - } - // END_OF_TRACK [\x2f][\x00] - else - { - Byte next = peek_byte (); - if ((byte == 0x2f) && (next == 0x00)) - { - next_byte (); - info_l_->byte_L_ = info_l_->end_byte_L_; - } - // TEMPO [\x51][\x03] - else if ((byte == 0x51) && (next == 0x03)) - { - next_byte (); - unsigned useconds_per_4_u = get_u (3); - // $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4); - // LOGOUT (DEBUG_ver) << $$->str() << endl; - Mudela_tempo* p = new Mudela_tempo ( useconds_per_4_u ); - item_p = p; - info_l_->score_l_->mudela_tempo_l_ = p; - mudela_staff_p_->mudela_tempo_l_ = p; - } - // SMPTE_OFFSET [\x54][\x05] - else if ((byte == 0x54) && (next == 0x05)) - { - next_byte (); - (int)next_byte (); - (int)next_byte (); - (int)next_byte (); - (int)next_byte (); - (int)next_byte (); - } - // TIME [\x58][\x04] - else if ((byte == 0x58) && (next == 0x04)) - { - next_byte (); - int num_i = (int)next_byte (); - int den_i = (int)next_byte (); - int clocks_4_i = (int)next_byte (); - int count_32_i = (int)next_byte (); - Mudela_time_signature* p = new Mudela_time_signature ( num_i, den_i, clocks_4_i, count_32_i ); - item_p = p; - info_l_->score_l_->mudela_time_signature_l_ = p; - info_l_->bar_mom_ = p->bar_mom (); - mudela_staff_p_->mudela_time_signature_l_ = p; - } - // KEY [\x59][\x02] - else if ((byte == 0x59) && (next == 0x02)) - { - next_byte (); - int accidentals_i = (int)(signed char)next_byte (); - int minor_i = (int)(bool)next_byte (); - Mudela_key* p = new Mudela_key (accidentals_i, minor_i); - item_p = p; -#if 0 - info_l_->score_l_->mudela_key_l_ = p; - mudela_staff_p_->mudela_key_l_ = p; -#endif - } - // SSME [\0x7f][\x03] - else if ((byte == 0x7f) && (next == 0x03)) - { - next_byte (); - int length_i = get_var_i (); - String str = get_str (length_i); - item_p = new Mudela_text ((Mudela_text::Type)byte, str); - } - else - { - next_byte (); - next_byte (); - warning (_ ("unimplemented MIDI meta-event")); - } - } - } - else - exit (_ ("invalid MIDI event")); - - if (item_p) - item_p->mudela_column_l_ = col_l; - - parse_delta_time (); - - return item_p; -} - -void -Midi_track_parser::parse_header () -{ - String str = get_str (4); - if ( str != "MTrk" ) - exit (_ ("MIDI track expected")); - - int length_i = get_i (4); - // is this signed? - if (length_i < 0) - exit (_ ("invalid track length")); - assert (!track_info_p_); - track_info_p_ = new Midi_parser_info (*info_l_); - track_info_p_->end_byte_L_ = track_info_p_->byte_L_ + length_i; - forward_byte_L (length_i); - // forward_byte_L (length_i-1); - info_l_ = track_info_p_; -} diff --git a/mi2mu/mudela-column.cc b/mi2mu/mudela-column.cc deleted file mode 100644 index 833b351f81..0000000000 --- a/mi2mu/mudela-column.cc +++ /dev/null @@ -1,24 +0,0 @@ -// -// mudela-column.cc -- implement Mudela_column -// -// copyright 1997 Jan Nieuwenhuizen - -#include "mudela-column.hh" - -Mudela_column::Mudela_column (Mudela_score* mudela_score_l, Moment mom) -{ - mudela_score_l_ = mudela_score_l; - at_mom_ = mom; -} - -void -Mudela_column::add_item (Mudela_item* mudela_item_l) -{ - mudela_item_l_list_.append (new Cons (mudela_item_l, 0)); -} - -Moment -Mudela_column::at_mom() -{ - return at_mom_; -} diff --git a/mi2mu/mudela-item.cc b/mi2mu/mudela-item.cc deleted file mode 100644 index 58a1db586b..0000000000 --- a/mi2mu/mudela-item.cc +++ /dev/null @@ -1,363 +0,0 @@ -// -// mudela-item.cc -- implement Mudela_item -// -// copyright 1997 Jan Nieuwenhuizen - -#include -#include "mi2mu-global.hh" -#include "string-convert.hh" -#include "duration-convert.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-stream.hh" -#include "mudela-score.hh" - -Mudela_item::Mudela_item (Mudela_column* mudela_column_l) -{ - mudela_column_l_ = mudela_column_l; -} - -Mudela_item::~Mudela_item () -{ -} - -Moment -Mudela_item::at_mom () -{ - return mudela_column_l_->at_mom (); -} - -Moment -Mudela_item::duration_mom () -{ - return Moment (0); -} - -void -Mudela_item::output (Mudela_stream& mudela_stream_r) -{ - mudela_stream_r << str () << " "; -} - -Mudela_key::Mudela_key (int accidentals_i, int minor_i) - : Mudela_item (0) -{ - accidentals_i_ = accidentals_i; - minor_i_ = minor_i; -} - -char const *accname[] = {"eses", "es", "", "is" , "isis"}; - -String -Mudela_key::str () -{ - int key_i = accidentals_i_ >= 0 - ? ((accidentals_i_ % 7) ["cgdaebf"] - 'a' - 2 -2 * minor_i_ + 7) % 7 - : ((-accidentals_i_ % 7) ["cfbeadg"] - 'a' - 2 -2 * minor_i_ + 7) % 7; - - String notename_str = !minor_i_ - ? to_str ((char) ((key_i + 2) % 7 + 'A')) - : to_str ((char) ((key_i + 2) % 7 + 'a')); - - // fis cis gis dis ais eis bis - static int sharps_i_a [7] = { 2, 4, 6, 1, 3, 5, 7 }; - // bes es as des ges ces fes - static int flats_i_a [7] = { 6, 4, 2, 7, 5, 3, 1 }; - int accidentals_i = accidentals_i_ >= 0 - ? sharps_i_a [key_i] <= accidentals_i_ ? 1 : 0 - : flats_i_a [key_i] <= -accidentals_i_ ? -1 : 0; - - if (accidentals_i) - notename_str += String (accname [accidentals_i + 2]); - - return "\\key " + notename_str + (minor_i_ ? "\\minor" : "") + ";\n"; -} - -String -Mudela_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 [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 *= -1; - notename_i = (notename_i + 1) % 7; - } - - String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a')); - if (accidental_i) - notename_str += String (accname [accidental_i + 2]); - - /* - By tradition, all scales now consist of a sequence of 7 notes each - with a distinct name, from amongst a b c d e f g. But, minor scales - have a wide second interval at the top - the 'leading note' is - sharped. (Why? it just works that way! Anything else doesn't sound as - good and isn't as flexible at saying things. In medieval times, - scales only had 6 notes to avoid this problem - the hexachords.) - - So, the d minor scale is d e f g a b-flat c-sharp d - using d-flat - for the leading note would skip the name c and duplicate the name d. - Why isn't c-sharp put in the key signature? Tradition. (It's also - supposedly based on the Pythagorean theory of the cycle of fifths, - but that really only applies to major scales...) - - Anyway, g minor is g a b-flat c d e-flat f-sharp g, and all the other - flat minor keys end up with a natural leading note. And there you - have it. - - John Sankey - - Let's also do a-minor: a b c d e f gis a - - --jcn - - */ - - /* ok, bit ugly, but here we go -- jcn */ - - - if (minor_i_) - { - if ((accidentals_i_ == 0) && (notename_str == "as")) - notename_str = "gis"; - else if ((accidentals_i_ == -1) && (notename_str == "des")) - notename_str = "cis"; - else if ((accidentals_i_ == -2) && (notename_str == "ges")) - notename_str = "fis"; - else if ((accidentals_i_ == 5) && (notename_str == "g")) - notename_str = "fisis"; - else if ((accidentals_i_ == 6) && (notename_str == "d")) - notename_str = "cisis"; - else if ((accidentals_i_ == 7) && (notename_str == "a")) - notename_str = "gisis"; - - if ((accidentals_i_ <= -6) && (notename_str == "b")) - notename_str = "ces"; - if ((accidentals_i_ <= -7) && (notename_str == "e")) - notename_str = "fes"; - } - - String de_octavate_str = to_str (',', (Mudela_note::c0_pitch_i_c_ + 11 - pitch_i) / 12); - String octavate_str = to_str ('\'', (pitch_i - Mudela_note::c0_pitch_i_c_) / 12); - return notename_str +de_octavate_str + octavate_str; -} - -Mudela_time_signature::Mudela_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i) - : Mudela_item (0) -{ - sync_dur_.durlog_i_ = 3; - sync_f_ = 1.0; - if (count_32_i != 8) - warning (_f ("#32 in quarter: %d", count_32_i)); - num_i_ = num_i; - den_i_ = den_i; - clocks_1_i_ = clocks_4_i * 4; -} - -Moment -Mudela_time_signature::bar_mom () -{ - Duration d; - d.durlog_i_ = den_i_; - return Moment (num_i_) * Duration_convert::dur2_mom (d); -} - -int -Mudela_time_signature::clocks_1_i () -{ - return clocks_1_i_; -} - -int -Mudela_time_signature::den_i () -{ - return den_i_; -} - -int -Mudela_time_signature::num_i () -{ - return num_i_; -} - -String -Mudela_time_signature::str () -{ - String str = "\\time " - + to_str (num_i_) + "/" + to_str (1 << den_i_) - + ";\n"; - return str; -} - - -// statics Mudela_note -/* - this switch can be used to write simple plets like - c4*2/3 - as - \plet 2/3; c4 \plet 1/1; - */ -/* - UGH: .hh says false, .cc says true. - FIXME. - */ -bool const Mudela_note::simple_plet_b_s; - -Mudela_note::Mudela_note (Mudela_column* mudela_column_l, - int channel_i, int pitch_i, int dyn_i) - : Mudela_item (mudela_column_l) -{ - // junk dynamics - (void)dyn_i; - channel_i_ = channel_i; - pitch_i_ = pitch_i; - end_column_l_ = 0; -} - -Duration -Mudela_note::duration () -{ - assert (end_column_l_); - Moment mom = end_column_l_->at_mom () - at_mom (); - return Duration_convert::mom2_dur (mom); -} - -Moment -Mudela_note::duration_mom () -{ - assert (end_column_l_); - return end_column_l_->at_mom () - at_mom (); -} - -String -Mudela_note::str () -{ - Duration dur = duration (); - if (dur.durlog_i_ < -10) - return ""; - - String name_str - = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_); - - if (simple_plet_b_s) - return name_str + Duration_convert::dur2_str (dur) + " "; - - String str; - - //ugh - if (dur.plet_b ()) - str += String ("\\times ") - + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0) - + "/" - + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0) - + " { "; - - - str += name_str; - - Duration tmp = dur; - tmp.set_plet (1,1); - str += Duration_convert::dur2_str (tmp); - - if (dur.plet_b ()) - str += String (" }"); - - /* - note of zero duration is nonsense, - but let's output anyway for convenient debugging - */ - if (!duration_mom ()) - return String ("\n% ") + str + "\n"; - - return str + " "; -} - -Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) - : Mudela_item (mudela_column_l) -{ - mom_ = skip_mom; -} - -Duration -Mudela_skip::duration () -{ - return Duration_convert::mom2_dur (mom_); -} - -Moment -Mudela_skip::duration_mom () -{ - return Duration_convert::dur2_mom (duration ()); -} - -String -Mudela_skip::str () -{ - if (!mom_) - return String (""); - - Duration dur = duration (); - if (dur.durlog_i_<-10) - return ""; - - String str = "\\skip "; - str += Duration_convert::dur2_str (dur) + "; "; - - return str; -} - -Mudela_tempo::Mudela_tempo (int useconds_per_4_i) - : Mudela_item (0) -{ - useconds_per_4_i_ = useconds_per_4_i; - seconds_per_1_mom_ = Moment(useconds_per_4_i_ *4, 1e6); -} - -String -Mudela_tempo::str () -{ - String str = "\\tempo 4="; - str += to_str (get_tempo_i (Moment (1, 4))); - str += ";\n"; - return str; -} - -int -Mudela_tempo::useconds_per_4_i () -{ - return useconds_per_4_i_; -} - -int -Mudela_tempo::get_tempo_i (Moment moment) -{ - Moment m1 = Moment (60) / moment; - Moment m2 = seconds_per_1_mom_; - return m1 / m2; -} - -Mudela_text::Mudela_text (Mudela_text::Type type, String text_str) - : Mudela_item (0) -{ - type_ = type; - text_str_ = text_str; -} - -String -Mudela_text::str () -{ - if (!text_str_.length_i () - || (text_str_.length_i () != (int)strlen (text_str_.ch_C ()))) - return ""; - - return "% " + text_str_ + "\n"; -} diff --git a/mi2mu/mudela-score.cc b/mi2mu/mudela-score.cc deleted file mode 100644 index 6916d80df7..0000000000 --- a/mi2mu/mudela-score.cc +++ /dev/null @@ -1,256 +0,0 @@ -// -// mudela-score.cc -- implement Mudela_score -// -// copyright 1997 Jan Nieuwenhuizen - -#include -#include "moment.hh" -#include "duration.hh" -#include "duration-convert.hh" -#include "mi2mu-global.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-score.hh" -#include "mudela-staff.hh" -#include "mudela-stream.hh" - -#include "killing-cons.tcc" - -//static Mudela_key key_c (0, 0); -static Mudela_time_signature time_sig_4 (4, 2, 24, 8); -// useconds per 4: 250000 === 60 4 per minute -static Mudela_tempo tempo_60 (1000000); - -Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i) -{ - last_staff_l_ =0; - format_i_ = format_i; - tracks_i_ = tracks_i; - tempo_i_ = tempo_i; - column_l_array_.push (new Mudela_column (this, Moment (0))); - // mudela_key_l_ = &key_c; - mudela_key_l_ = 0; - mudela_time_signature_l_ = &time_sig_4; - mudela_tempo_l_ = &tempo_60; -} - -Mudela_score::~Mudela_score () -{ -} - -void -Mudela_score::add_item (Mudela_item* mudela_item_p) -{ - last_staff_l_->add_item (mudela_item_p); -} - -void -Mudela_score::add_staff (Mudela_staff* mudela_staff_p) -{ - mudela_staff_p_list_.append (new Killing_cons (mudela_staff_p, 0)); - last_staff_l_ = mudela_staff_p; -} - -Mudela_column* -Mudela_score::find_column_l (Moment mom) -{ - int upper_i = max (0, column_l_array_.size () - 1); - int lower_i = 0; - int i = 0; //upper_i; - while (1) - { - Moment i_mom = column_l_array_ [i]->at_mom (); - if (i_mom == mom) - return column_l_array_ [i]; - if (mom < i_mom) - upper_i = i; - else - lower_i = i; - if ( (upper_i == lower_i) || (i == column_l_array_.size () - 1)) - { - // we don't do inserts - assert (0); - Mudela_column* col_p = new Mudela_column (this, mom); - column_l_array_.push (col_p); - return col_p; - } - i = (upper_i + lower_i + 1 ) / 2; - } - assert (0); - return 0; -} - -Mudela_column* -Mudela_score::get_column_l (Moment mom) -{ - int i; - Mudela_column *c=0; - for (i=column_l_array_.size () - 1; !c && i >=0; i--) - { - if (column_l_array_ [i]->at_mom () == mom ) - c = column_l_array_[i]; - else if (column_l_array_[i]->at_mom () < mom) - break; - } - if (!c) - { - c = new Mudela_column (this, mom); - column_l_array_.insert (c, i+1); - } - - assert (c->at_mom () == mom); - return c; -} - -void -Mudela_score::output (String filename_str) -{ - LOGOUT (NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl; - - // ugh, ugly midi type 1 fix - if ( (mudela_staff_p_list_.size_i () == 1) - && !mudela_staff_p_list_.head_->car_->number_i_) - mudela_staff_p_list_.head_->car_->number_i_ = 1; - - int track_i = 0; - Mudela_stream mudela_stream (filename_str); - for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) - { - LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush; - i->car_->output (mudela_stream); - mudela_stream << '\n'; - LOGOUT (NORMAL_ver) << endl; - } - - mudela_stream << "\\score{\n"; - if (mudela_staff_p_list_.size_i () > 1) - mudela_stream << "< \n"; - for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) - { - if ( (mudela_staff_p_list_.size_i () != 1) - && (i->car_ == mudela_staff_p_list_.head_->car_)) - continue; - mudela_stream << "\\type Staff = \"" << i->car_->id_str () << "\" "; - mudela_stream << String ("\\" + i->car_->id_str ()) << "\n"; - } - if (mudela_staff_p_list_.size_i () > 1) - mudela_stream << ">\n"; - - mudela_stream << "\\paper{}\n"; - -#if 0 - mudela_stream << "\\midi{\n"; - - // let's not use silly 0 track - last_cons (mudela_staff_p_list_.head_)->car_->mudela_tempo_l_->output (mudela_stream); - mudela_stream << "}\n"; -#endif - - mudela_stream << "}\n"; -} - -void -Mudela_score::process () -{ - LOGOUT (NORMAL_ver) << '\n' << _ ("Processing...") << endl; - - LOGOUT (DEBUG_ver) << "columns\n"; - - settle_columns (); - filter_tempo (); - quantify_columns (); - quantify_durations (); - - LOGOUT (NORMAL_ver) << '\n' << _ ("Creating voices...") << endl; - int track_i = 0; - for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) - { - LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush; - i->car_->process (); - LOGOUT (NORMAL_ver) << endl; - } -} - -void -Mudela_score::filter_tempo () -{ - LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl; -} - -void -Mudela_score::quantify_columns () -{ - // ugh - if (Duration_convert::no_quantify_b_s) - { - LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Quantifying columns...") << endl; - return; - } - - LOGOUT (NORMAL_ver) << '\n' << _ ("Quantifying columns...") << endl; - - int current_bar_i = 0; - Moment bar_mom = mudela_time_signature_l_->bar_mom (); - - int n = 5 >? Duration_convert::no_smaller_than_i_s; - n = Duration_convert::type2_i (n); - Moment s = Moment (1, n); - for (int i = 0; i < column_l_array_.size (); i++) - { - column_l_array_ [i]->at_mom_ = - s * Moment ( (int) ( (column_l_array_ [i]->at_mom ()) / s)); - - int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1; - if (bar_i > current_bar_i) - - { - LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush; - current_bar_i = bar_i; - } - } - LOGOUT (NORMAL_ver) << endl; -} - -void -Mudela_score::quantify_durations () -{ - -} - -void -Mudela_score::settle_columns () -{ - LOGOUT (NORMAL_ver) << '\n' << _ ("Settling columns...") << endl; - - int n = column_l_array_.size (); - - int start_i = 0; - int end_i = 0; - Moment start_mom = 0; - - Duration smallest_dur; - smallest_dur.durlog_i_ = 6; - Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur) - / Moment (2); - for (int i = 0; i < n; i++) - { - if (!start_i) - { - start_i = end_i = i; - start_mom = column_l_array_ [i]->at_mom (); - continue; - } - - // find all columns within noise's distance - while ( (i < n) - && (column_l_array_ [i]->at_mom () - start_mom < noise_mom)) - end_i = ++i; - - // bluntly set all to time of first in group - for (int j = start_i; j < end_i; j++) - column_l_array_ [j]->at_mom_ = start_mom; - - start_i = end_i = 0; - } -} - diff --git a/mi2mu/mudela-staff.cc b/mi2mu/mudela-staff.cc deleted file mode 100644 index d6088e1bec..0000000000 --- a/mi2mu/mudela-staff.cc +++ /dev/null @@ -1,252 +0,0 @@ -// -// mudela-staff.cc -- implement Mudela_staff -// -// copyright 1997 Jan Nieuwenhuizen - -#include -#include -#include "moment.hh" -#include "duration-convert.hh" -#include "string-convert.hh" -#include "mi2mu-proto.hh" -#include "mi2mu-global.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-staff.hh" -#include "mudela-stream.hh" -#include "mudela-voice.hh" -#include "mudela-score.hh" - -#include "killing-cons.tcc" - -extern Mudela_score* mudela_score_l_g; - -Mudela_staff::Mudela_staff (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; - name_str_ = track_name_str; - mudela_key_l_ = 0; - mudela_time_signature_l_ = 0; - mudela_tempo_l_ = 0; -} - -void -Mudela_staff::add_item (Mudela_item* mudela_item_p) -{ - mudela_item_p_list_.append (new Killing_cons (mudela_item_p, 0)); - if (mudela_item_p->mudela_column_l_) - mudela_item_p->mudela_column_l_->add_item (mudela_item_p); -} - -void -Mudela_staff::eat_voice (Cons_list& items) -{ - Mudela_voice* voice_p = new Mudela_voice (this); - mudela_voice_p_list_.append (new Killing_cons (voice_p, 0)); - - // Moment mom = items.top ()->at_mom (); - Moment mom = 0; - - for (Cons** pp = &items.head_; *pp;) - { - Cons* i = *pp; - LOGOUT (DEBUG_ver) << "At: " << i->car_->at_mom ().str () << "; "; - LOGOUT (DEBUG_ver) << "dur: " << i->car_->duration_mom ().str () << "; "; - LOGOUT (DEBUG_ver) << "mom: " << mom.str () << " -> "; - if (i->car_->at_mom () > mom) - { - Moment dur = i->car_->at_mom () - mom; - // ugh, need score - Mudela_column* start = mudela_score_l_g->find_column_l (mom); - voice_p->add_item (new Mudela_skip (start, dur)); - mom = i->car_->at_mom (); - } - if (i->car_->at_mom () == mom) - { - mom = i->car_->at_mom () + i->car_->duration_mom (); - Cons* c = items.remove_cons (pp); - voice_p->add_item (c->car_); - delete c; - } - else if (*pp) - pp = &i->next_; - LOGOUT (DEBUG_ver) << "mom: " << mom.str () << '\n'; - } -} - -String -Mudela_staff::id_str () -{ - String id (name_str ()); - char *cp = id.ch_l (); - char *end = cp + id.length_i (); - for (;cp < end; cp++) - { - if (!isalpha (*cp)) - { - *cp = 'X'; - } - } - return id; -} - -String -Mudela_staff::name_str () -{ - if (name_str_.length_i ()) - return name_str_; - return String ("track") + to_str (char ('A' - 1 + number_i_)); -} - - - -void -Mudela_staff::output (Mudela_stream& mudela_stream_r) -{ - mudela_stream_r << id_str () << " = \\notes"; - mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "<" : "{"); - mudela_stream_r << '\n'; - mudela_stream_r << _ ("% midi copyright:") << copyright_str_ << '\n'; - mudela_stream_r << _ ("% instrument:") << instrument_str_ << '\n'; - - // don't use last duration mode - // mudela_stream_r << "\\duration 4;\n"; - if (mudela_voice_p_list_.size_i () == 1) - mudela_voice_p_list_.head_->car_->output (mudela_stream_r); - else - for (Cons* i = mudela_voice_p_list_.head_; i; i = i->next_) - { - mudela_stream_r << "{ "; - i->car_->output (mudela_stream_r); - mudela_stream_r << "} "; - } - - mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "\n>" : "\n}"); - mudela_stream_r << " % " << name_str () << '\n'; -} - -void -Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i) -{ - Moment bar_mom = mudela_time_signature_l_->bar_mom (); - Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom; - if (bar_i > 1) - { - if (!into_bar_mom) - mudela_stream_r << "|\n"; - } - mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' '); - if (into_bar_mom) - mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom)); - mudela_stream_r << '\n'; -} - - -#if 0 // not used for now -void -Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom) -{ - Moment bar_mom = mudela_time_signature_l_->bar_mom (); - Moment now_mom = begin_mom; - - int begin_bar_i = (int) (now_mom / bar_mom) + 1; - int end_bar_i = (int) (end_mom / bar_mom) + 1; - - if (end_bar_i == begin_bar_i) - { - output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom); - return; - } - - // multiple bars involved - int bar_i = (int) (now_mom / bar_mom) + 1; - - //fill current bar - Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom; - if (now_mom > begin_bar_mom) - { - int next_bar_i = (int) (now_mom / bar_mom) + 2; - Moment next_bar_mom = Moment (next_bar_i - 1) * bar_mom; - assert (next_bar_mom <= end_mom); - - Moment remain_mom = next_bar_mom - now_mom; - if (remain_mom > Moment (0)) - { - output_mudela_rest_remain (mudela_stream_r, remain_mom); - now_mom += remain_mom; - } - - bar_i = check_end_bar_i (now_mom, bar_i); - } - - // fill whole bars - int count_i = end_bar_i - bar_i; - for (int i = 0; i < count_i; i++) - { - int begin_bar_i = check_begin_bar_i (now_mom, bar_i); - if (begin_bar_i) - output_mudela_begin_bar (mudela_stream_r, now_mom, begin_bar_i); - mudela_stream_r << "r1 "; - // *mudela_stream_r.os_p_ << flush; - if (begin_bar_i) - LOGOUT (NORMAL_ver) << begin_bar_i << flush; - bar_i = check_end_bar_i (now_mom, bar_i); - now_mom += bar_mom; - } - - // use "int i" here, and gcc 2.7.2 hits internal compiler error - int ii = check_begin_bar_i (now_mom, bar_i); - if (ii) - output_mudela_begin_bar (mudela_stream_r, now_mom, ii); - - // bar_i = check_end_bar_i (now_mom, bar_i); - - Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom; - if (remain_mom > Moment (0)) - { - output_mudela_rest_remain (mudela_stream_r, remain_mom); - now_mom += remain_mom; - } - assert (now_mom == end_mom); -} - -void -Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom) -{ - if (Duration_convert::no_quantify_b_s) - { - Duration dur = Duration_convert::mom2_dur (mom); - mudela_stream_r << "r" << dur.str () << " "; - // assert (mom == dur.mom ()); - assert (mom == dur.length ()); - return; - } - - Duration dur = Duration_convert::mom2standardised_dur (mom); - if (dur.type_i_>-10) - mudela_stream_r << "r" << dur.str () << " "; -} -#endif - - -void -Mudela_staff::process () -{ - /* - group items into voices - */ - - assert (mudela_score_l_g); - mudela_key_l_ = mudela_score_l_g->mudela_key_l_; - mudela_time_signature_l_ = mudela_score_l_g->mudela_time_signature_l_; - mudela_tempo_l_ = mudela_score_l_g->mudela_tempo_l_; - - Cons_list items; - for (Cons* i = mudela_item_p_list_.head_; i; i = i->next_) - items.append (new Cons (i->car_, 0)); - - while (items.size_i ()) - eat_voice (items); -} diff --git a/mi2mu/mudela-stream.cc b/mi2mu/mudela-stream.cc deleted file mode 100644 index 5bdfd11e25..0000000000 --- a/mi2mu/mudela-stream.cc +++ /dev/null @@ -1,184 +0,0 @@ -// -// mudela-stream.cc -// -// source file of the LilyPond music typesetter -// -// (c) 1997--1998, 1998 Jan Nieuwenhuizen - -#include -#include -#include -#include "mi2mu-global.hh" -#include "mudela-item.hh" -#include "mudela-stream.hh" -#include "string-convert.hh" - -extern String filename_str_g; - -static int const INDENT_i = 8; - -Mudela_stream::Mudela_stream (String filename_str) -{ - filename_str_ = filename_str; - pending_indent_i_ = 0; - os_p_ = 0; - indent_i_ = 0; - comment_mode_b_ = false; - column_i_ = 0; - wrap_column_i_ = 68; - open(); - header(); -} - -Mudela_stream::~Mudela_stream() -{ - delete os_p_; - if (indent_i_) - warning (_f ("lily indent level: %d", indent_i_)); -} - -Mudela_stream& -Mudela_stream::operator << (Scalar s) -{ - static String word_sep_str = "{} \t\n"; - while (s.length_i()) - { - int i = s.index_any_i (word_sep_str) + 1; - if (!i) - i = s.length_i(); - String word = s.left_str (i); - s = s.cut_str (i, s.length_i()); - output_wrapped (word); - } - return *this; -} - -Mudela_stream& -Mudela_stream::operator << (Mudela_item& mudela_item_r) -{ - mudela_item_r.output (*this); - *os_p_ << flush; - return *this; -} - -void -Mudela_stream::handle_pending_indent() -{ - *os_p_ << String_convert::char_str ('\t', pending_indent_i_); - column_i_ += pending_indent_i_ * INDENT_i; - pending_indent_i_ = 0; -} - -void -Mudela_stream::header() -{ - *os_p_ << _ ("% Creator: "); - if (no_timestamps_b_g) - *os_p_ << "GNU LilyPond\n"; - else - *os_p_ << mi2mu_version_str() << '\n'; - *os_p_ << _ ("% Automatically generated"); - if (no_timestamps_b_g) - *os_p_ << ".\n"; - else - { - *os_p_ << _ (", at "); - time_t t (time (0)); - *os_p_ << ctime (&t) << "%\n"; - } - *os_p_ << _ ("% from input file: "); - // *os_p_ << midi_parser_l_g->filename_str_; - // ugh - *os_p_ << filename_str_g; - *os_p_ << "\n\n"; - // ugh - *os_p_ << "\\version \"1.0.14\";\n"; -} - -void -Mudela_stream::open() -{ - os_p_ = new ofstream (filename_str_.ch_C ()); - if (!*os_p_) - error (_f ("can't open file: `%s\'", filename_str_)); -} - -void -Mudela_stream::output (String str) -{ - for (int i = 0; i < str.length_i(); i++) - { - char c = str[ i ]; - switch (c) - { - case '{' : - case '<' : - handle_pending_indent(); - if (column_i_ == indent_i_ * INDENT_i) - output ("\t"); - indent_i_++; - *os_p_ << c; - column_i_++; - break; - case '}' : - case '>' : - assert (indent_i_); - indent_i_--; - if (pending_indent_i_) - pending_indent_i_--; - handle_pending_indent(); - *os_p_ << c; - column_i_++; - break; - case '%' : - handle_pending_indent(); - comment_mode_b_ = true; - *os_p_ << c; - column_i_++; - break; - case '\t' : - handle_pending_indent(); - *os_p_ << c; - column_i_ += INDENT_i; - break; - case '\n' : - *os_p_ << endl; - pending_indent_i_ = indent_i_; - column_i_ = 0; - comment_mode_b_ = false; - break; - default : - handle_pending_indent(); - *os_p_ << c; - column_i_++; - break; - } - } -} - -void -Mudela_stream::output_wrapped (String str) -{ - // enough room left -> doit - if (column_i_ + str.length_i() <= wrap_column_i_) - { - output (str); - return; - } - - // we're at BOL already; this will never fit -> doit - if (column_i_ == indent_i_ * INDENT_i) - { - output (str); - return; - } - - // ok, let's wrap - // preserve comment mode - if (comment_mode_b_) - output (String ("\n%")); - else - output (String ("\n")); - - output (str); -} diff --git a/mi2mu/mudela-voice.cc b/mi2mu/mudela-voice.cc deleted file mode 100644 index 286d2176c9..0000000000 --- a/mi2mu/mudela-voice.cc +++ /dev/null @@ -1,69 +0,0 @@ -// -// mudela-voice.cc -- implement Mudela_voice -// -// copyright 1997 Jan Nieuwenhuizen - -#include "string-convert.hh" -#include "mi2mu-global.hh" -#include "mudela-column.hh" -#include "mudela-item.hh" -#include "mudela-staff.hh" -#include "mudela-stream.hh" -#include "mudela-voice.hh" -#include "mudela-score.hh" - -extern Mudela_score* mudela_score_l_g; - -Mudela_voice::Mudela_voice (Mudela_staff* mudela_staff_l) -{ - mudela_staff_l_ = mudela_staff_l; -} - -void -Mudela_voice::add_item (Mudela_item* mudela_item_l) -{ - mudela_item_l_list_.append (new Cons (mudela_item_l, 0)); -} - - -static int const FAIRLY_LONG_VOICE_i = 6; - -void -Mudela_voice::output (Mudela_stream& mudela_stream_r) -{ - if (!mudela_item_l_list_.size_i ()) - return; - - if (mudela_item_l_list_.size_i () > FAIRLY_LONG_VOICE_i) - mudela_stream_r << '\n'; - - int current_bar_i = 0; - Moment bar_mom = mudela_staff_l_->mudela_time_signature_l_->bar_mom (); - - for (Cons* i = mudela_item_l_list_.head_; i; i = i->next_) - { - Moment at_mom = i->car_->mudela_column_l_->at_mom (); - int bar_i = (int) (at_mom / bar_mom) + 1; - if (bar_i > current_bar_i) - { - if (current_bar_i) - { - if (at_mom == Moment (bar_i - 1) * bar_mom) - mudela_stream_r << "|"; - mudela_stream_r << "\n% "; - mudela_stream_r << String_convert::i2dec_str (bar_i, 0, ' '); - mudela_stream_r << '\n'; - } - LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush; - current_bar_i = bar_i; - } - - mudela_stream_r << *i->car_; - if (Mudela_key* k = dynamic_cast (i->car_)) - mudela_staff_l_->mudela_key_l_ = mudela_score_l_g->mudela_key_l_ = k; - } - - if (mudela_item_l_list_.size_i () > FAIRLY_LONG_VOICE_i) - mudela_stream_r << '\n'; -} - diff --git a/midi2ly/include/mi2mu-global.hh b/midi2ly/include/mi2mu-global.hh new file mode 100644 index 0000000000..4ed873fb54 --- /dev/null +++ b/midi2ly/include/mi2mu-global.hh @@ -0,0 +1,33 @@ +// +// mi2mu-global.hh -- declare global (sic) stuff for mi2mu +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MI2MU_GLOBAL_HH +#define MI2MU_GLOBAL_HH + +#include "string.hh" +#include "proto.hh" + +#define monitor_p_g &cout +enum Verbose { QUIET_ver, BRIEF_ver, NORMAL_ver, VERBOSE_ver, DEBUG_ver }; +extern Verbose level_ver; +#if 0 // NPRINT + // not what i want, all output goes through tors. + // set verbosity level. + #define LOGOUT(threshold) if (0) *monitor_p_g +#else + #define LOGOUT(threshold) if (level_ver >= threshold) *monitor_p_g +#endif + +extern Sources* source_l_g; +// huh? +void message (String message_str); //, char const* context_ch_C); +void warning (String message_str); //, char const* context_ch_C); +void error (String message_str); //, char const* context_ch_C); + +String mi2mu_version_str(); +extern bool no_timestamps_b_g;; + +#endif // MI2MU_GLOBAL_HH + diff --git a/midi2ly/include/midi-parser.hh b/midi2ly/include/midi-parser.hh new file mode 100644 index 0000000000..9dca4db212 --- /dev/null +++ b/midi2ly/include/midi-parser.hh @@ -0,0 +1,106 @@ +/* + midi-parser.hh -- declare Midi_parser + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_PARSER_HH +#define MIDI_PARSER_HH + +// must, gcc 2.7.2{,.1} hits ico on midi-track-parser.cc:134 (@Midi_note) +#define INLINES + +#ifdef INLINES + +#define next_byte() (inline_next_byte (__FUNCTION__)) +#define peek_byte() (inline_peek_byte (__FUNCTION__)) +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#else + +#define next_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_++\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define peek_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#endif + +#include "proto.hh" +#include "moment.hh" +#include "mi2mu-proto.hh" + +struct Midi_parser_info +{ + Midi_parser_info(); + int division_1_i_; + int format_i_; + int tracks_i_; + int errorlevel_i_; + Byte const* byte_L_; + Byte const* end_byte_L_; + Source_file* source_l_; + Mudela_score* score_l_; + Moment bar_mom_; +}; + +#include "string.hh" + +class Midi_parser +{ +public: + Midi_parser (); + + Midi_parser_info* info_l_; + +protected: + Byte const* inline_forward_byte_L (char const* fun, int n) + { + if (info_l_->byte_L_ + n < info_l_->end_byte_L_ ) + { + Byte const* p = info_l_->byte_L_; + info_l_->byte_L_ += n; + return p; + } + exit (String (fun) + ": unexpected EOF"); + return 0; + } + +#ifdef INLINES + Byte inline_next_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_++; + exit (String (fun) + ": unexpected EOF"); + return 0; + } + + Byte inline_peek_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_; + exit (String (fun) + ": unexpected EOF"); + return 0; + } +#endif + + int get_i (int); + String get_str (int); + unsigned get_u (int); + int get_var_i (); + int exit (String); + void error (String); + String message (String); + void warning (String); +}; + +#endif // MIDI_PARSER_HH diff --git a/midi2ly/include/midi-score-parser.hh b/midi2ly/include/midi-score-parser.hh new file mode 100644 index 0000000000..0dc9823705 --- /dev/null +++ b/midi2ly/include/midi-score-parser.hh @@ -0,0 +1,33 @@ +/* + midi-score-parser.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_SCORE_PARSER_HH +#define MIDI_SCORE_PARSER_HH + +#include "midi-parser.hh" +#include "proto.hh" +#include "mi2mu-proto.hh" +#include "parray.hh" + +class Midi_score_parser : public Midi_parser +{ +public: + Mudela_score* parse (String filename_str, Sources*); + +private: + void open (String filename_str, Sources*); + + void parse_header (); + // why the #*&$#{%) has Link_array another behaviour than Link_list?? + // int find_earliest_i (Link_array& tracks); + int find_earliest_i (Link_array& tracks); + Mudela_score* parse_score (); +}; + +#endif // MIDI_SCORE_PARSER_HH diff --git a/midi2ly/include/midi-track-parser.hh b/midi2ly/include/midi-track-parser.hh new file mode 100644 index 0000000000..d873e198df --- /dev/null +++ b/midi2ly/include/midi-track-parser.hh @@ -0,0 +1,44 @@ +/* + midi-track-parser.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_TRACK_PARSER_HH +#define MIDI_TRACK_PARSER_HH + +#include "proto.hh" +#include "cons.hh" +#include "moment.hh" +#include "mi2mu-proto.hh" +#include "midi-parser.hh" + +class Midi_track_parser : public Midi_parser +{ +public: + + Midi_track_parser (Midi_parser_info* info_l, int i); + ~Midi_track_parser (); + + Moment at_mom (); + Mudela_staff* parse (Mudela_column* col_l); + +private: + bool eot (); + void note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ); + void note_end_all (Mudela_column* col_l) ; + void parse_delta_time (); + Mudela_item* parse_event (Mudela_column* col_l); + void parse_header (); + + Moment at_mom_; + Byte running_byte_; + Cons_list open_note_l_list_; + Mudela_staff* mudela_staff_p_; + Midi_parser_info* track_info_p_; +}; + +#endif // MIDI_TRACK_PARSER_HH diff --git a/midi2ly/include/mudela-column.hh b/midi2ly/include/mudela-column.hh new file mode 100644 index 0000000000..a09cebb469 --- /dev/null +++ b/midi2ly/include/mudela-column.hh @@ -0,0 +1,29 @@ +// +// mudela-column.hh -- declare Mudela_column +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MUDELA_COLUMN_HH +#define MUDELA_COLUMN_HH + +#include "proto.hh" +#include "mi2mu-proto.hh" +#include "moment.hh" +#include "cons.hh" + +/// (mudela_column) +class Mudela_column +{ +public: + Mudela_column (Mudela_score* mudela_score_l, Moment mom); + + void add_item (Mudela_item* mudela_item_l); + Moment at_mom (); + + Cons_list mudela_item_l_list_; + Moment at_mom_; + Mudela_score* mudela_score_l_; +}; + +#endif // MUDELA_COLUMN_HH + diff --git a/midi2ly/include/mudela-item.hh b/midi2ly/include/mudela-item.hh new file mode 100644 index 0000000000..e1b52b7368 --- /dev/null +++ b/midi2ly/include/mudela-item.hh @@ -0,0 +1,130 @@ +// +// mudela-item.hh -- declare mudela_item +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MUDELA_ITEM_HH +#define MUDELA_ITEM_HH + +#include "mi2mu-proto.hh" +#include "string.hh" +#include "moment.hh" +#include "duration.hh" + +// should these: +// * be Mudela_items +// * be Voice_elements/requests +// * get a name-change +// ? + +/// (mudela_item) +class Mudela_item +{ +public: + Mudela_item (Mudela_column* mudela_column_l); + virtual ~Mudela_item (); + + virtual Moment at_mom (); + virtual Moment duration_mom (); + void output (Mudela_stream& mudela_stream_r); + virtual String str () = 0; + + Mudela_column* mudela_column_l_; +}; + +class Mudela_key : public Mudela_item +{ +public: + Mudela_key (int accidentals_i, int minor_i); + + String notename_str (int pitch_i); + virtual String str (); + + //private: + int accidentals_i_; + int minor_i_; +}; + +class Mudela_time_signature : public Mudela_item +{ +public: + Mudela_time_signature (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 (); + int den_i (); + int num_i (); + virtual String str (); + Moment bar_mom (); + +private: + Real sync_f_; + Duration sync_dur_; + int clocks_1_i_; + int num_i_; + int den_i_; +}; + +class Mudela_note : public Mudela_item +{ +public: + Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pitch_i, int dyn_i); + + Duration duration (); + virtual Moment duration_mom (); + virtual String str (); + + // int const c0_pitch_i_c_ = 60; // huh? + static int const c0_pitch_i_c_ = 48; + + static bool const simple_plet_b_s = false; + int channel_i_; + int pitch_i_; + Mudela_column* end_column_l_; +}; + +class Mudela_skip : public Mudela_item +{ +public: + Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom); + + Duration duration (); + virtual Moment duration_mom (); + virtual String str (); + +private: + Moment mom_; +}; + + +class Mudela_tempo : public Mudela_item +{ +public: + Mudela_tempo (int useconds_per_4_i); + + int get_tempo_i (Moment moment); + virtual String str (); + int useconds_per_4_i (); + +private: + int useconds_per_4_i_; + Moment seconds_per_1_mom_; +}; + +class Mudela_text : public Mudela_item +{ +public: + enum Type { + TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, + MARKER, CUE_POINT + }; + Mudela_text (Mudela_text::Type type, String str); + virtual String str (); + + //private: + Type type_; + String text_str_; +}; + +#endif // MUDELA_ITEM_HH + diff --git a/midi2ly/include/mudela-score.hh b/midi2ly/include/mudela-score.hh new file mode 100644 index 0000000000..8e75d028cc --- /dev/null +++ b/midi2ly/include/mudela-score.hh @@ -0,0 +1,51 @@ +// +// mudela-score.hh -- declare Mudela_score +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MUDELA_SCORE_HH +#define MUDELA_SCORE_HH + +#include "mi2mu-proto.hh" +#include "proto.hh" +#include "cons.hh" +#include "parray.hh" + +/// (mudela_score) +class Mudela_score { +public: + Mudela_score (int format_i, int tracks_i, int tempo_i); + ~Mudela_score (); + + void add_item (Mudela_item* mudela_item_p); + void add_staff (Mudela_staff* mudela_staff_p); + + Mudela_column* find_column_l (Moment mom); + Mudela_column* get_column_l (Moment mom); + + void output (String filename_str); + void process (); + + // ugh + Mudela_key* mudela_key_l_; + Mudela_time_signature* mudela_time_signature_l_; + Mudela_tempo* mudela_tempo_l_; + Mudela_staff * last_staff_l_; +private: + void filter_tempo (); + void quantify_columns (); + void quantify_durations (); + void settle_columns (); + + Cons_list mudela_staff_p_list_; + Link_array column_l_array_; + + // ugh, ugh, ugh +public: + int format_i_; + int tracks_i_; + int tempo_i_; +}; + +#endif // MUDELA_SCORE_HH + diff --git a/midi2ly/include/mudela-staff.hh b/midi2ly/include/mudela-staff.hh new file mode 100644 index 0000000000..8c0afa044a --- /dev/null +++ b/midi2ly/include/mudela-staff.hh @@ -0,0 +1,43 @@ +// +// mudela-staff.hh -- declare mudela_staff +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MUDELA_STAFF_HH +#define MUDELA_STAFF_HH + +#include "mi2mu-proto.hh" +#include "proto.hh" +#include "cons.hh" +#include "string.hh" + +/// (mudela_staff) +class Mudela_staff +{ +public: + Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str); + + void add_item (Mudela_item* mudela_item_p); + void eat_voice (Cons_list& items); + String id_str (); + String name_str (); + void output (Mudela_stream& mudela_stream_r); + void process (); + + String copyright_str_; + String instrument_str_; + String name_str_; + Mudela_key* mudela_key_l_; + Mudela_time_signature* mudela_time_signature_l_; + Mudela_tempo* mudela_tempo_l_; + int number_i_; + +private: + void output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i); + + Cons_list mudela_voice_p_list_; + Cons_list mudela_item_p_list_; +}; + +#endif // MUDELA_STAFF_HH + diff --git a/midi2ly/include/mudela-stream.hh b/midi2ly/include/mudela-stream.hh new file mode 100644 index 0000000000..6953a961cd --- /dev/null +++ b/midi2ly/include/mudela-stream.hh @@ -0,0 +1,41 @@ +// +// mudela-stream.hh -- part of LilyPond +// +// copyright 1997 Jan Nieuwenhuizen + +// should i be named Mudela_stream? + +#ifndef MUDELA_STREAM_HH +#define MUDELA_STREAM_HH + +#include "mi2mu-proto.hh" +#include "string.hh" +#include "scalar.hh" + +/// Lily output +class Mudela_stream { +public: + Mudela_stream (String filename_str); + ~Mudela_stream(); + + Mudela_stream& operator << (Scalar s); + Mudela_stream& operator << (Mudela_item& mudela_item_r); + +private: + void handle_pending_indent(); + void header(); + void open(); + void output (String str); + void output_wrapped (String str); + + ostream* os_p_; + String filename_str_; + int indent_i_; + int column_i_; + int pending_indent_i_; + int wrap_column_i_; + bool comment_mode_b_; +}; + +#endif // MUDELA_STREAM_HH + diff --git a/midi2ly/include/mudela-voice.hh b/midi2ly/include/mudela-voice.hh new file mode 100644 index 0000000000..db196da9e6 --- /dev/null +++ b/midi2ly/include/mudela-voice.hh @@ -0,0 +1,26 @@ +// +// mudela-voice.hh -- declare Mudela_voice +// +// copyright 1997 Jan Nieuwenhuizen + +#ifndef MUDELA_VOICE_HH +#define MUDELA_VOICE_HH + +#include "mi2mu-proto.hh" +#include "cons.hh" + +/// (mudela_voice) +class Mudela_voice +{ +public: + Mudela_voice (Mudela_staff* mudela_staff_l); + void add_item (Mudela_item* mudela_item_l); + void output (Mudela_stream& mudela_stream_r); + +private: + Mudela_staff* mudela_staff_l_; + Cons_list mudela_item_l_list_; +}; + +#endif // MUDELA_VOICE_HH + diff --git a/midi2ly/main.cc b/midi2ly/main.cc new file mode 100644 index 0000000000..26e0c66b8e --- /dev/null +++ b/midi2ly/main.cc @@ -0,0 +1,271 @@ +// +// main.cc -- implement silly main () entry point +// should have Root class. +// +// copyright 1997 Jan Nieuwenhuizen + +#include +#include +#include "config.hh" +#include "string-convert.hh" +#include "getopt-long.hh" +#include "file-path.hh" +#include "duration-convert.hh" +#include "source.hh" + +#include "mi2mu-global.hh" +#include "midi-score-parser.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" + +#if HAVE_GETTEXT +#include +#endif + + +// ugh +String filename_str_g; + +// ugh +Mudela_score* mudela_score_l_g = 0; + +bool no_timestamps_b_g = false; + +Sources source; + +static File_path path; + +Verbose level_ver = NORMAL_ver; + +void +usage() +{ + cout << _f ("Usage: %s [OPTION]... [FILE]", "mi2mu"); + cout << '\n'; + cout << _ ("Translate midi-file to mudela"); + cout << '\n'; + cout << '\n'; + cout << _ ("Options:"); + cout << '\n'; + cout << _ ( + " -b, --no-quantify write exact durations, e.g.: a4*385/384\n" + ); + cout << _ ( + " -D, --debug enable debugging output\n" + ); + cout << _ ( + " -h, --help this help\n" + ); + cout << _ ( + " -I, --include=DIR add DIR to search path\n" + ); + cout << _ ( + " -k, --key=ACC[:MINOR] set key: ACC +sharps/-flats; :1 minor\n" + ); + cout << _ ( + " -n, --no-silly assume no plets or double dots, smallest is 32\n" + ); + cout << _ ( + " -o, --output=FILE set FILE as default output\n" + ); + cout << _ ( + " -p, --no-plets assume no plets\n" + ); + cout << _ ( + " -q, --quiet be quiet\n" + ); + cout << _ ( + " -T, --no-timestamps don't timestamp the output\n" + ); + cout << _ ( + " -s, --smallest=N assume no shorter (reciprocal) durations than N\n" + ); + cout << _ ( + " -v, --verbose be verbose\n" + ); + cout << _ ( + " -w, --warranty show warranty and copyright\n" + ); + cout << _ ( + " -x, --no-double-dots assume no double dotted notes\n" + ); + ; +} + +void +identify() +{ + LOGOUT(NORMAL_ver) << mi2mu_version_str() << endl; +} + +void +notice() +{ + LOGOUT(NORMAL_ver) << '\n'; + LOGOUT(NORMAL_ver) << _ ("Mi2mu, translate midi to mudela"); + LOGOUT(NORMAL_ver) << '\n'; + LOGOUT(NORMAL_ver) << _f ("Copyright (c) %s by", "1997, 1998"); + LOGOUT(NORMAL_ver) << '\n'; + LOGOUT(NORMAL_ver) << " " + _ ("Han-Wen Nienhuys ") + "\n"; + LOGOUT(NORMAL_ver) << " " + _ ("Jan Nieuwenhuizen ") + "\n"; + LOGOUT(NORMAL_ver) << '\n'; + LOGOUT(NORMAL_ver) << _ ( + " This program is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU General Public License version 2\n" + "as published by the Free Software Foundation.\n" + "\n" + " This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" + "General Public License for more details.\n" + "\n" + " You should have received a copy (refer to the file COPYING) of the\n" + "GNU General Public License along with this program; if not, write to\n" + "the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,\n" + "USA.\n"); +} + +int +main (int argc_i, char* argv_sz_a[]) +{ + +#if HAVE_GETTEXT + setlocale (LC_ALL, ""); /* enable locales */ + setlocale (LC_NUMERIC, "C"); /* musn't have comma's in output */ + String name (PACKAGE); + name.to_lower (); + bindtextdomain (name.ch_C (), DIR_LOCALEDIR); + textdomain (name.ch_C ()) ; +#endif + + bool key_override_b = false; + Mudela_key key (0, 0); + + Long_option_init long_option_init_a[] = + { + {0, "no-quantify", 'b'}, + {0, "debug", 'D'}, + {0, "help", 'h'}, + {1, "key", 'k'}, + {0, "no-silly", 'n'}, + {1, "output", 'o'}, + {0, "no-plets", 'p'}, + {0, "quiet", 'q'}, + {1, "smallest", 's'}, + {0, "no-timestamps", 'T'}, + {0, "verbose", 'v'}, + {0, "warranty", 'w'}, + {0, "no-double-dots", 'x'}, + {0,0,0} + }; + Getopt_long getopt_long (argc_i, argv_sz_a, long_option_init_a); + + String output_str; + while (Long_option_init const* long_option_init_p = getopt_long()) + switch (long_option_init_p->shortname) + { + case 'b': + Duration_convert::no_quantify_b_s = true; + break; + case 'D': + level_ver = DEBUG_ver; + break; + case 'h': + identify(); + usage(); + exit (0); + break; +// case 'I': +// path->push (getopt_long.optional_argument_ch_C_); +// break; + case 'k': + { + String str = getopt_long.optional_argument_ch_C_; + int i = str.index_i (':'); + i = (i >=0 ? i : str.length_i ()); + key.accidentals_i_ = String_convert::dec2_i (str.left_str (i)); + key.minor_i_ = (int)(bool)String_convert::dec2_i (str.cut_str (i + 1, str.length_i ())); + key_override_b = true; + break; + } + case 'n': + Duration_convert::no_double_dots_b_s = true; + Duration_convert::no_triplets_b_s = true; + Duration_convert::no_smaller_than_i_s = 5; + break; + case 'o': + output_str = getopt_long.optional_argument_ch_C_; + break; + case 'p': + Duration_convert::no_triplets_b_s = true; + break; + case 'q': + level_ver = QUIET_ver; + break; + case 'T': + no_timestamps_b_g = true; + break; + case 's': + { + int i = String_convert::dec2_i (getopt_long.optional_argument_ch_C_); + if (!i) + { + identify(); + usage(); + exit (2); //usage + } + Duration_convert::no_smaller_than_i_s = + Duration_convert::i2_type(i); + } + break; + case 'v': + level_ver = VERBOSE_ver; + break; + case 'w': + identify(); + notice(); + exit (0); + break; + case 'x': + Duration_convert::no_double_dots_b_s = true; + break; + default: + assert (0); + break; + } + + // flag -q must be checked first + identify(); + + path.add (""); + source.set_binary (true); + source.set_path (&path); + + char const* arg_sz = 0; + while ( (arg_sz = getopt_long.get_next_arg ())) + { + filename_str_g = arg_sz; + Midi_score_parser midi_parser; + Mudela_score* score_p = midi_parser.parse (arg_sz, &source); + + if (!score_p) + return 1; + + // if given on command line: override + if (key_override_b || !score_p->mudela_key_l_) + score_p->mudela_key_l_ = &key; + mudela_score_l_g = score_p; + score_p->process(); + + if (!output_str.length_i ()) + { + String d, dir, base, ext; + split_path (arg_sz, d, dir, base, ext); + output_str = base + ext + ".ly"; + } + + score_p->output (output_str); + delete score_p; + } + return 0; +} diff --git a/midi2ly/mi2mu-version.cc b/midi2ly/mi2mu-version.cc new file mode 100644 index 0000000000..113512d363 --- /dev/null +++ b/midi2ly/mi2mu-version.cc @@ -0,0 +1,20 @@ +// +// version.cc -- implement inexpensive versioning +// +// copyright 1997 Jan Nieuwenhuizen + +#include +#include "config.hh" +#include "version.hh" + +#define VERSION_SZ MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL "." MY_PATCH_LEVEL + +static char *s = "mi2mu " VERSION_SZ; + + +const char * +mi2mu_version_sz() +{ + return s; +} + diff --git a/midi2ly/midi-parser.cc b/midi2ly/midi-parser.cc new file mode 100644 index 0000000000..eafd50c004 --- /dev/null +++ b/midi2ly/midi-parser.cc @@ -0,0 +1,101 @@ +/* + midi-parser.cc -- implement Midi_parser[_info] + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "source-file.hh" +#include "mi2mu-global.hh" +#include "midi-parser.hh" + +Midi_parser_info::Midi_parser_info () +{ + division_1_i_ = 0; + format_i_ = 0; + tracks_i_ = 0; + errorlevel_i_ = 0; + byte_L_ = 0; + end_byte_L_ = 0; + score_l_ = 0; +} + +Midi_parser::Midi_parser () +{ + info_l_ = 0; +} + +int +Midi_parser::exit (String str) +{ + error (str); + ::exit (1); + return 0; +} + +void +Midi_parser::error (String str) +{ + ::message (message (str)); +} + +int +Midi_parser::get_i (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +unsigned +Midi_parser::get_u (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +String +Midi_parser::get_str (int n) +{ + assert (n >= 0); + if (!n) + warning (_ ("zero length string encountered")); + + Byte const* p = forward_byte_L (n); + return String (p, n); +} + +int +Midi_parser::get_var_i () +{ + int var_i = 0; + + while (1) + { + Byte byte = next_byte (); + var_i <<= 7; + var_i += byte & 0x7f; + if (!(byte & 0x80)) + return var_i; + } + exit ("get_var_i:"); + return 0; +} + +String +Midi_parser::message (String str) +{ + return String ("mi2mu: ") + + info_l_->source_l_->name_str () + ": " + + String_convert::i2dec_str (info_l_->source_l_->line_i ((char const*)info_l_->byte_L_), 0, 0) + ": " + + str + "\n" + + info_l_->source_l_->error_str ((char const*)info_l_->byte_L_); +} + +void +Midi_parser::warning (String str) +{ + ::message (message (String (_ ("warning: ")) + str)); +} diff --git a/midi2ly/midi-score-parser.cc b/midi2ly/midi-score-parser.cc new file mode 100644 index 0000000000..c20fe468e2 --- /dev/null +++ b/midi2ly/midi-score-parser.cc @@ -0,0 +1,121 @@ +/* + midi-score-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + +#include "moment.hh" +#include "source-file.hh" +#include "source.hh" +#include "mi2mu-global.hh" +#include "midi-score-parser.hh" +#include "midi-track-parser.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" + + +void +Midi_score_parser::open (String filename_str, Sources* sources_l) +{ + info_l_->source_l_ = sources_l->get_file_l (filename_str); + if (!info_l_->source_l_) + ::error (_f ("can't find file: `%s\'", filename_str)); + info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C (); + info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1; +} + +Mudela_score* +Midi_score_parser::parse (String filename_str, Sources* sources_l) +{ + Midi_parser_info info; + info_l_ = &info; + open (filename_str, sources_l); + parse_header (); + return parse_score (); +} + +void +Midi_score_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MThd" ) + exit (_ ("MIDI header expected")); + + int length_i = get_i (4); + // is this signed? + if (length_i < 6) + exit (_ ("Invalid header length")); + info_l_->format_i_ = get_i (2); + if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1) + exit (_("Invalid midi format")); + info_l_->tracks_i_ = get_i (2); + if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 ) + exit (_("Invalid number of tracks")); + info_l_->division_1_i_ = get_i (2) * 4; + if (info_l_->division_1_i_ < 0) + exit (_f ("can't handle %s", _ ("non-metrical time"))); + // ugh + Duration::division_1_i_s = info_l_->division_1_i_; + forward_byte_L (length_i - 6); +} + +int +Midi_score_parser::find_earliest_i (Link_array& tracks) +{ + int earliest_i = 0; + Moment earliest_mom = infinity_mom; + for (int i = 0; i < tracks.size(); i++) + { + if ( tracks [i]->at_mom () < earliest_mom ) + { + earliest_mom = tracks [i]->at_mom (); + earliest_i = i; + } + } + return earliest_i; +} + +Mudela_score* +Midi_score_parser::parse_score () +{ + int current_bar_i = 0; + Mudela_time_signature m4 (4, 2, 24, 8); + Moment bar4_mom = m4.bar_mom (); + + Mudela_score* score_p = new Mudela_score( 1, 1, 1 ); + info_l_->score_l_ = score_p; + + Link_array tracks; + for (int i = 0; i < info_l_->tracks_i_; i++) + tracks.push (new Midi_track_parser (info_l_, i)); + + LOGOUT (NORMAL_ver) << _ ("Parsing...\n"); + while (tracks.size ()) + { + int i = find_earliest_i (tracks); + Moment at_mom = tracks [i]->at_mom (); + Mudela_column* column_l = score_p->get_column_l (at_mom); + Mudela_staff* staff_p = tracks [i]->parse (column_l); + if ( staff_p ) + { + score_p->add_staff (staff_p); + delete tracks [i]; + tracks.del (i); + } + + // brr, musta have some progress + for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++) + info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_; + + int bar_i = (int) (at_mom + / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1; + if (bar_i > current_bar_i) + { + LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; + current_bar_i = bar_i; + } + } + return score_p; +} diff --git a/midi2ly/midi-track-parser.cc b/midi2ly/midi-track-parser.cc new file mode 100644 index 0000000000..49840ec77c --- /dev/null +++ b/midi2ly/midi-track-parser.cc @@ -0,0 +1,360 @@ +/* + midi-track-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "mi2mu-global.hh" +#include "midi-track-parser.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" +#include "mudela-staff.hh" + +Midi_track_parser::Midi_track_parser (Midi_parser_info* info_l, int i) +{ + info_l_ = info_l; + at_mom_ = 0; + track_info_p_ = 0; + mudela_staff_p_ = new Mudela_staff (i, "", "", ""); + parse_header (); + parse_delta_time (); +} + +Midi_track_parser::~Midi_track_parser () +{ + delete mudela_staff_p_; + delete track_info_p_; +} + +Moment +Midi_track_parser::at_mom () +{ + return at_mom_; +} + +bool +Midi_track_parser::eot () +{ + if ( info_l_->byte_L_ < info_l_->end_byte_L_ ) + return false; + return true; +} + +void +Midi_track_parser::note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ) +{ + // junk dynamics + (void)aftertouch_i; + + assert (col_l); + + for (Cons** pp = &open_note_l_list_.head_; *pp;) + { + Cons* i = *pp; + if ((i->car_->pitch_i_ == pitch_i) && (i->car_->channel_i_ == channel_i)) + { + i->car_->end_column_l_ = col_l; + delete open_note_l_list_.remove_cons (pp); + return; + } + else + pp = &i->next_; + } + warning (_f ("junking note-end event: channel = %d, pitch = %d", + channel_i, pitch_i)); +} + +void +Midi_track_parser::note_end_all (Mudela_column* col_l) +{ + // find + assert (col_l); + for (Cons* i = open_note_l_list_.head_; i; i = i->next_) + { + i->car_->end_column_l_ = col_l; + } + // UGH UGH. MEMORY LEAK. + open_note_l_list_.init (); +} + +Mudela_staff* +Midi_track_parser::parse (Mudela_column* col_l) +{ + Moment mom = at_mom (); + while (!eot () && (mom == at_mom ())) + { + Mudela_item* p = parse_event (col_l); + if (p) + mudela_staff_p_->add_item (p); + } + + if (!eot()) + return 0; + + // catch-all + note_end_all (col_l); + + Mudela_staff* p = mudela_staff_p_; + mudela_staff_p_ = 0; + return p; +} + +void +Midi_track_parser::parse_delta_time () +{ + if (eot ()) + return; + int delta_i = get_var_i (); + at_mom_ += Moment (delta_i, info_l_->division_1_i_); +} + +Mudela_item* +Midi_track_parser::parse_event (Mudela_column* col_l) +{ + Byte byte = peek_byte (); + // RUNNING_STATUS [\x00-\x5f] + if (byte <= 0x5f) + { + if (running_byte_ <= 0x5f) + exit (_ ("invalid running status")); + /* + 'running status' rather means 'missing status'. + we'll just pretend we read the running status byte. + */ + byte = running_byte_; + } + else + byte = next_byte (); + + Mudela_item* item_p = 0; + // DATA_ENTRY [\x60-\x79] + if ((byte >= 0x60) && (byte <= 0x79)) + { + next_byte (); + } + // ALL_NOTES_OFF [\x7a-\x7f] + else if ((byte >= 0x7a) && (byte <= 0x7f)) + { + next_byte (); + next_byte (); + note_end_all (col_l); + } + // NOTE_OFF [\x80-\x8f] + else if ((byte >= 0x80) && (byte <= 0x8f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + note_end (col_l, channel_i, pitch_i, dyn_i); + } + // NOTE_ON [\x90-\x9f] + else if ((byte >= 0x90) && (byte <= 0x9f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + /* + sss: some broken devices encode NOTE_OFF as + NOTE_ON with zero volume + */ + if (dyn_i) + { + Mudela_note* p = new Mudela_note (col_l, channel_i, pitch_i, dyn_i); + item_p = p; + open_note_l_list_.append (new Cons (p, 0)); + } + else + { + note_end (col_l, channel_i, pitch_i, dyn_i); + } + } + + // POLYPHONIC_AFTERTOUCH [\xa0-\xaf] + else if ((byte >= 0xa0) && (byte <= 0xaf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // CONTROLMODE_CHANGE [\xb0-\xbf] + else if ((byte >= 0xb0) && (byte <= 0xbf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PROGRAM_CHANGE [\xc0-\xcf] + else if ((byte >= 0xc0) && (byte <= 0xcf)) + { + running_byte_ = byte; + next_byte (); + } + // CHANNEL_AFTERTOUCH [\xd0-\xdf] + else if ((byte >= 0xd0) && (byte <= 0xdf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PITCHWHEEL_RANGE [\xe0-\xef] + else if ((byte >= 0xe0) && (byte <= 0xef)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // SYSEX_EVENT1 [\xf0] + else if (byte == 0xf0) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // SYSEX_EVENT2 [\xf7] + else if (byte == 0xf7) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // META_EVENT [\xff] + else if (byte == 0xff) + { + // SEQUENCE [\x00][\x02] + byte = next_byte (); + if (byte == 0) + { + next_byte (); + get_i (2); + } + // YYTEXT [\x01] + // YYCOPYRIGHT [\x02] + // YYTRACK_NAME [\x03] + // YYINSTRUMENT_NAME [\x04] + // YYLYRIC [\x05] + // YYMARKER [\x06] + // YYCUE_POINT [\x07] + else if ((byte >= 0x01) && (byte <= 0x07)) + { + // LOGOUT (DEBUG_ver) << "\n% Text(" << (int)byte << "):" << flush; + int length_i = get_var_i (); + String str = get_str (length_i); + // LOGOUT (DEBUG_ver) << str << endl; + Mudela_text::Type t = (Mudela_text::Type)byte; + Mudela_text* p = new Mudela_text (t, str); + item_p = p; + if (t == Mudela_text::COPYRIGHT) + mudela_staff_p_->copyright_str_ = p->text_str_; + else if (t == Mudela_text::TRACK_NAME) + mudela_staff_p_->name_str_ = p->text_str_; + else if (t == Mudela_text::INSTRUMENT_NAME) + mudela_staff_p_->instrument_str_ = p->text_str_; + } + // END_OF_TRACK [\x2f][\x00] + else + { + Byte next = peek_byte (); + if ((byte == 0x2f) && (next == 0x00)) + { + next_byte (); + info_l_->byte_L_ = info_l_->end_byte_L_; + } + // TEMPO [\x51][\x03] + else if ((byte == 0x51) && (next == 0x03)) + { + next_byte (); + unsigned useconds_per_4_u = get_u (3); + // $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4); + // LOGOUT (DEBUG_ver) << $$->str() << endl; + Mudela_tempo* p = new Mudela_tempo ( useconds_per_4_u ); + item_p = p; + info_l_->score_l_->mudela_tempo_l_ = p; + mudela_staff_p_->mudela_tempo_l_ = p; + } + // SMPTE_OFFSET [\x54][\x05] + else if ((byte == 0x54) && (next == 0x05)) + { + next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + } + // TIME [\x58][\x04] + else if ((byte == 0x58) && (next == 0x04)) + { + next_byte (); + int num_i = (int)next_byte (); + int den_i = (int)next_byte (); + int clocks_4_i = (int)next_byte (); + int count_32_i = (int)next_byte (); + Mudela_time_signature* p = new Mudela_time_signature ( num_i, den_i, clocks_4_i, count_32_i ); + item_p = p; + info_l_->score_l_->mudela_time_signature_l_ = p; + info_l_->bar_mom_ = p->bar_mom (); + mudela_staff_p_->mudela_time_signature_l_ = p; + } + // KEY [\x59][\x02] + else if ((byte == 0x59) && (next == 0x02)) + { + next_byte (); + int accidentals_i = (int)(signed char)next_byte (); + int minor_i = (int)(bool)next_byte (); + Mudela_key* p = new Mudela_key (accidentals_i, minor_i); + item_p = p; +#if 0 + info_l_->score_l_->mudela_key_l_ = p; + mudela_staff_p_->mudela_key_l_ = p; +#endif + } + // SSME [\0x7f][\x03] + else if ((byte == 0x7f) && (next == 0x03)) + { + next_byte (); + int length_i = get_var_i (); + String str = get_str (length_i); + item_p = new Mudela_text ((Mudela_text::Type)byte, str); + } + else + { + next_byte (); + next_byte (); + warning (_ ("unimplemented MIDI meta-event")); + } + } + } + else + exit (_ ("invalid MIDI event")); + + if (item_p) + item_p->mudela_column_l_ = col_l; + + parse_delta_time (); + + return item_p; +} + +void +Midi_track_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MTrk" ) + exit (_ ("MIDI track expected")); + + int length_i = get_i (4); + // is this signed? + if (length_i < 0) + exit (_ ("invalid track length")); + assert (!track_info_p_); + track_info_p_ = new Midi_parser_info (*info_l_); + track_info_p_->end_byte_L_ = track_info_p_->byte_L_ + length_i; + forward_byte_L (length_i); + // forward_byte_L (length_i-1); + info_l_ = track_info_p_; +} diff --git a/midi2ly/mudela-column.cc b/midi2ly/mudela-column.cc new file mode 100644 index 0000000000..833b351f81 --- /dev/null +++ b/midi2ly/mudela-column.cc @@ -0,0 +1,24 @@ +// +// mudela-column.cc -- implement Mudela_column +// +// copyright 1997 Jan Nieuwenhuizen + +#include "mudela-column.hh" + +Mudela_column::Mudela_column (Mudela_score* mudela_score_l, Moment mom) +{ + mudela_score_l_ = mudela_score_l; + at_mom_ = mom; +} + +void +Mudela_column::add_item (Mudela_item* mudela_item_l) +{ + mudela_item_l_list_.append (new Cons (mudela_item_l, 0)); +} + +Moment +Mudela_column::at_mom() +{ + return at_mom_; +} diff --git a/midi2ly/mudela-item.cc b/midi2ly/mudela-item.cc new file mode 100644 index 0000000000..58a1db586b --- /dev/null +++ b/midi2ly/mudela-item.cc @@ -0,0 +1,363 @@ +// +// mudela-item.cc -- implement Mudela_item +// +// copyright 1997 Jan Nieuwenhuizen + +#include +#include "mi2mu-global.hh" +#include "string-convert.hh" +#include "duration-convert.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-stream.hh" +#include "mudela-score.hh" + +Mudela_item::Mudela_item (Mudela_column* mudela_column_l) +{ + mudela_column_l_ = mudela_column_l; +} + +Mudela_item::~Mudela_item () +{ +} + +Moment +Mudela_item::at_mom () +{ + return mudela_column_l_->at_mom (); +} + +Moment +Mudela_item::duration_mom () +{ + return Moment (0); +} + +void +Mudela_item::output (Mudela_stream& mudela_stream_r) +{ + mudela_stream_r << str () << " "; +} + +Mudela_key::Mudela_key (int accidentals_i, int minor_i) + : Mudela_item (0) +{ + accidentals_i_ = accidentals_i; + minor_i_ = minor_i; +} + +char const *accname[] = {"eses", "es", "", "is" , "isis"}; + +String +Mudela_key::str () +{ + int key_i = accidentals_i_ >= 0 + ? ((accidentals_i_ % 7) ["cgdaebf"] - 'a' - 2 -2 * minor_i_ + 7) % 7 + : ((-accidentals_i_ % 7) ["cfbeadg"] - 'a' - 2 -2 * minor_i_ + 7) % 7; + + String notename_str = !minor_i_ + ? to_str ((char) ((key_i + 2) % 7 + 'A')) + : to_str ((char) ((key_i + 2) % 7 + 'a')); + + // fis cis gis dis ais eis bis + static int sharps_i_a [7] = { 2, 4, 6, 1, 3, 5, 7 }; + // bes es as des ges ces fes + static int flats_i_a [7] = { 6, 4, 2, 7, 5, 3, 1 }; + int accidentals_i = accidentals_i_ >= 0 + ? sharps_i_a [key_i] <= accidentals_i_ ? 1 : 0 + : flats_i_a [key_i] <= -accidentals_i_ ? -1 : 0; + + if (accidentals_i) + notename_str += String (accname [accidentals_i + 2]); + + return "\\key " + notename_str + (minor_i_ ? "\\minor" : "") + ";\n"; +} + +String +Mudela_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 [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 *= -1; + notename_i = (notename_i + 1) % 7; + } + + String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a')); + if (accidental_i) + notename_str += String (accname [accidental_i + 2]); + + /* + By tradition, all scales now consist of a sequence of 7 notes each + with a distinct name, from amongst a b c d e f g. But, minor scales + have a wide second interval at the top - the 'leading note' is + sharped. (Why? it just works that way! Anything else doesn't sound as + good and isn't as flexible at saying things. In medieval times, + scales only had 6 notes to avoid this problem - the hexachords.) + + So, the d minor scale is d e f g a b-flat c-sharp d - using d-flat + for the leading note would skip the name c and duplicate the name d. + Why isn't c-sharp put in the key signature? Tradition. (It's also + supposedly based on the Pythagorean theory of the cycle of fifths, + but that really only applies to major scales...) + + Anyway, g minor is g a b-flat c d e-flat f-sharp g, and all the other + flat minor keys end up with a natural leading note. And there you + have it. + + John Sankey + + Let's also do a-minor: a b c d e f gis a + + --jcn + + */ + + /* ok, bit ugly, but here we go -- jcn */ + + + if (minor_i_) + { + if ((accidentals_i_ == 0) && (notename_str == "as")) + notename_str = "gis"; + else if ((accidentals_i_ == -1) && (notename_str == "des")) + notename_str = "cis"; + else if ((accidentals_i_ == -2) && (notename_str == "ges")) + notename_str = "fis"; + else if ((accidentals_i_ == 5) && (notename_str == "g")) + notename_str = "fisis"; + else if ((accidentals_i_ == 6) && (notename_str == "d")) + notename_str = "cisis"; + else if ((accidentals_i_ == 7) && (notename_str == "a")) + notename_str = "gisis"; + + if ((accidentals_i_ <= -6) && (notename_str == "b")) + notename_str = "ces"; + if ((accidentals_i_ <= -7) && (notename_str == "e")) + notename_str = "fes"; + } + + String de_octavate_str = to_str (',', (Mudela_note::c0_pitch_i_c_ + 11 - pitch_i) / 12); + String octavate_str = to_str ('\'', (pitch_i - Mudela_note::c0_pitch_i_c_) / 12); + return notename_str +de_octavate_str + octavate_str; +} + +Mudela_time_signature::Mudela_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i) + : Mudela_item (0) +{ + sync_dur_.durlog_i_ = 3; + sync_f_ = 1.0; + if (count_32_i != 8) + warning (_f ("#32 in quarter: %d", count_32_i)); + num_i_ = num_i; + den_i_ = den_i; + clocks_1_i_ = clocks_4_i * 4; +} + +Moment +Mudela_time_signature::bar_mom () +{ + Duration d; + d.durlog_i_ = den_i_; + return Moment (num_i_) * Duration_convert::dur2_mom (d); +} + +int +Mudela_time_signature::clocks_1_i () +{ + return clocks_1_i_; +} + +int +Mudela_time_signature::den_i () +{ + return den_i_; +} + +int +Mudela_time_signature::num_i () +{ + return num_i_; +} + +String +Mudela_time_signature::str () +{ + String str = "\\time " + + to_str (num_i_) + "/" + to_str (1 << den_i_) + + ";\n"; + return str; +} + + +// statics Mudela_note +/* + this switch can be used to write simple plets like + c4*2/3 + as + \plet 2/3; c4 \plet 1/1; + */ +/* + UGH: .hh says false, .cc says true. + FIXME. + */ +bool const Mudela_note::simple_plet_b_s; + +Mudela_note::Mudela_note (Mudela_column* mudela_column_l, + int channel_i, int pitch_i, int dyn_i) + : Mudela_item (mudela_column_l) +{ + // junk dynamics + (void)dyn_i; + channel_i_ = channel_i; + pitch_i_ = pitch_i; + end_column_l_ = 0; +} + +Duration +Mudela_note::duration () +{ + assert (end_column_l_); + Moment mom = end_column_l_->at_mom () - at_mom (); + return Duration_convert::mom2_dur (mom); +} + +Moment +Mudela_note::duration_mom () +{ + assert (end_column_l_); + return end_column_l_->at_mom () - at_mom (); +} + +String +Mudela_note::str () +{ + Duration dur = duration (); + if (dur.durlog_i_ < -10) + return ""; + + String name_str + = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_); + + if (simple_plet_b_s) + return name_str + Duration_convert::dur2_str (dur) + " "; + + String str; + + //ugh + if (dur.plet_b ()) + str += String ("\\times ") + + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0) + + "/" + + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0) + + " { "; + + + str += name_str; + + Duration tmp = dur; + tmp.set_plet (1,1); + str += Duration_convert::dur2_str (tmp); + + if (dur.plet_b ()) + str += String (" }"); + + /* + note of zero duration is nonsense, + but let's output anyway for convenient debugging + */ + if (!duration_mom ()) + return String ("\n% ") + str + "\n"; + + return str + " "; +} + +Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) + : Mudela_item (mudela_column_l) +{ + mom_ = skip_mom; +} + +Duration +Mudela_skip::duration () +{ + return Duration_convert::mom2_dur (mom_); +} + +Moment +Mudela_skip::duration_mom () +{ + return Duration_convert::dur2_mom (duration ()); +} + +String +Mudela_skip::str () +{ + if (!mom_) + return String (""); + + Duration dur = duration (); + if (dur.durlog_i_<-10) + return ""; + + String str = "\\skip "; + str += Duration_convert::dur2_str (dur) + "; "; + + return str; +} + +Mudela_tempo::Mudela_tempo (int useconds_per_4_i) + : Mudela_item (0) +{ + useconds_per_4_i_ = useconds_per_4_i; + seconds_per_1_mom_ = Moment(useconds_per_4_i_ *4, 1e6); +} + +String +Mudela_tempo::str () +{ + String str = "\\tempo 4="; + str += to_str (get_tempo_i (Moment (1, 4))); + str += ";\n"; + return str; +} + +int +Mudela_tempo::useconds_per_4_i () +{ + return useconds_per_4_i_; +} + +int +Mudela_tempo::get_tempo_i (Moment moment) +{ + Moment m1 = Moment (60) / moment; + Moment m2 = seconds_per_1_mom_; + return m1 / m2; +} + +Mudela_text::Mudela_text (Mudela_text::Type type, String text_str) + : Mudela_item (0) +{ + type_ = type; + text_str_ = text_str; +} + +String +Mudela_text::str () +{ + if (!text_str_.length_i () + || (text_str_.length_i () != (int)strlen (text_str_.ch_C ()))) + return ""; + + return "% " + text_str_ + "\n"; +} diff --git a/midi2ly/mudela-score.cc b/midi2ly/mudela-score.cc new file mode 100644 index 0000000000..6916d80df7 --- /dev/null +++ b/midi2ly/mudela-score.cc @@ -0,0 +1,256 @@ +// +// mudela-score.cc -- implement Mudela_score +// +// copyright 1997 Jan Nieuwenhuizen + +#include +#include "moment.hh" +#include "duration.hh" +#include "duration-convert.hh" +#include "mi2mu-global.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" +#include "mudela-staff.hh" +#include "mudela-stream.hh" + +#include "killing-cons.tcc" + +//static Mudela_key key_c (0, 0); +static Mudela_time_signature time_sig_4 (4, 2, 24, 8); +// useconds per 4: 250000 === 60 4 per minute +static Mudela_tempo tempo_60 (1000000); + +Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i) +{ + last_staff_l_ =0; + format_i_ = format_i; + tracks_i_ = tracks_i; + tempo_i_ = tempo_i; + column_l_array_.push (new Mudela_column (this, Moment (0))); + // mudela_key_l_ = &key_c; + mudela_key_l_ = 0; + mudela_time_signature_l_ = &time_sig_4; + mudela_tempo_l_ = &tempo_60; +} + +Mudela_score::~Mudela_score () +{ +} + +void +Mudela_score::add_item (Mudela_item* mudela_item_p) +{ + last_staff_l_->add_item (mudela_item_p); +} + +void +Mudela_score::add_staff (Mudela_staff* mudela_staff_p) +{ + mudela_staff_p_list_.append (new Killing_cons (mudela_staff_p, 0)); + last_staff_l_ = mudela_staff_p; +} + +Mudela_column* +Mudela_score::find_column_l (Moment mom) +{ + int upper_i = max (0, column_l_array_.size () - 1); + int lower_i = 0; + int i = 0; //upper_i; + while (1) + { + Moment i_mom = column_l_array_ [i]->at_mom (); + if (i_mom == mom) + return column_l_array_ [i]; + if (mom < i_mom) + upper_i = i; + else + lower_i = i; + if ( (upper_i == lower_i) || (i == column_l_array_.size () - 1)) + { + // we don't do inserts + assert (0); + Mudela_column* col_p = new Mudela_column (this, mom); + column_l_array_.push (col_p); + return col_p; + } + i = (upper_i + lower_i + 1 ) / 2; + } + assert (0); + return 0; +} + +Mudela_column* +Mudela_score::get_column_l (Moment mom) +{ + int i; + Mudela_column *c=0; + for (i=column_l_array_.size () - 1; !c && i >=0; i--) + { + if (column_l_array_ [i]->at_mom () == mom ) + c = column_l_array_[i]; + else if (column_l_array_[i]->at_mom () < mom) + break; + } + if (!c) + { + c = new Mudela_column (this, mom); + column_l_array_.insert (c, i+1); + } + + assert (c->at_mom () == mom); + return c; +} + +void +Mudela_score::output (String filename_str) +{ + LOGOUT (NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl; + + // ugh, ugly midi type 1 fix + if ( (mudela_staff_p_list_.size_i () == 1) + && !mudela_staff_p_list_.head_->car_->number_i_) + mudela_staff_p_list_.head_->car_->number_i_ = 1; + + int track_i = 0; + Mudela_stream mudela_stream (filename_str); + for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) + { + LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush; + i->car_->output (mudela_stream); + mudela_stream << '\n'; + LOGOUT (NORMAL_ver) << endl; + } + + mudela_stream << "\\score{\n"; + if (mudela_staff_p_list_.size_i () > 1) + mudela_stream << "< \n"; + for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) + { + if ( (mudela_staff_p_list_.size_i () != 1) + && (i->car_ == mudela_staff_p_list_.head_->car_)) + continue; + mudela_stream << "\\type Staff = \"" << i->car_->id_str () << "\" "; + mudela_stream << String ("\\" + i->car_->id_str ()) << "\n"; + } + if (mudela_staff_p_list_.size_i () > 1) + mudela_stream << ">\n"; + + mudela_stream << "\\paper{}\n"; + +#if 0 + mudela_stream << "\\midi{\n"; + + // let's not use silly 0 track + last_cons (mudela_staff_p_list_.head_)->car_->mudela_tempo_l_->output (mudela_stream); + mudela_stream << "}\n"; +#endif + + mudela_stream << "}\n"; +} + +void +Mudela_score::process () +{ + LOGOUT (NORMAL_ver) << '\n' << _ ("Processing...") << endl; + + LOGOUT (DEBUG_ver) << "columns\n"; + + settle_columns (); + filter_tempo (); + quantify_columns (); + quantify_durations (); + + LOGOUT (NORMAL_ver) << '\n' << _ ("Creating voices...") << endl; + int track_i = 0; + for (Cons* i = mudela_staff_p_list_.head_; i; i = i->next_) + { + LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush; + i->car_->process (); + LOGOUT (NORMAL_ver) << endl; + } +} + +void +Mudela_score::filter_tempo () +{ + LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl; +} + +void +Mudela_score::quantify_columns () +{ + // ugh + if (Duration_convert::no_quantify_b_s) + { + LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Quantifying columns...") << endl; + return; + } + + LOGOUT (NORMAL_ver) << '\n' << _ ("Quantifying columns...") << endl; + + int current_bar_i = 0; + Moment bar_mom = mudela_time_signature_l_->bar_mom (); + + int n = 5 >? Duration_convert::no_smaller_than_i_s; + n = Duration_convert::type2_i (n); + Moment s = Moment (1, n); + for (int i = 0; i < column_l_array_.size (); i++) + { + column_l_array_ [i]->at_mom_ = + s * Moment ( (int) ( (column_l_array_ [i]->at_mom ()) / s)); + + int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1; + if (bar_i > current_bar_i) + + { + LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush; + current_bar_i = bar_i; + } + } + LOGOUT (NORMAL_ver) << endl; +} + +void +Mudela_score::quantify_durations () +{ + +} + +void +Mudela_score::settle_columns () +{ + LOGOUT (NORMAL_ver) << '\n' << _ ("Settling columns...") << endl; + + int n = column_l_array_.size (); + + int start_i = 0; + int end_i = 0; + Moment start_mom = 0; + + Duration smallest_dur; + smallest_dur.durlog_i_ = 6; + Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur) + / Moment (2); + for (int i = 0; i < n; i++) + { + if (!start_i) + { + start_i = end_i = i; + start_mom = column_l_array_ [i]->at_mom (); + continue; + } + + // find all columns within noise's distance + while ( (i < n) + && (column_l_array_ [i]->at_mom () - start_mom < noise_mom)) + end_i = ++i; + + // bluntly set all to time of first in group + for (int j = start_i; j < end_i; j++) + column_l_array_ [j]->at_mom_ = start_mom; + + start_i = end_i = 0; + } +} + diff --git a/midi2ly/mudela-staff.cc b/midi2ly/mudela-staff.cc new file mode 100644 index 0000000000..d6088e1bec --- /dev/null +++ b/midi2ly/mudela-staff.cc @@ -0,0 +1,252 @@ +// +// mudela-staff.cc -- implement Mudela_staff +// +// copyright 1997 Jan Nieuwenhuizen + +#include +#include +#include "moment.hh" +#include "duration-convert.hh" +#include "string-convert.hh" +#include "mi2mu-proto.hh" +#include "mi2mu-global.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-staff.hh" +#include "mudela-stream.hh" +#include "mudela-voice.hh" +#include "mudela-score.hh" + +#include "killing-cons.tcc" + +extern Mudela_score* mudela_score_l_g; + +Mudela_staff::Mudela_staff (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; + name_str_ = track_name_str; + mudela_key_l_ = 0; + mudela_time_signature_l_ = 0; + mudela_tempo_l_ = 0; +} + +void +Mudela_staff::add_item (Mudela_item* mudela_item_p) +{ + mudela_item_p_list_.append (new Killing_cons (mudela_item_p, 0)); + if (mudela_item_p->mudela_column_l_) + mudela_item_p->mudela_column_l_->add_item (mudela_item_p); +} + +void +Mudela_staff::eat_voice (Cons_list& items) +{ + Mudela_voice* voice_p = new Mudela_voice (this); + mudela_voice_p_list_.append (new Killing_cons (voice_p, 0)); + + // Moment mom = items.top ()->at_mom (); + Moment mom = 0; + + for (Cons** pp = &items.head_; *pp;) + { + Cons* i = *pp; + LOGOUT (DEBUG_ver) << "At: " << i->car_->at_mom ().str () << "; "; + LOGOUT (DEBUG_ver) << "dur: " << i->car_->duration_mom ().str () << "; "; + LOGOUT (DEBUG_ver) << "mom: " << mom.str () << " -> "; + if (i->car_->at_mom () > mom) + { + Moment dur = i->car_->at_mom () - mom; + // ugh, need score + Mudela_column* start = mudela_score_l_g->find_column_l (mom); + voice_p->add_item (new Mudela_skip (start, dur)); + mom = i->car_->at_mom (); + } + if (i->car_->at_mom () == mom) + { + mom = i->car_->at_mom () + i->car_->duration_mom (); + Cons* c = items.remove_cons (pp); + voice_p->add_item (c->car_); + delete c; + } + else if (*pp) + pp = &i->next_; + LOGOUT (DEBUG_ver) << "mom: " << mom.str () << '\n'; + } +} + +String +Mudela_staff::id_str () +{ + String id (name_str ()); + char *cp = id.ch_l (); + char *end = cp + id.length_i (); + for (;cp < end; cp++) + { + if (!isalpha (*cp)) + { + *cp = 'X'; + } + } + return id; +} + +String +Mudela_staff::name_str () +{ + if (name_str_.length_i ()) + return name_str_; + return String ("track") + to_str (char ('A' - 1 + number_i_)); +} + + + +void +Mudela_staff::output (Mudela_stream& mudela_stream_r) +{ + mudela_stream_r << id_str () << " = \\notes"; + mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "<" : "{"); + mudela_stream_r << '\n'; + mudela_stream_r << _ ("% midi copyright:") << copyright_str_ << '\n'; + mudela_stream_r << _ ("% instrument:") << instrument_str_ << '\n'; + + // don't use last duration mode + // mudela_stream_r << "\\duration 4;\n"; + if (mudela_voice_p_list_.size_i () == 1) + mudela_voice_p_list_.head_->car_->output (mudela_stream_r); + else + for (Cons* i = mudela_voice_p_list_.head_; i; i = i->next_) + { + mudela_stream_r << "{ "; + i->car_->output (mudela_stream_r); + mudela_stream_r << "} "; + } + + mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "\n>" : "\n}"); + mudela_stream_r << " % " << name_str () << '\n'; +} + +void +Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i) +{ + Moment bar_mom = mudela_time_signature_l_->bar_mom (); + Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom; + if (bar_i > 1) + { + if (!into_bar_mom) + mudela_stream_r << "|\n"; + } + mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' '); + if (into_bar_mom) + mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom)); + mudela_stream_r << '\n'; +} + + +#if 0 // not used for now +void +Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom) +{ + Moment bar_mom = mudela_time_signature_l_->bar_mom (); + Moment now_mom = begin_mom; + + int begin_bar_i = (int) (now_mom / bar_mom) + 1; + int end_bar_i = (int) (end_mom / bar_mom) + 1; + + if (end_bar_i == begin_bar_i) + { + output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom); + return; + } + + // multiple bars involved + int bar_i = (int) (now_mom / bar_mom) + 1; + + //fill current bar + Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom; + if (now_mom > begin_bar_mom) + { + int next_bar_i = (int) (now_mom / bar_mom) + 2; + Moment next_bar_mom = Moment (next_bar_i - 1) * bar_mom; + assert (next_bar_mom <= end_mom); + + Moment remain_mom = next_bar_mom - now_mom; + if (remain_mom > Moment (0)) + { + output_mudela_rest_remain (mudela_stream_r, remain_mom); + now_mom += remain_mom; + } + + bar_i = check_end_bar_i (now_mom, bar_i); + } + + // fill whole bars + int count_i = end_bar_i - bar_i; + for (int i = 0; i < count_i; i++) + { + int begin_bar_i = check_begin_bar_i (now_mom, bar_i); + if (begin_bar_i) + output_mudela_begin_bar (mudela_stream_r, now_mom, begin_bar_i); + mudela_stream_r << "r1 "; + // *mudela_stream_r.os_p_ << flush; + if (begin_bar_i) + LOGOUT (NORMAL_ver) << begin_bar_i << flush; + bar_i = check_end_bar_i (now_mom, bar_i); + now_mom += bar_mom; + } + + // use "int i" here, and gcc 2.7.2 hits internal compiler error + int ii = check_begin_bar_i (now_mom, bar_i); + if (ii) + output_mudela_begin_bar (mudela_stream_r, now_mom, ii); + + // bar_i = check_end_bar_i (now_mom, bar_i); + + Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom; + if (remain_mom > Moment (0)) + { + output_mudela_rest_remain (mudela_stream_r, remain_mom); + now_mom += remain_mom; + } + assert (now_mom == end_mom); +} + +void +Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom) +{ + if (Duration_convert::no_quantify_b_s) + { + Duration dur = Duration_convert::mom2_dur (mom); + mudela_stream_r << "r" << dur.str () << " "; + // assert (mom == dur.mom ()); + assert (mom == dur.length ()); + return; + } + + Duration dur = Duration_convert::mom2standardised_dur (mom); + if (dur.type_i_>-10) + mudela_stream_r << "r" << dur.str () << " "; +} +#endif + + +void +Mudela_staff::process () +{ + /* + group items into voices + */ + + assert (mudela_score_l_g); + mudela_key_l_ = mudela_score_l_g->mudela_key_l_; + mudela_time_signature_l_ = mudela_score_l_g->mudela_time_signature_l_; + mudela_tempo_l_ = mudela_score_l_g->mudela_tempo_l_; + + Cons_list items; + for (Cons* i = mudela_item_p_list_.head_; i; i = i->next_) + items.append (new Cons (i->car_, 0)); + + while (items.size_i ()) + eat_voice (items); +} diff --git a/midi2ly/mudela-stream.cc b/midi2ly/mudela-stream.cc new file mode 100644 index 0000000000..5bdfd11e25 --- /dev/null +++ b/midi2ly/mudela-stream.cc @@ -0,0 +1,184 @@ +// +// mudela-stream.cc +// +// source file of the LilyPond music typesetter +// +// (c) 1997--1998, 1998 Jan Nieuwenhuizen + +#include +#include +#include +#include "mi2mu-global.hh" +#include "mudela-item.hh" +#include "mudela-stream.hh" +#include "string-convert.hh" + +extern String filename_str_g; + +static int const INDENT_i = 8; + +Mudela_stream::Mudela_stream (String filename_str) +{ + filename_str_ = filename_str; + pending_indent_i_ = 0; + os_p_ = 0; + indent_i_ = 0; + comment_mode_b_ = false; + column_i_ = 0; + wrap_column_i_ = 68; + open(); + header(); +} + +Mudela_stream::~Mudela_stream() +{ + delete os_p_; + if (indent_i_) + warning (_f ("lily indent level: %d", indent_i_)); +} + +Mudela_stream& +Mudela_stream::operator << (Scalar s) +{ + static String word_sep_str = "{} \t\n"; + while (s.length_i()) + { + int i = s.index_any_i (word_sep_str) + 1; + if (!i) + i = s.length_i(); + String word = s.left_str (i); + s = s.cut_str (i, s.length_i()); + output_wrapped (word); + } + return *this; +} + +Mudela_stream& +Mudela_stream::operator << (Mudela_item& mudela_item_r) +{ + mudela_item_r.output (*this); + *os_p_ << flush; + return *this; +} + +void +Mudela_stream::handle_pending_indent() +{ + *os_p_ << String_convert::char_str ('\t', pending_indent_i_); + column_i_ += pending_indent_i_ * INDENT_i; + pending_indent_i_ = 0; +} + +void +Mudela_stream::header() +{ + *os_p_ << _ ("% Creator: "); + if (no_timestamps_b_g) + *os_p_ << "GNU LilyPond\n"; + else + *os_p_ << mi2mu_version_str() << '\n'; + *os_p_ << _ ("% Automatically generated"); + if (no_timestamps_b_g) + *os_p_ << ".\n"; + else + { + *os_p_ << _ (", at "); + time_t t (time (0)); + *os_p_ << ctime (&t) << "%\n"; + } + *os_p_ << _ ("% from input file: "); + // *os_p_ << midi_parser_l_g->filename_str_; + // ugh + *os_p_ << filename_str_g; + *os_p_ << "\n\n"; + // ugh + *os_p_ << "\\version \"1.0.14\";\n"; +} + +void +Mudela_stream::open() +{ + os_p_ = new ofstream (filename_str_.ch_C ()); + if (!*os_p_) + error (_f ("can't open file: `%s\'", filename_str_)); +} + +void +Mudela_stream::output (String str) +{ + for (int i = 0; i < str.length_i(); i++) + { + char c = str[ i ]; + switch (c) + { + case '{' : + case '<' : + handle_pending_indent(); + if (column_i_ == indent_i_ * INDENT_i) + output ("\t"); + indent_i_++; + *os_p_ << c; + column_i_++; + break; + case '}' : + case '>' : + assert (indent_i_); + indent_i_--; + if (pending_indent_i_) + pending_indent_i_--; + handle_pending_indent(); + *os_p_ << c; + column_i_++; + break; + case '%' : + handle_pending_indent(); + comment_mode_b_ = true; + *os_p_ << c; + column_i_++; + break; + case '\t' : + handle_pending_indent(); + *os_p_ << c; + column_i_ += INDENT_i; + break; + case '\n' : + *os_p_ << endl; + pending_indent_i_ = indent_i_; + column_i_ = 0; + comment_mode_b_ = false; + break; + default : + handle_pending_indent(); + *os_p_ << c; + column_i_++; + break; + } + } +} + +void +Mudela_stream::output_wrapped (String str) +{ + // enough room left -> doit + if (column_i_ + str.length_i() <= wrap_column_i_) + { + output (str); + return; + } + + // we're at BOL already; this will never fit -> doit + if (column_i_ == indent_i_ * INDENT_i) + { + output (str); + return; + } + + // ok, let's wrap + // preserve comment mode + if (comment_mode_b_) + output (String ("\n%")); + else + output (String ("\n")); + + output (str); +} diff --git a/midi2ly/mudela-voice.cc b/midi2ly/mudela-voice.cc new file mode 100644 index 0000000000..286d2176c9 --- /dev/null +++ b/midi2ly/mudela-voice.cc @@ -0,0 +1,69 @@ +// +// mudela-voice.cc -- implement Mudela_voice +// +// copyright 1997 Jan Nieuwenhuizen + +#include "string-convert.hh" +#include "mi2mu-global.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-staff.hh" +#include "mudela-stream.hh" +#include "mudela-voice.hh" +#include "mudela-score.hh" + +extern Mudela_score* mudela_score_l_g; + +Mudela_voice::Mudela_voice (Mudela_staff* mudela_staff_l) +{ + mudela_staff_l_ = mudela_staff_l; +} + +void +Mudela_voice::add_item (Mudela_item* mudela_item_l) +{ + mudela_item_l_list_.append (new Cons (mudela_item_l, 0)); +} + + +static int const FAIRLY_LONG_VOICE_i = 6; + +void +Mudela_voice::output (Mudela_stream& mudela_stream_r) +{ + if (!mudela_item_l_list_.size_i ()) + return; + + if (mudela_item_l_list_.size_i () > FAIRLY_LONG_VOICE_i) + mudela_stream_r << '\n'; + + int current_bar_i = 0; + Moment bar_mom = mudela_staff_l_->mudela_time_signature_l_->bar_mom (); + + for (Cons* i = mudela_item_l_list_.head_; i; i = i->next_) + { + Moment at_mom = i->car_->mudela_column_l_->at_mom (); + int bar_i = (int) (at_mom / bar_mom) + 1; + if (bar_i > current_bar_i) + { + if (current_bar_i) + { + if (at_mom == Moment (bar_i - 1) * bar_mom) + mudela_stream_r << "|"; + mudela_stream_r << "\n% "; + mudela_stream_r << String_convert::i2dec_str (bar_i, 0, ' '); + mudela_stream_r << '\n'; + } + LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush; + current_bar_i = bar_i; + } + + mudela_stream_r << *i->car_; + if (Mudela_key* k = dynamic_cast (i->car_)) + mudela_staff_l_->mudela_key_l_ = mudela_score_l_g->mudela_key_l_ = k; + } + + if (mudela_item_l_list_.size_i () > FAIRLY_LONG_VOICE_i) + mudela_stream_r << '\n'; +} +