Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Midi-Komponenten, Teil 2: TMidiInput (https://www.delphipraxis.net/113152-midi-komponenten-teil-2-tmidiinput.html)

FAlter 3. Mai 2008 15:53


Midi-Komponenten, Teil 2: TMidiInput
 
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:

Delphi-Quellcode:
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

BurtaN 10. Jun 2008 12:11

Re: Midi-Komponenten, Teil 2: TMidiInput
 
Hi,

weißt du wie man es hinbekommt, dass mehrere Programme auf einen Midi-Eingang zugreifen können? Wenn ich mein Programm benutze, kann ich mit keinem anderen Programm darauf zugreifen (z.B. Midi-Ox, Kore 2...). Wenn ich zuerst mit Midi-Ox auf einen Eingang zugreife, kann ihn nicht mehr mit meinem Programm benutzen, mit Kore 2 z.B. jedoch schon.

Danke,
BurtaN

H4ndy 27. Jan 2009 19:23

Re: Midi-Komponenten, Teil 2: TMidiInput
 
Schon bissle älter, aber zu MIDI gibt es ja kaum Alternativen.

Gibt es einen Trick bei den Sysex-Nachrichten? SysexLength scheint zwar korrekt zu sein, der Sysex-String ist aber immer nur "ð". Muss ich das gesondert irgendwo "abholen"?

//Edit:
OK, nach einem Blick in den Code hab ichs gefunden.
Sysex ist ein Pointer auf den Speicherbereich des Sysex-Puffers, den man dann mit SysexLength auslesen/kopieren kann.
Ist in der Klasse als PChar deklariert und Turbo Delphi macht da in den Vervollständigungsfunktionen PAnsiChar draus...

beanbear6 27. Dez 2011 11:43

AW: Midi-Komponenten, Teil 2: TMidiInput
 
Hallo,
hm... bin am grübeln. Gibt es die Möglichkeit,
über die MidiIn Funktion den Text des Midifiles
in z.B. einem Memo zu übergeben???
Danke für jeden Tip.
Gruß beanbear6


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf