Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Bass.dll kollidiert mit Midi Komponenten (https://www.delphipraxis.net/169534-bass-dll-kollidiert-mit-midi-komponenten.html)

tvgcjpgnvid 27. Jul 2012 10:58

Bass.dll kollidiert mit Midi Komponenten
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo DP,

ich habe / bin dabei ein Programm zu schreiben, was MIDIs öffnen kann, und diese letztlich durch einen Sampler (Bass.dll) abgespielt werden soll.
Das Programm hat 2 Features. Einmal direkt MIDI-IN (für Keyboard usw.) und einmal soll es halt MIDI-Files öffnen können (und auch dann abspielen)
Und genau beim Abspielen ist das Problem:

MIDI-IN (Komponente = siehe Anhang)

Code:
//Deklaration
MidiIn: TMidiInPut;

//Create (FormActivate)
MidiIn := TMidiInPut.Create(self);
MidiIn.OnMidiInput := MidiMessageIn;

//Code
procedure TForm1.MidiMessageIn(Sender: TObject);
var
  Event: TMyMidiEvent;
  temp:string;
  ex: boolean;
  vol: extended;
begin
  Event := MidiIn.GetMidiEvent;
    Inc(events);
  Label4.Caption := IntToStr(events);
  ex := False;
  case Event.MidiMessage of
    $80..$8F : begin
                 ex := true;
                 //Here be Dragons.. Or code..
               end;
    $90..$9F : begin
                 ex := mchans[Event.MidiMessage mod 16];
                  //
               end;
    else ex := false;
  end;
  if CheckBox2.Checked = True
     then begin
            if Event.Data1 < tbData1Min.Position then ex := True;
            if Event.Data1 > tbData1Max.Position then ex := True;
          end;
  if ex = True then exit;
  vol := Event.Data2 / 127;
  try
    case Event.Data1 of
          12 : BassPlayer.PlaySound(path+'C0.WAV',vol);
          13 : BassPlayer.PlaySound(path+'C#0.WAV',vol);
          14 : BassPlayer.PlaySound(path+'D0.WAV',vol);
               [...]
          117 : BassPlayer.PlaySound(path+'A8.WAV',vol);
    end;
  finally
    Event.Free;
  end;
end;
Der Code funktioniert wunderbar, wenn ich über mein Keyboard MIDI Befehle reingebe (bzw über Loopmidi eine MIDI Datei reingebe) spielt er wunderbar ab.
http://soundcloud.com/magic94/monkey-island-1

Nun zum MIDI-File:

Code:
//Deklaration
MidiFile: TMidiFile;

//Create (FormActivate)
MidiFile := TMidiFile.Create(self);
MidiFile.OnMidiEvent := MidiMessageInFile;

//Laden
procedure TForm1.Button8Click(Sender: TObject);
begin
  if OpenDialog1.Execute
     then begin
            MidiFile.Filename := OpenDialog1.Filename;
            MidiFile.Readfile;
          end;
end;

//Abspielen
procedure TForm1.Button9Click(Sender: TObject);
begin
  MidiFile.StartPlaying;
end;

//Code
procedure TForm1.MidiMessageInFile(event: PMidiEvent);
var
  temp:string;
  ex: boolean;
  vol: extended;
  note: integer;
begin
  Inc(events);
  Label4.Caption := IntToStr(events);
  ex := False;
  case event^.event of
    $80..$8F : begin
                 ex := true;
                 //Here be Dragons.. Or code..
               end;
    $90..$9F : begin
                 ex := mchans[event^.event mod 16];
                  //
               end;
    else ex := false;
  end;
  if CheckBox2.Checked = True
     then begin
            if Event^.Data1 < tbData1Min.Position then ex := True;
            if Event^.Data1 > tbData1Max.Position then ex := True;
          end;
  if ex = True then exit;
  vol := Event^.Data2 / 127;
  try
    note := Event^.data1;
    case note of
          12 : BassPlayer.PlaySound(path+'C0.WAV',vol);
          13 : BassPlayer.PlaySound(path+'C#0.WAV',vol);
          117 : BassPlayer.PlaySound(path+'A8.WAV',vol);
    end;
  finally
    FreeMem(event);
  end;
  ListBox1.Items.Add(IntToStr(shit));
  PlaySomething;
end;

procedure TForm1.PlaySomething; //Als Test
begin
  BassPlayer.PlaySound(path+'C3.WAV',100);
end;
Leider versagt hierbei jetzt der BassPlayer. Kommentiere ich den Bassplayer aus, füllt er die Listbox am Ende des Code einfach mit den Zahlwerten. Lasse ich sie stehen, findet er aufeinmal das Sample nicht mehr.

Also ein durchlauf könnte so aussehen:

PlaySomething aufrufen (DING -> Sound hörbar)
MIDI öffnen und abspielen (Fehlermeldungssound hörbar, aber keine Fehlermeldung sichtbar)
PlaySomething wieder aufrufen (RUMS -> Sample nicht gefunden)

Und zum schluss noch den Bassplayer (siehe Anhang)

Danke für eure Hilfe :) (Nutze Delphi 7 Personal)

