+++ /dev/null
-//
-// mi2mu-global.hh -- declare global (sic) stuff for mi2mu
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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
-
+++ /dev/null
-/*
- midi-parser.hh -- declare Midi_parser
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-
-#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
+++ /dev/null
-/*
- midi-score-parser.hh -- declare
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-
-#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<Midi_track_parser*>& tracks);
- int find_earliest_i (Link_array<Midi_track_parser>& tracks);
- Mudela_score* parse_score ();
-};
-
-#endif // MIDI_SCORE_PARSER_HH
+++ /dev/null
-/*
- midi-track-parser.hh -- declare
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-
-#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<Mudela_note> open_note_l_list_;
- Mudela_staff* mudela_staff_p_;
- Midi_parser_info* track_info_p_;
-};
-
-#endif // MIDI_TRACK_PARSER_HH
+++ /dev/null
-//
-// mudela-column.hh -- declare Mudela_column
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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> mudela_item_l_list_;
- Moment at_mom_;
- Mudela_score* mudela_score_l_;
-};
-
-#endif // MUDELA_COLUMN_HH
-
+++ /dev/null
-//
-// mudela-item.hh -- declare mudela_item
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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
-
+++ /dev/null
-//
-// mudela-score.hh -- declare Mudela_score
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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> mudela_staff_p_list_;
- Link_array<Mudela_column> column_l_array_;
-
- // ugh, ugh, ugh
-public:
- int format_i_;
- int tracks_i_;
- int tempo_i_;
-};
-
-#endif // MUDELA_SCORE_HH
-
+++ /dev/null
-//
-// mudela-staff.hh -- declare mudela_staff
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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<Mudela_item>& 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> mudela_voice_p_list_;
- Cons_list<Mudela_item> mudela_item_p_list_;
-};
-
-#endif // MUDELA_STAFF_HH
-
+++ /dev/null
-//
-// mudela-stream.hh -- part of LilyPond
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-// 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
-
+++ /dev/null
-//
-// mudela-voice.hh -- declare Mudela_voice
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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> mudela_item_l_list_;
-};
-
-#endif // MUDELA_VOICE_HH
-
+++ /dev/null
-//
-// main.cc -- implement silly main () entry point
-// should have Root class.
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <assert.h>
-#include <locale.h>
-#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 <libintl.h>
-#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 <hanwen@cs.uu.nl>") + "\n";
- LOGOUT(NORMAL_ver) << " " + _ ("Jan Nieuwenhuizen <janneke@gnu.org>") + "\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;
-}
+++ /dev/null
-//
-// version.cc -- implement inexpensive versioning
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <stdio.h>
-#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;
-}
-
+++ /dev/null
-/*
- midi-parser.cc -- implement Midi_parser[_info]
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#include <assert.h>
-#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));
-}
+++ /dev/null
-/*
- midi-score-parser.cc -- implement
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#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<Midi_track_parser>& 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<Midi_track_parser> 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;
-}
+++ /dev/null
-/*
- midi-track-parser.cc -- implement
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#include <assert.h>
-#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<Mudela_note>** pp = &open_note_l_list_.head_; *pp;)
- {
- Cons<Mudela_note>* 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<Mudela_note>* 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<Mudela_note> (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_;
-}
+++ /dev/null
-//
-// mudela-column.cc -- implement Mudela_column
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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> (mudela_item_l, 0));
-}
-
-Moment
-Mudela_column::at_mom()
-{
- return at_mom_;
-}
+++ /dev/null
-//
-// mudela-item.cc -- implement Mudela_item
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <assert.h>
-#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 <bf250@freenet.carleton.ca>
-
- 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";
-}
+++ /dev/null
-//
-// mudela-score.cc -- implement Mudela_score
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <assert.h>
-#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> (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<Mudela_staff>* 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<Mudela_staff>* 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<Mudela_staff>* 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;
- }
-}
-
+++ /dev/null
-//
-// mudela-staff.cc -- implement Mudela_staff
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <assert.h>
-#include <ctype.h>
-#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> (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<Mudela_item>& items)
-{
- Mudela_voice* voice_p = new Mudela_voice (this);
- mudela_voice_p_list_.append (new Killing_cons<Mudela_voice> (voice_p, 0));
-
- // Moment mom = items.top ()->at_mom ();
- Moment mom = 0;
-
- for (Cons<Mudela_item>** pp = &items.head_; *pp;)
- {
- Cons<Mudela_item>* 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<Mudela_item>* 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<Mudela_voice>* 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<Mudela_item> items;
- for (Cons<Mudela_item>* i = mudela_item_p_list_.head_; i; i = i->next_)
- items.append (new Cons<Mudela_item> (i->car_, 0));
-
- while (items.size_i ())
- eat_voice (items);
-}
+++ /dev/null
-//
-// mudela-stream.cc
-//
-// source file of the LilyPond music typesetter
-//
-// (c) 1997--1998, 1998 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#include <assert.h>
-#include <time.h>
-#include <fstream.h>
-#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);
-}
+++ /dev/null
-//
-// mudela-voice.cc -- implement Mudela_voice
-//
-// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
-
-#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> (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<Mudela_item>* 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<Mudela_key*> (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';
-}
-
--- /dev/null
+//
+// mi2mu-global.hh -- declare global (sic) stuff for mi2mu
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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
+
--- /dev/null
+/*
+ midi-parser.hh -- declare Midi_parser
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#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
--- /dev/null
+/*
+ midi-score-parser.hh -- declare
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#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<Midi_track_parser*>& tracks);
+ int find_earliest_i (Link_array<Midi_track_parser>& tracks);
+ Mudela_score* parse_score ();
+};
+
+#endif // MIDI_SCORE_PARSER_HH
--- /dev/null
+/*
+ midi-track-parser.hh -- declare
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#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<Mudela_note> open_note_l_list_;
+ Mudela_staff* mudela_staff_p_;
+ Midi_parser_info* track_info_p_;
+};
+
+#endif // MIDI_TRACK_PARSER_HH
--- /dev/null
+//
+// mudela-column.hh -- declare Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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> mudela_item_l_list_;
+ Moment at_mom_;
+ Mudela_score* mudela_score_l_;
+};
+
+#endif // MUDELA_COLUMN_HH
+
--- /dev/null
+//
+// mudela-item.hh -- declare mudela_item
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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
+
--- /dev/null
+//
+// mudela-score.hh -- declare Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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> mudela_staff_p_list_;
+ Link_array<Mudela_column> column_l_array_;
+
+ // ugh, ugh, ugh
+public:
+ int format_i_;
+ int tracks_i_;
+ int tempo_i_;
+};
+
+#endif // MUDELA_SCORE_HH
+
--- /dev/null
+//
+// mudela-staff.hh -- declare mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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<Mudela_item>& 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> mudela_voice_p_list_;
+ Cons_list<Mudela_item> mudela_item_p_list_;
+};
+
+#endif // MUDELA_STAFF_HH
+
--- /dev/null
+//
+// mudela-stream.hh -- part of LilyPond
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+// 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
+
--- /dev/null
+//
+// mudela-voice.hh -- declare Mudela_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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> mudela_item_l_list_;
+};
+
+#endif // MUDELA_VOICE_HH
+
--- /dev/null
+//
+// main.cc -- implement silly main () entry point
+// should have Root class.
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#include <locale.h>
+#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 <libintl.h>
+#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 <hanwen@cs.uu.nl>") + "\n";
+ LOGOUT(NORMAL_ver) << " " + _ ("Jan Nieuwenhuizen <janneke@gnu.org>") + "\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;
+}
--- /dev/null
+//
+// version.cc -- implement inexpensive versioning
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <stdio.h>
+#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;
+}
+
--- /dev/null
+/*
+ midi-parser.cc -- implement Midi_parser[_info]
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include <assert.h>
+#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));
+}
--- /dev/null
+/*
+ midi-score-parser.cc -- implement
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#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<Midi_track_parser>& 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<Midi_track_parser> 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;
+}
--- /dev/null
+/*
+ midi-track-parser.cc -- implement
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include <assert.h>
+#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<Mudela_note>** pp = &open_note_l_list_.head_; *pp;)
+ {
+ Cons<Mudela_note>* 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<Mudela_note>* 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<Mudela_note> (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_;
+}
--- /dev/null
+//
+// mudela-column.cc -- implement Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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> (mudela_item_l, 0));
+}
+
+Moment
+Mudela_column::at_mom()
+{
+ return at_mom_;
+}
--- /dev/null
+//
+// mudela-item.cc -- implement Mudela_item
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#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 <bf250@freenet.carleton.ca>
+
+ 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";
+}
--- /dev/null
+//
+// mudela-score.cc -- implement Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#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> (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<Mudela_staff>* 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<Mudela_staff>* 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<Mudela_staff>* 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;
+ }
+}
+
--- /dev/null
+//
+// mudela-staff.cc -- implement Mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#include <ctype.h>
+#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> (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<Mudela_item>& items)
+{
+ Mudela_voice* voice_p = new Mudela_voice (this);
+ mudela_voice_p_list_.append (new Killing_cons<Mudela_voice> (voice_p, 0));
+
+ // Moment mom = items.top ()->at_mom ();
+ Moment mom = 0;
+
+ for (Cons<Mudela_item>** pp = &items.head_; *pp;)
+ {
+ Cons<Mudela_item>* 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<Mudela_item>* 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<Mudela_voice>* 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<Mudela_item> items;
+ for (Cons<Mudela_item>* i = mudela_item_p_list_.head_; i; i = i->next_)
+ items.append (new Cons<Mudela_item> (i->car_, 0));
+
+ while (items.size_i ())
+ eat_voice (items);
+}
--- /dev/null
+//
+// mudela-stream.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997--1998, 1998 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#include <time.h>
+#include <fstream.h>
+#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);
+}
--- /dev/null
+//
+// mudela-voice.cc -- implement Mudela_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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> (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<Mudela_item>* 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<Mudela_key*> (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';
+}
+