]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/midi-item.cc
release: 1.1.43
[lilypond.git] / lily / midi-item.cc
index 24f297942d2ccc5b61a8f29e271a2a0912a8995d..b358e1843359de320537accbd7e5a50d1a3723b8 100644 (file)
@@ -3,12 +3,10 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+  (c)  1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
  */
 
 #include "proto.hh"
-#include "plist.hh"
-#include "pcursor.hh"
 #include "debug.hh"
 #include "misc.hh"
 #include "string.hh"
 #include "midi-stream.hh"
 #include "audio-item.hh"
 
-IMPLEMENT_IS_TYPE_B (Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_chunk, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_duration, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_header, Midi_chunk);
-IMPLEMENT_IS_TYPE_B1 (Midi_instrument, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_key,Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_meter, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_note, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_note_off, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_tempo, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_text, Midi_item);
-IMPLEMENT_IS_TYPE_B1 (Midi_track, Midi_chunk);
+#include "killing-cons.tcc"
 
 Midi_chunk::Midi_chunk ()
   : Midi_item (0)
@@ -55,11 +42,17 @@ String
 Midi_chunk::str () const
 {
   String str = header_str_;
+  String dat = data_str ();
+#if 1 
+  String length_str = String_convert::i2hex_str (dat.length_i () 
+#else
+  // huh, huh??
   String length_str = String_convert::i2hex_str (data_str_.length_i () 
+#endif
     + footer_str_.length_i (), 8, '0');
   length_str = String_convert::hex2bin_str (length_str);
   str += length_str;
-  str += data_str ();
+  str += dat;
   str += footer_str_;
   return str;
 }
@@ -73,7 +66,7 @@ Midi_duration::Midi_duration (Real seconds_f)
 String
 Midi_duration::str () const
 {
-  return String ("<duration: ") + String (seconds_f_) + ">";
+  return String ("<duration: ") + to_str (seconds_f_) + ">";
 }
 
 Midi_event::Midi_event (Moment delta_mom, Midi_item* mitem_p)
@@ -116,13 +109,14 @@ Midi_header::Midi_header (int format_i, int tracks_i, int clocks_per_4_i)
   set ("MThd", str, "");
 }
 