EWeiss 27. Jul 2012 14:27

AW: Bass.dll kollidiert mit Midi Komponenten
 
Wenn du schon Bass verwendest dann wäre es besser du verwendest auch das AddOn für MIDI zeugs
Dann kommst auch nicht in bedrängnis was die Midi Komponente angeht.

gruss

tvgcjpgnvid 27. Jul 2012 16:08

AW: Bass.dll kollidiert mit Midi Komponenten
 
Leider ist diese Komponente für die Verwaltung von Soundfonts gedacht, bzw das abspielen von Soundfonts. Wir brauchen aber die Rohen MIDI Daten.

sx2008 27. Jul 2012 21:45

AW: Bass.dll kollidiert mit Midi Komponenten
 
Kuck mal dieses Stückchen Code an:
Delphi-Quellcode:
case Event.Data1 of
   12 : BassPlayer.PlaySound(path+'C0.WAV',vol);
   13 : BassPlayer.PlaySound(path+'C#0.WAV',vol);
   14 : BassPlayer.PlaySound(path+'D0.WAV',vol);
      [...]
   117 : BassPlayer.PlaySound(path+'A8.WAV',vol);
end;
Ständige Wiederholungen von immer gleichem Code; das ist schlecht!
Mach' Dir eine Unterfunktion, die für jeden Midinote den Namen der Wav-Datei liefert:
Delphi-Quellcode:
function MidiNote2Wav(note:integer):string;
begin
  case note of
   12 : Result := 'C0.WAV';
   13 : Result := 'C#0.WAV';
   14 : result := 'D0.WAV';
      [...]
   117 : result := 'A8.WAV';
  end;
end;
Und dann baust du noch eine Prüfung ein ob die Datei überhaupt existiert:
Delphi-Quellcode:
procedure TForm1.MidiMessageInFile(event: PMidiEvent);
var
  temp:string;
  ex: boolean;
  vol: extended;
  note: integer;
  filename : string;
begin
  Inc(events);
  Label4.Caption := IntToStr(events);
...
  try
    note := Event^.data1;
    filename := path + MidiNote2Wav(note); // NEU
    if not FileExists(filename) then
      ShowMessageFmt('%s nicht vorhanden', [filename]);

    BassPlayer.PlaySound(filename,vol);
  finally
    FreeMem(event);
  end;
  ListBox1.Items.Add(IntToStr(shit));
  PlaySomething;
end;

tvgcjpgnvid 27. Jul 2012 22:33

AW: Bass.dll kollidiert mit Midi Komponenten
 
Zitat:

Zitat von sx2008 (Beitrag 1176112)
Ständige Wiederholungen von immer gleichem Code; das ist schlecht!
Mach' Dir eine Unterfunktion, die für jeden Midinote den Namen der Wav-Datei liefert:
Delphi-Quellcode:
function MidiNote2Wav(note:integer):string;
begin
  case note of
   12 : Result := 'C0.WAV';
   13 : Result := 'C#0.WAV';
   14 : result := 'D0.WAV';
      [...]
   117 : result := 'A8.WAV';
  end;
end;
Und dann baust du noch eine Prüfung ein ob die Datei überhaupt existiert:

Eine Unterfunktion macht doch im Endeffekt nichts anderes, und dabei noch einen Function-Call ... klingt langsamer.
Zudem das mit dem "normalen" Datei nicht vorhanden ja irgendwie nicht sein kann. Denn ich habe ja oben gepostet:

Fester Pfad, nichts zu rütteln.
Playsomething -> spielt etwas ab.
MIDI öffnen, auf Play klicken -> Fehlermeldungssounds erscheinen -> Stop.
Playsomething -> aufeinmal findet es die Datei nicht mehr...

