Einzelnen Beitrag anzeigen

Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.096 Beiträge
 
FreePascal / Lazarus
 
#1

Midi-Komponenten, Teil 2: TMidiInput

  Alt 3. Mai 2008, 15:53
Hi,

dieses Tutorial beschäftigt sich nun mit der Komponente für den MIDI-Eingang. Die Komponente gibts in Teil 1 als Anhang. Falls ihr keinen MIDI-Eingang oder kein Gerät zum dort anschließen habt, empfehle ich euch zum Testen Bei Google suchenMIDI-Yoke, z. B. im Zusammenhang mit meinem Hier im Forum suchenMIDI-Klavier. Damit erhaltet ihr virtuelle Ein- und Ausgänge, wobei die Signale von den virtuellen Ausgängen an die Eingänge weitergegeben werden.

Ich arbeite hier mit dem Programm aus Teil 1 weiter, aber es ist so gestaltet, dass ihr das Tutorial, außer ganz am Ende (Eingabe -> Ausgabe), auch ohne Teil 1 durcharbeiten könnt. Der Code aus Teil 1 wurde durch ... ersetzt.

MIDI-Eingang

Diesmal fügen wir zu Uses die Unit "MidiIn" hinzu und erstellen ein Feld vom Typ TMidiInput.

Delphi-Quellcode:
uses
  ..., MidiIn;

type
  TForm1 = class(TForm)
    ...
  private
    { Private-Deklarationen }
    MidiIn: TMidiInput;
    ...
  end;
Für den MIDI-Eingang gibt es so einen Standard wie den MIDI-Mapper (siehe Teil 1) nicht, daher müssen wir hier die Geräte auflisten und den User wählen lassen. Somit sieht das FormCreate/Destroy so aus:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  ...

  MidiIn := TMidiInput.Create(nil);
  for I := 0 to MidiIn.Numdevs - 1 do
  begin
    MidiIn.DeviceID := I;
    InputComboBox.Items.Add(MidiIn.ProductName);
  end;

  InputComboBox.ItemIndex := 0;
  MidiIn.DeviceID := 0;
  MidiIn.Open;
  MidiIn.Start;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MidiIn.Stop;
  MidiIn.Close;

  ...
end;
Auf die ComboBox wird so reagiert:

Delphi-Quellcode:
procedure TForm1.InputComboBoxChange(Sender: TObject);
begin
  MidiIn.Stop;
  MidiIn.Close;
  MidiIn.DeviceID := DeviceComboBox.ItemIndex;
  MidiIn.Open;
  MidiIn.Start;
end;
Halt, da fehlt noch noch was! Was sollen wir tun, wenn eine MIDI-Message reinkommt? Wir brauchen eine procedure MidiMessageIn(Sender: TObject)!

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ...
  private
    { Private-Deklarationen }
    MidiIn: TMidiInput;
    ...
    procedure MidiMessageIn(Sender: TObject); // <-- Hier!
  public
    { Public-Deklarationen }
  end;

...

implementation

uses
  MidiType; // <-- Hier! (wegen TMyMidiEvent)

...

{ Hier die ganze proc }
procedure TForm1.MidiMessageIn(Sender: TObject);
var
  Event: TMyMidiEvent;
begin
  Event := MidiIn.GetMidiEvent;
  try
    with Event do
    begin
      Memo.Lines.Add('Message: ' + IntToHex(MidiMessage, 2) +
        #9'Data1: ' + IntToStr(Data1) +
        #9'Data2: ' + IntToStr(Data2));
    end;
    //MidiOut.PutMidiEvent(Event);
  finally
    Event.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  ...

  MidiIn := TMidiInput.Create(nil);
  MidiIn.OnMidiInput := MidiMessageIn; // <-- Hier, nicht vergessen!

  for I := 0 to MidiIn.Numdevs - 1 do
  begin
    MidiIn.DeviceID := I;
    InputComboBox.Items.Add(MidiIn.ProductName);
  end;

  InputComboBox.ItemIndex := 0;
  MidiIn.DeviceID := 0;
  MidiIn.Open;
  MidiIn.Start;
end;
Im Beispiel füge ich die Daten in ein Memo ein. Ihr könnt sie natürlich auch anders verarbeiten.

TMidiInput und TMidiOutput
Wenn die Eingaben direkt, ohne weiterverarbeitet zu werden, ausgegeben werden sollen, so kann das so gemacht werden:

MidiOut.PutMidiEvent(Event); Ansonsten für die MIDI-Ausgabe einfach Teil 1 ansehen.

Wenn ihr MIDI-Eingabe und -Ausgabe und so etwas wie MIDI-Yoke kombiniert, macht bitte nicht den Fehler, den selben MIDI-Yoke-Eingang und -Ausgang zu benutzen. Das wird lustig Nehmt zum Testen dann lieber ein Extraprogramm, stellt dort den MIDI-Yoke-Ausgang ein und lasst den Ausgang eures Programmes auf was anderem.

So, das war es mit Teil 2.

Mfg
FAlter
Felix Alter
  Mit Zitat antworten Zitat