![]() |
Problem mit SysEx (MIDI)
Hallo Community!
Hab schon lange nix mehr mit Delphi gemacht, jetzt bin ich aber wieder hier gelandet und zwar mit folgendem problem: Ich möchte mit der midi-bibliothek von ![]()
Code:
einen Fehler vom Typus "MMSYSERR_INVALPARAM". Gemäß
if not MIDIOutput.IsOpen(MidiOutputDevices.ItemIndex) then
begin showmessage('Device not opened!'); exit; end; str := 'f0 00 00 7e 32 00 00 01 f7'; MidiOutput.SendSysEx(MidiOutputDevices.ItemIndex, str ); ![]() Die aufgerufene Funktion tut folgendes:
Code:
Ich weiß nicht genau, was ich da falsch mache, vielleicht könnt ihr mir helfen. Ich arbeite mit Lazarus, aber ich glaube, das sollte hier nicht ausschlaggebend sein.
procedure TMidiOutput.SendSysEx(const aDeviceIndex: integer;
const aStream: TMemoryStream); var lSysExHeader: TMidiHdr; begin aStream.Position := 0; lSysExHeader.dwBufferLength := aStream.Size; lSysExheader.lpData := aStream.Memory; lSysExHeader.dwFlags := 0; MidiResult := midiOutPrepareHeader(GetHandle(aDeviceIndex), @lSysExHeader, SizeOf(TMidiHdr)); MidiResult := midiOutLongMsg( GetHandle(aDeviceIndex), @lSysExHeader, SizeOf(TMidiHdr)); MidiResult := midiOutUnprepareHeader(GetHandle(aDeviceIndex), @lSysExHeader, SizeOf(TMidiHdr)); end; Danke, Bääääär [Edit:] Noch etwas zur Klärung: Im Beispiel übergebe ich einen String an eine Funktion, die einen Stream erwartet. Es exisieren jedoch zwei Versionen dieser Funktion, wovon eine den übergebenen String umwandelt und dann die abgebildete Variante aufruft. Das hat also seine Richtigkeit |
AW: Problem mit SysEx (MIDI)
Fehlt da nicht noch ein
Delphi-Quellcode:
?
lSysExHeader.dwBytesRecorded := lSysExHeader.dwBufferLength;
|
AW: Problem mit SysEx (MIDI)
Das habe ich bereits probiert, scheint aber nichts zu ändern...
Mir ist eben aufgefallen: MIDI-Empfang geht auch nicht. (Ausnahmefehler, sobald das Programm was empfängt). Klingt für mich ein wenig so, als sei der MIDI-Header bei Lazarus irgendwo falsch definiert. |
AW: Problem mit SysEx (MIDI)
Dieses 3-malige
Delphi-Quellcode:
ist natürlich auch etwas fahrlässig.
GetHandle(aDeviceIndex)
Das Handle muss eigentlich direkt als Membervariable in der Klasse gespeichert sein. Und natürlich muss schon beim Öffnen sichergestellt werden, dass das Handle gültig ist. Das ist jetzt nicht unbedingt die Fehlerursache, aber doch ein bisschen unsauber. |
AW: Problem mit SysEx (MIDI)
Ich muss gestehen, ich verstehe diesen Code eh nicht so recht. Er schien aber so mal funktioniert zu haben, sonst wöre er ja nicht als funktionierend veröffentlich wordern. Vielleicht hat er unter älteren Windows Versionen funktioniert (und in seiner Funktion sozusagen eine "gedultete Ungültigkeit" gehabt, die von Widnows 7 jetzt nicht mehr akzeptiert wird)
aDeviceIndex ist ja ein Integer. Was genau jetzt der Sinn ist, das Handle eines Integers zu übergeben - ... Ich glaube, genauso wurde es auch beim Öffnen des Midi-Gerätes gemacht... Ich werde mir das nochmal anschauen, sobald ich wieder Zugriff auf den Code habe. Bääääär |
AW: Problem mit SysEx (MIDI)
Kleines Update dazu:
GetHandle ist wie folgt definiert:
Delphi-Quellcode:
Wobei TMidiOutput/TMidiInput und TMidiDevices so definiert ist:
function TMidiDevices.GetHandle(const aDeviceIndex: integer): THandle;
begin try if not InRange(aDeviceIndex, 0, fDevices.Count - 1) then raise EMidiDevices.CreateFmt('%s: Device index out of bounds! (%d)', [ClassName,aDeviceIndex]); Result:= THandle(fDevices.Objects[ aDeviceIndex ]); except Result:= 0; end; end;
Delphi-Quellcode:
GetHandle ist also Teil der Klasse, das war mir so noch nicht klar. Ich habe das für eine Delphi-eigene Funktion gehalten... Damit ergibt die Sache mit dem GetHandle ja erstmal wieder Sinn.
// base class for MIDI devices
TMidiDevices = class private fDevices: TStringList; fMidiResult: MMResult; procedure SetMidiResult(const Value: MMResult); protected property MidiResult: MMResult read fMidiResult write SetMidiResult; function GetHandle(const aDeviceIndex: integer): THandle; public // create the MIDI devices constructor Create; virtual; // whack the devices destructor Destroy; override; // open a specific device procedure Open(const aDeviceIndex: integer); virtual; abstract; // close a specific device procedure Close(const aDeviceIndex: integer); virtual; abstract; // close all devices procedure CloseAll; // THE devices function IsOpen(ADeviceIndex: Integer): Boolean; // check if open property Devices: TStringList read fDevices; end; // MIDI input devices TMidiInput = class(TMidiDevices) private fOnMidiData: TOnMidiInData; fOnSysExData: TOnSysExData; fSysExData: TObjectList; protected procedure DoSysExData(const aDeviceIndex: integer); public // create an input device constructor Create; override; // what the input devices destructor Destroy; override; // open a specific input device procedure Open(const aDeviceIndex: integer); override; // close a specific device procedure Close(const aDeviceIndex: integer); override; // Rescan device list procedure Rescan; // midi data event property OnMidiData: TOnMidiInData read fOnMidiData write fOnMidiData; // midi system exclusive is received property OnSysExData: TOnSysExData read fOnSysExData write fOnSysExData; end; // MIDI output devices TMidiOutput = class(TMidiDevices) constructor Create; override; // open a specific input device procedure Open(const aDeviceIndex: integer); override; // close a specific device procedure Close(const aDeviceIndex: integer); override; // send some midi data to the indexed device procedure Send(const aDeviceINdex: integer; const aStatus, aData1, aData2: byte); procedure SendSystemReset( const aDeviceIndex: integer); procedure SendAllSoundOff(const aDeviceIndex: integer; const channel: byte); // Rescan device list procedure Rescan; // send system exclusive data to a device procedure SendSysEx(const aDeviceIndex: integer; const aStream: TMemoryStream); overload; procedure SendSysEx(const aDeviceIndex: integer; const aString: string); overload; end; Bääääär |
AW: Problem mit SysEx (MIDI)
A bisserl spät, der Thread ist alt .. aber dennoch :
Delphi-Quellcode:
if not MIDIOutput.IsOpen(MidiOutputDevices.ItemIndex) then
begin showmessage('Device not opened!'); exit; end; str := 'f0 00 00 7e 32 00 00 01 f7'; MidiOutput.SendSysEx(MidiOutputDevices.ItemIndex, str ); Was machen denn die Leerzeichen da zwischen den HEX-Werten ? Kann die aufgerufene Funktion damit umgehen ? Oder interpretiert sie die Leerzeichen als HEX-Zahlen (was ja zu keinem sinnvollen Ergebnis führen würde ..) |
AW: Problem mit SysEx (MIDI)
Guckst Du hier:
![]() In der procedure StrToSysExStream werden die Leerzeichen entfernt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz