AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit SysEx (MIDI)

Ein Thema von Bääääär · begonnen am 21. Mär 2011 · letzter Beitrag vom 10. Apr 2015
Antwort Antwort
Bääääär

Registriert seit: 12. Apr 2007
Ort: Thüringen
28 Beiträge
 
Delphi 2005 Personal
 
#1

Problem mit SysEx (MIDI)

  Alt 21. Mär 2011, 18:32
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 hier SysEx Daten verschicken. Allerdings erhalte ich bei folgendem Aufruf
Code:
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 );
einen Fehler vom Typus "MMSYSERR_INVALPARAM". Gemäß dieser Seite bedeutet das, dass der vorzubereitende MIDIheader bzw. dessen Adresse nicht korrekt ist.
Die aufgerufene Funktion tut folgendes:
Code:
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;
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.

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

Geändert von Bääääär (21. Mär 2011 um 21:50 Uhr) Grund: siehe Text
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

AW: Problem mit SysEx (MIDI)

  Alt 21. Mär 2011, 18:39
Fehlt da nicht noch ein lSysExHeader.dwBytesRecorded := lSysExHeader.dwBufferLength; ?
Andreas
  Mit Zitat antworten Zitat
Bääääär

Registriert seit: 12. Apr 2007
Ort: Thüringen
28 Beiträge
 
Delphi 2005 Personal
 
#3

AW: Problem mit SysEx (MIDI)

  Alt 21. Mär 2011, 20:21
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.

Geändert von Bääääär (21. Mär 2011 um 20:43 Uhr)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

AW: Problem mit SysEx (MIDI)

  Alt 22. Mär 2011, 18:02
Dieses 3-malige GetHandle(aDeviceIndex) ist natürlich auch etwas fahrlässig.
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.
Andreas
  Mit Zitat antworten Zitat
Bääääär

Registriert seit: 12. Apr 2007
Ort: Thüringen
28 Beiträge
 
Delphi 2005 Personal
 
#5

AW: Problem mit SysEx (MIDI)

  Alt 23. Mär 2011, 08:18
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

Geändert von Bääääär (23. Mär 2011 um 08:36 Uhr)
  Mit Zitat antworten Zitat
Bääääär

Registriert seit: 12. Apr 2007
Ort: Thüringen
28 Beiträge
 
Delphi 2005 Personal
 
#6

AW: Problem mit SysEx (MIDI)

  Alt 23. Mär 2011, 08:57
Kleines Update dazu:
GetHandle ist wie folgt definiert:

Delphi-Quellcode:
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;
Wobei TMidiOutput/TMidiInput und TMidiDevices so definiert ist:
Delphi-Quellcode:
// 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;
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.

Bääääär
  Mit Zitat antworten Zitat
NickNameX

Registriert seit: 10. Apr 2015
1 Beiträge
 
#7

AW: Problem mit SysEx (MIDI)

  Alt 10. Apr 2015, 10:06
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 ..)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#8

AW: Problem mit SysEx (MIDI)

  Alt 10. Apr 2015, 10:58
Guckst Du hier:
http://www.midimountain.com/delphi_midi.html

In der procedure StrToSysExStream werden die Leerzeichen entfernt.

Geändert von hathor (10. Apr 2015 um 11:05 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz