MIDI to TXT list

Hello everyone,
could someone explain me, how exactly MIDI works or if you know how to convert midi file to text? My goal is to make a list of notes with time stamps, other things like velocity are optimal, but not necessary.

here MIDI - Wikipedia

in German page some details are shown: Musical Instrument Digital Interface – Wikipedia

Also look here http://code.compartmental.net/tools/minim/

When you install it:
in menu File is a point Examples, there:

  • Contributed libraries | Minim | Advanced | Midi…

here are some songs Songs - hpmusic

here is example with print of text as byte but it doesn’t work. Obviously, the text file / midi starts with meta data like title

You need to install minim; code’s derived from one of the examples

Chrisir




/**
 This example demonstrates how you might use JavaSound's midi file playing
 abilities to drive UGens in Minim for synthesis, rather than using the 
 midi sounds built into JavaSound. You might want to take this 
 approach if you want to tightly couple visuals and music, like this example does,
 but don't want to hand-code your sequence using AudioOutput's playNote method,
 or if you want to synthesize a midi file you've already created with custom
 synthesis chains and effects.
 <p>
 This is a simple example, as far as it goes, and ignores NoteOff midi messages. To handle NoteOff 
 messages, you would need to conceive of some kind of system for pairing NoteOn messages with 
 NoteOff messages so that your Instrument instances (or whatever classes you write to respond
 to midi messages) behave properly.
 <p>
 For more info about what can be done with the JavaSound Sequencer and Sequence classes, see:
 <a href="http://docs.oracle.com/javase/6/docs/api/javax/sound/midi/Sequence.html">javax.sound.midi.Sequence</a> and 
 <a href="http://docs.oracle.com/javase/6/docs/api/javax/sound/midi/Sequencer.html">javax.sound.midi.Sequencer</a>
 <p>
 For more information about Minim and additional features, visit http://code.compartmental.net/minim/
 <p>
 Author: Damien Di Fede  
 */

import ddf.minim.*;
import ddf.minim.ugens.*;

// this package is where we get our midi objects from
import javax.sound.midi.*;

// two things we need from Minim synthesis
Minim       minim;
AudioOutput out;

// what we need from JavaSound for sequence playback
Sequencer     sequencer;
// holds the actual midi data
Sequence      sequence;

// the Blip class is what handles our visuals.
// see below the draw function for the definition.
ArrayList<Blip> blips;

// in order to be send midi messages from the Sequencer
// we must implement the JavaSound interface Receiver.
// we then set an instance of this class as the Receiver
// for on of the Sequencer's Trasmitters.
// See: http://docs.oracle.com/javase/6/docs/api/javax/sound/midi/Receiver.html
class MidiReceiver implements Receiver
{
  void close() {
  }

  void send( MidiMessage msg, long timeStamp )
  { 
    // we only care about NoteOn midi messages.
    // here's how you check for that
    if ( msg instanceof ShortMessage )
    {
      ShortMessage sm = (ShortMessage)msg;
      // if you want to handle messages other than NOTE_ON, you can refer to the constants defined in 
      // ShortMessage: http://docs.oracle.com/javase/6/docs/api/javax/sound/midi/ShortMessage.html
      // And figure out what Data1 and Data2 will be, refer to the midi spec: http://www.midi.org/techspecs/midimessages.php
      print(sm.getCommand()+"."); 
      if ( sm.getCommand() == ShortMessage.NOTE_ON )
      {
        // note number, between 1 and 127
        int note = sm.getData1();
        // velocity, between 1 and 127
        int vel  = sm.getData2();
        // we could also use sm.getChannel() to do something different depending on the channel of the message

        // see below the draw method for the definition of this sound generating Instrument
        out.playNote( 0, 0.1f, new Synth( note, vel ) );
      }
    }
  }
}

void setup()
{

  size( 640, 480 );

  byte[] c1=
    loadBytes("bassline.MID" );
  println (c1.length);
  println(c1[0]); 
  println ("-----------------------------------------------------------");
  println ("-----------------------------------------------------------");
  for (byte b : c1) { 
    print(b); 
    print(" ");
  }
  println ("================================================================================\n\n");


  minim = new Minim(this);
  out   = minim.getLineOut();

  // try to get the default sequencer from JavaSound
  // if it fails, we print a message to the console
  // and don't do any of the sequencing.
  try
  {
    // get a disconnected sequencer. this should prevent
    // us from hearing the general midi sounds the 
    // sequecer is automatically hooked up to.
    sequencer = MidiSystem.getSequencer( false );

    // have to open it
    sequencer.open();

    // load our sequence
    sequence  = MidiSystem.getSequence( createInput( "bassline.MID" ) );

    // put it in the sequencer
    sequencer.setSequence( sequence );

    // set the tempo
    sequencer.setTempoInBPM( 128 );

    // hook up an instance of our Receiver to the Sequencer's Transmitter
    sequencer.getTransmitter().setReceiver( new MidiReceiver() );

    // just keep looping
    sequencer.setLoopCount( 0 ) ;// Sequencer.LOOP_CONTINUOUSLY );

    // and away we go
    sequencer.start();
  }

  catch( MidiUnavailableException ex ) // getSequencer can throw this
  {
    // oops there wasn't one.
    println( "No default sequencer, sorry bud." );
  }
  catch( InvalidMidiDataException ex ) // getSequence can throw this
  {
    // oops, the file was bad
    println( "The midi file was hosed or not a midi file, sorry bud." );
  }
  catch( IOException ex ) // getSequence can throw this
  {
    println( "Had a problem accessing the midi file, sorry bud." );
  }

  // and we need to make our Blip list
  blips = new ArrayList<Blip>();
  // and set our drawing preferences
  rectMode( CENTER );
}