Bei dem was du umgeschrieben hast würde er mir nur nochmal sagen das die Datei spurlos verschwunden ist.

EWeiss 27. Jul 2012 23:19

AW: Bass.dll kollidiert mit Midi Komponenten
 
Ich frage dich noch einmal warum verwendest du denn Bibliotheken die nicht oder angeblich.. nicht funktionieren wie Bass.
Warum baut man sich so etwas ein nur um eine Wav-Datei abzuspielen das geht ganz einfach nur mit
einer funktion aus MMSystem unter verwendung von MCI.

Delphi-Quellcode:
PlaySound(path + 'C0.WAV', 0, SND_FILENAME Or SND_ASYNC);


Ok kein Volumen aber das läßt sich auch ganz schnell mit MCI implementieren.

Oder schau mal hier!
Nachbearbeitung meiner MCIPlayer Classe von Sir Rufo

Du mußt hier nur für die Guid für D7 zwei Dinge ändern..
Delphi-Quellcode:
constructor TMciPlayer.Create;
var
  NewGUID: TGUID;
 begin
   inherited Create;

   FState := mpsClosed;
   CreateGUID(NewGUID);
   FAlias := GUIDToString( NewGUID );
   FFileName := '';
   FDuration := 0;
 end;

Entweder oder (MIDI mit MCI) oder (BASS mit dem dazugehörigen MIDI AddON).
Was anderes fällt mir jetzt auch nicht ein.

bla.. bla .. bla ;)

gruss

sx2008 28. Jul 2012 00:04

AW: Bass.dll kollidiert mit Midi Komponenten
 
Zitat:

Zitat von tvgcjpgnvid (Beitrag 1176117)
Eine Unterfunktion macht doch im Endeffekt nichts anderes, und dabei noch einen Function-Call ... klingt langsamer.

Man verliert wenige Mikrosekunden aber man verbessert die Struktur der Software.
Eine der wichtigsten Grundprinzipien der Softwareentwicklung nennt sich "Don't Repeat Yourself"
Es muss dir doch auffallen, dass grosse Abschnitte deines Codes aus ständigen Wiederholungen von gleichen oder stark ähnlichen Teilen bestehen.
Zitat:

Zitat von tvgcjpgnvid (Beitrag 1176117)
Fester Pfad, nichts zu rütteln.

Das kann jeder behaupten.
Wer sagt denn, dass die Variable path innerhalb der
Delphi-Quellcode:
procedure TForm1.MidiMessageInFile
den korrekten Wert hat?
Vielleicht fehlt ja nur ein abschliesender Backslash oder der Pfad ist relativ.
Glauben heisst nicht wissen.
Du musst schon den Beweis erbringen, dass der Dateiname den du
Delphi-Quellcode:
BassPlayer.PlaySound()
übergibst auch wirklich existiert.
Es reicht auch nicht wenn du nur mit dem Debugger den Pfad anschaust.
Das menschliche Gehirn ist manchmal blind gegenüber Buchstabendrehern und ähnlichen Fehlern.
Das ist der berühmte Tomaten-auf-den-Augen-Effekt.
Daher: Beweise zuerst, dass die Datei existiert (mit der Funktion
Delphi-Quellcode:
FileExists()
) und erst dann kann man den BassPlayer verdächtigen nicht korrekt zu arbeiten.

EWeiss 28. Jul 2012 00:11

AW: Bass.dll kollidiert mit Midi Komponenten
 
Zitat:

Daher: Beweise zuerst, dass die Datei existiert (mit der Funktion FileExists() ) und erst dann kann man den BassPlayer verdächtigen nicht korrekt zu arbeiten.
Wird wohl schwer manche Leute verbeißen sich so in ihrem Standpunkt
da hilft auch ein Statement wie das von dir nicht viel.

Was er nicht will das will er nicht! :)

gruss

tvgcjpgnvid 28. Jul 2012 00:24

AW: Bass.dll kollidiert mit Midi Komponenten
 
Nee ok überzeugt ;-)
Ich probiers jetzt, ergebnis folgt:´

Ok zugegeben, die Idee war nicht schlecht.
Die "path" Variable wars nicht schuld. aber da die Path Variable Relativ ist, und der OpenDialog den Aktuellen Pfad verändert gabs da Probleme.
Gefixt, Danke :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:28 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