home  |  suche  |  kontakt/johner  |  institut 
studierende  |  tech-docs  |  mindmailer 

Ein erster Versuch: StartMidi

package midi;

import java.io.IOException;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;

/**
 * Diese Klasse erstellt eigene Midi-Sequence uns spielt sie ab.
 */
public class MidiStart {

    private final static int PPQS = 16// Auflösung pro Viertelnote
    private final static int STAKKATO = 8//Abkürzung einer Stakkatonote in PPQS

    public static void main(String[] argsthrows InvalidMidiDataException, MidiUnavailableException, IOException{
      MidiStart start = new MidiStart();
      Sequence sequence = start.generateSequence();
      SequencePlayer.playSequence(sequence);
  }
    
    
    private Sequence generateSequence() throws InvalidMidiDataException {

        // MIDI-Daten-Organisation (Sequence, Track) erstellen
        Sequence seq = new Sequence(Sequence.PPQ, PPQS);
        Track track = seq.createTrack();
        long currentTick = 0// Aktuelle Zeitposition in PPQS

        //Kanal 0 auf "EnsembleStrings" umschalten
        ShortMessage msg = new ShortMessage();
        msg.setMessage(ShortMessage.PROGRAM_CHANGE, 8480);
        track.add(new MidiEvent(msg, currentTick));

        //Partiturdaten hinzufügen
        currentTick = generateTone(track, currentTick, 601641);
        currentTick = generateTone(track, currentTick, 601645);
        currentTick = generateTone(track, currentTick, 601647);
        currentTick = generateTone(track, currentTick, 601648);
        currentTick = generateTone(track, currentTick, 1616410);
        currentTick = generateTone(track, currentTick, 6016412);
        currentTick = generateTone(track, currentTick, 6221277);
        currentTick = generateTone(track, currentTick, 601323);
        return seq;
    }

  /**
   
   @param track: Instrument/Stimme
   @param currentTick aktuelle Position
   @param ton Tonhöhe (C entspricht 60, C# 61, D 62 usw.
   @param dauer: in Viertelnoten
   @param laut: Lautstärke (0-127)
   @param channel: Kanal (0-15) Spezialfall 10: Schlagzeug (Jede Tonhöhe = anderes Instrument)
   @return neue aktuelle Position
   @throws InvalidMidiDataException --
   */
    private long generateTone(Track track, long currentTick, int ton, int dauer, int laut, int channelthrows InvalidMidiDataException {
    ShortMessage msg = new ShortMessage();
    // Note-On-Message generieren
    msg.setMessage(ShortMessage.NOTE_ON, channel, ton, laut);//
    track.add(new MidiEvent(msg, currentTick));
    currentTick += PPQS * dauer - STAKKATO;

    // Note-Off-Message generieren
    msg = new ShortMessage();
    msg.setMessage(ShortMessage.NOTE_OFF, channel, ton, 0);
    track.add(new MidiEvent(msg, currentTick));
    currentTick += STAKKATO;
    return currentTick;
  }
}

SequencePlayer

package midi;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Track;
import javax.sound.midi.Transmitter;

/**
 * Diese Klasse spielt existierende Midi-Datei und gibt Werte aus.
 */
public class SequencePlayer {
  public static void playSequence(Sequence seq)
      throws InvalidMidiDataException, MidiUnavailableException {
    // Sequencer und Synthesizer initialisieren
    Sequencer sequencer = MidiSystem.getSequencer();
    Synthesizer synth = MidiSystem.getSynthesizer();
    Transmitter trans = sequencer.getTransmitter();
    Receiver rcvr = synth.getReceiver();

    // Beide öffnen und verbinden
    sequencer.open();
    synth.open();
    trans.setReceiver(rcvr);

    // Sequence abspielen
    sequencer.setSequence(seq);
    sequencer.setTempoInBPM(120);
    sequencer.start();

    // Warten, bis der Sequencer seine Arbeit beendet hat...
    while (true) {
      try {
        Thread.sleep(100);
      catch (Exception e) {
        // nothing
      }
      if (!sequencer.isRunning()) {
        break;
      }
    }

    // Sequencer anhalten und Geräte schließen
    sequencer.stop();
    sequencer.close();
    synth.close();
  }

  public static Sequence loadSequence(String fileNamethrows IOException,
      InvalidMidiDataException, MidiUnavailableException {
    Sequencer sequencer = MidiSystem.getSequencer();
    FileInputStream filestream = new FileInputStream(new File(fileName));
    BufferedInputStream stream = new BufferedInputStream(filestream);
    sequencer.setSequence(stream);
    return sequencer.getSequence();
  }

  /**
   * Gibt Midi-Daten der Sequenz aus
   
   @param seq
   */
  public static void dumpSequence(Sequence seq) {
    Track[] tracks = seq.getTracks();
    for (int i = 0; i < tracks.length; i++) {
      System.out.println("Dumping Track " + i);
      Track track = tracks[i];
      for (int j = 0; j < track.size(); j++) {
        MidiEvent event = track.get(j);
        MidiMessage message = event.getMessage();
        long time = event.getTick();
        byte[] part = message.getMessage();
        System.out.print("Message " + j + " with time " + time + ": ");
        for (int k = 0; k < part.length; k++) {
          System.out.print("<" + part[k">");
        }
        System.out.println();
      }
    }
  }
}

Beispieldatei

Dieses Midifile kann man den SequencePlayer ausgeben lassen: Clocks von Coldplay