+/* why doesn't this start at 0 ?
+ */
 char const* const instrument_name_sz_a_[ ] = {
-
   /* default is usually piano */
-  /* 0 */ "piano",
+  /* 0 "piano", */
 
-         /* (1-8 piano) */
-         /* 1 */ "acoustic grand",
+  /* (1-8 piano) */
+  /* 1 */ "acoustic grand",
          /* 2 */ "bright acoustic",
          /* 3 */ "electric grand",
          /* 4 */ "honky-tonk",
@@ -147,9 +141,9 @@ char const* const instrument_name_sz_a_[ ] = {
          /* 19 */ "rock organ",
          /* 20 */ "church organ",
          /* 21 */ "reed organ",
-         /* 22 */ "accoridan",
+         /* 22 */ "accordion",
          /* 23 */ "harmonica",
-         /* 24 */ "tango accordian",
+         /* 24 */ "concertina",
 
          /* (25-32 guitar) */
          /* 25 */ "acoustic guitar (nylon)",
@@ -158,7 +152,7 @@ char const* const instrument_name_sz_a_[ ] = {
          /* 28 */ "electric guitar (clean)",
          /* 29 */ "electric guitar (muted)",
          /* 30 */ "overdriven guitar",
-         /* 31 */ "distortion guitar",
+         /* 31 */ "distorted guitar",
          /* 32 */ "guitar harmonics",
 
          /* (33-40 bass) */
@@ -299,15 +293,21 @@ String
 Midi_instrument::str () const
 {
   Byte program_byte = 0;
-  for (int i = 0; instrument_name_sz_a_[i]; i++)
+  bool found = false;
+  for (int i = 0; !found && instrument_name_sz_a_[i]; i++)
     if (instrument_str_ == String (instrument_name_sz_a_[ i ])) 
       {
        program_byte = (Byte)i;
-       break;
+       found = true;
       }
 
-  String str = String ( (char) (0xc0 + channel_i_));
-  str += String ( (char)program_byte);
+  if (!found)
+    {
+      warning (_f("No such instrument: `%s'", instrument_str_.ch_C ()));
+    }
+  
+  String str = to_str ((char) (0xc0 + channel_i_));
+  str += to_str ((char)program_byte);
   return str;
 }
 
@@ -331,7 +331,7 @@ Midi_item::i2varint_str (int i)
   String str;
   while (1) 
     {
-      str += (char)buffer_i;
+      str += to_str ((char)buffer_i);
       if (buffer_i & 0x80)
        buffer_i >>= 8;
       else
@@ -348,13 +348,17 @@ Midi_key::Midi_key (Audio_item* audio_item_l)
 String
 Midi_key::str () const
 {
-  Key_change_req* k = audio_item_l_->req_l_->command ()->keychange ();
+  Key_change_req* k = dynamic_cast <Key_change_req *> (audio_item_l_->req_l_);
   int sharps_i = k->sharps_i ();
   int flats_i = k->flats_i ();
 
   // midi cannot handle non-conventional keys
   if (flats_i && sharps_i)
-    return "";
+    {
+      String str = _f ("unconventional key: flats: %d, sharps: %d", flats_i, 
+        sharps_i);
+      flats_i = sharps_i = 0;
+    }
   int accidentals_i = sharps_i - flats_i;
 
   String str = "ff5902";
@@ -364,16 +368,16 @@ Midi_key::str () const
   return String_convert::hex2bin_str (str);
 }
 
-Midi_meter::Midi_meter (Audio_item* audio_item_l)
+Midi_time_signature::Midi_time_signature (Audio_item* audio_item_l)
   : Midi_item (audio_item_l)
 {
   clocks_per_1_i_ = 18;
 }
 
 String
-Midi_meter::str () const
+Midi_time_signature::str () const
 {
-  Meter_change_req* m = audio_item_l_->req_l_->command ()->meterchange ();
+  Time_signature_change_req* m = dynamic_cast <Time_signature_change_req *> (audio_item_l_->req_l_);
   int num_i = m->beats_i_;
   int den_i = m->one_beat_i_;
 
@@ -389,34 +393,43 @@ Midi_note::Midi_note (Audio_item* audio_item_l)
   : Midi_item (audio_item_l)
 {
   dynamic_byte_ = 0x7f;
+  assert (dynamic_cast<Audio_note*> (audio_item_l));
 }
 
 Moment
-Midi_note::duration () const
+Midi_note::length_mom () const
 {
-  return audio_item_l_->req_l_->musical ()->rhythmic ()->duration ();
+  Moment m = dynamic_cast <Rhythmic_req *> (audio_item_l_->req_l_)->length_mom ();
+  if (m < Moment (1, 1000))
+    {
+      warning (_ ("silly duration"));
+      m = 1;
+     }
+  return m;
 }
 
 int
 Midi_note::pitch_i () const
 {
-  return audio_item_l_->req_l_->musical ()->melodic ()->pitch ();
+  int p = dynamic_cast <Melodic_req*> (audio_item_l_->req_l_)->pitch_.semitone_pitch () 
+    + dynamic_cast<Audio_note*>(audio_item_l_)->transposing_i_;
+  if (p == INT_MAX)
+    {
+      warning (_ ("silly pitch"));
+      p = 0;
+     }
+  return p;
 }
 
 String
 Midi_note::str () const
 {
-  if (pitch_i () == INT_MAX)
-    return String ("");
-
   Byte status_byte = (char) (0x90 + channel_i_);
 
-  String str = String ( (char)status_byte);
-  str += (char) (pitch_i () + c0_pitch_i_c_);
-
-  // poor man's staff dynamics:
-  str += (char) (dynamic_byte_ - 0x10 * channel_i_);
+  String str = to_str ((char)status_byte);
+  str += to_str ((char) (pitch_i () + c0_pitch_i_c_));
 
+  str += to_str ((char)dynamic_byte_);
   return str;
 }
 
@@ -431,27 +444,25 @@ Midi_note_off::Midi_note_off (Midi_note* midi_note_l)
 int
 Midi_note_off::pitch_i () const
 {
-  return audio_item_l_->req_l_->musical ()->melodic ()->pitch ();
+  return dynamic_cast <Melodic_req *> (audio_item_l_->req_l_)->pitch_.semitone_pitch ()
+    + dynamic_cast<Audio_note*>(audio_item_l_)->transposing_i_;
 }
 
 String
 Midi_note_off::str () const
 {
-  if (pitch_i () == INT_MAX)
-    return String ("");
-
   Byte status_byte = (char) (0x80 + channel_i_);
 
-  String str = String ( (char)status_byte);
-  str += (char) (pitch_i () + Midi_note::c0_pitch_i_c_);
-  str += (char)aftertouch_byte_;
+  String str = to_str ((char)status_byte);
+  str += to_str ((char) (pitch_i () + Midi_note::c0_pitch_i_c_));
+  str += to_str ((char)aftertouch_byte_);
   return str;
 }
 
 Midi_tempo::Midi_tempo (Audio_item* audio_item_l)
   : Midi_item (audio_item_l)
 {
-  per_minute_4_i_ = ( (Audio_tempo*)audio_item_l_)->per_minute_4_i_;
+  per_minute_4_i_ = dynamic_cast<Audio_tempo*>(audio_item_l_)->per_minute_4_i_;
 }
 
 Midi_tempo::Midi_tempo (int per_minute_4_i)
@@ -472,8 +483,8 @@ Midi_tempo::str () const
 Midi_text::Midi_text (Audio_item* audio_item_l)
   : Midi_item (audio_item_l)
 {
-  text_str_ = ( (Audio_text*)audio_item_l_)->text_str_;
-  type_ = (Type) ( (Audio_text*)audio_item_l_)->type_;
+  text_str_ = dynamic_cast<Audio_text*>(audio_item_l_)->text_str_;
+  type_ = (Type) dynamic_cast<Audio_text*>(audio_item_l_)->type_;
 }
 
 Midi_text::Midi_text (Midi_text::Type type, String text_str)
@@ -535,8 +546,10 @@ Midi_track::Midi_track ()
 void 
 Midi_track::add (Moment delta_time_mom, Midi_item* mitem_p)
 {
-  assert (delta_time_mom >= 0);
-  event_p_list_.bottom ().add (new Midi_event (delta_time_mom, mitem_p));
+  assert (delta_time_mom >= Moment (0));
+
+  Midi_event * e = new Midi_event (delta_time_mom, mitem_p);
+  event_p_list_.append (new Killing_cons<Midi_event> (e, 0));
 }
 
 String
@@ -545,9 +558,9 @@ Midi_track::data_str () const
   String str = Midi_chunk::data_str ();
   if (check_debug && !monitor->silent_b ("Midistrings"))
     str += "\n";
-  for (PCursor<Midi_event*> i (event_p_list_); i.ok (); i++
+  for (Cons<Midi_event> *i=event_p_list_.head_; i; i = i->next_
     {
-      str += i->str ();
+      str += i->car_->str ();
       if (check_debug && !monitor->silent_b ("Midistrings"))
         str += "\n";
     }