void draw()
{
  background( 20 );

  // just draw all the Blips!
  for ( int i = 0; i < blips.size(); ++i )
  {
    // blips.get(i).draw();
  }
}

// the Instrument implementation we use for playing notes
// we have to explicitly specify the Instrument interface
// from Minim because there is also an Instrument interface
// in javax.sound.midi. We could avoid this by importing
// only the classes we need from javax.sound.midi, 
// rather than importing everything.
class Synth implements ddf.minim.ugens.Instrument
{
  Oscil       wave;
  Damp        env;
  int         noteNumber;
  Blip        blip;

  Synth( int note, int velocity )
  {
    noteNumber = note;
    float freq = Frequency.ofMidiNote( noteNumber ).asHz();
    float amp  = (float)(velocity-1) / 126.0f;

    wave = new Oscil( freq, amp, Waves.QUARTERPULSE );
    // Damp arguments are: attack time, damp time, and max amplitude
    env  = new Damp( 0.001f, 0.1f, 1.0f );

    wave.patch( env );
  }

  void noteOn( float dur )
  {
    // make visual
    color c = color( 0, 200, 64, 255*(wave.amplitude.getLastValue()) );
    blip = new Blip( c, map(noteNumber, 30, 55, height, 0), 200 );
    blips.add( blip );

    // make sound
    env.activate();
    env.patch( out );
  }

  void noteOff()
  {
    env.unpatchAfterDamp( out );
    blips.remove( blip );
  }
}

// this class stores data for drawing one Blip on the screen.
// in this example, each Blip directly corresponds to a note
// played in the musical sequence. the pitch of the note
// is represented by the vertical position of the Blip on the screen,
// the velocity is represented by the opacity of the Blip,
// and the duration is represented by the width.
// The color is used to differentiate between the two
// midi instruments being used in the example.
class Blip
{
  // color
  color shade;
  // vertical position on screen
  float position;
  // width
  float size;

  Blip( color c, float p, float s )
  {
    shade = c;
    position = p;
    size = s;
  }

  void draw()
  {
    fill( shade );
    rect( width/2, position, size, 10 );
  }
}


645
77


77 84 104 100 0 0 0 6 0 1 0 2 3 -64 77 84 114 107 0 0 0 31 0 -1 3 8 98 97 115 115 108 105 110 101 0 -1 88 4 4 2 24 8 0 -1 81 3 7 -95 32 0 -1 47 0 77 84 114 107 0 0 2 72 0 -112 36 127 0 -1 3 0 -127 112 -128 36 0 0 -112 36 96 -127 112 -128 36 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 44 127 -127 112 -128 44 0 0 -112 44 96 -127 112 -128 44 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 41 127 -127 112 -128 41 0 0 -112 41 96 -127 112 -128 41 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 36 127 -127 112 -128 36 0 0 -112 36 96 -127 112 -128 36 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 51 127 -127 112 -128 51 0 0 -112 51 96 -127 112 -128 51 0 0 -112 50 127 -127 112 -128 50 0 0 -112 50 96 -127 112 -128 50 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 50 127 -127 112 -128 50 0 0 -112 50 96 -127 112 -128 50 0 0 -112 36 127 -127 112 -128 36 0 0 -112 36 96 -127 112 -128 36 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 41 127 -127 112 -128 41 0 0 -112 41 96 -127 112 -128 41 0 0 -112 39 127 -127 112 -128 39 0 0 -112 39 96 -127 112 -128 39 0 0 -112 41 127 -127 112 -128 41 0 0 -112 41 96 -127 112 -128 41 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -112 43 127 -127 112 -128 43 0 0 -112 43 96 -127 112 -128 43 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -112 44 127 -127 112 -128 44 0 0 -112 44 96 -127 112 -128 44 0 0 -112 48 127 -127 112 -128 48 0 0 -112 48 96 -127 112 -128 48 0 0 -112 46 127 -127 112 -128 46 0 0 -112 46 96 -127 112 -128 46 0 0 -1 47 0 ================================================================================

144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.128.144.