Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   TBassDllPlayer + Visualisierung (Komponenten) (https://www.delphipraxis.net/52388-tbassdllplayer-visualisierung-komponenten.html)

Gandalfus 29. Aug 2005 11:46


TBassDllPlayer + Visualisierung (Komponenten)
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ein Player der auf der bass.dll basiert (Lizens der bass.dll beachten) und eine Visualisierungs Komponente.

Bei der Visualisierungs Komponente ist wichtig, dass die Felder Bassdllplayer und VisualisierungsEinstellungen zugeordnet sind.

Für die VIsualierung kann man dlls als Plugin laden.

Ein Beispiel für solch eine Dll:

Delphi-Quellcode:
library Project1;

{keine normalen strings übergeben sonder nur PChar}

uses
  Windows, Classes, Graphics,
  math, Controls, Messages, ExtCtrls, mmsystem, Dialogs, Contnrs, SysUtils;
{$R *.res}

type
  TFFTData= array[0..256] of Extended;
  TWaveData = array [ 0..2048] of DWORD;

  TFFTandWaveData = record
    FFTdata: TFFTdata; //zwischen 0 und 1
    waveData: TwaveData;
    leftpeak,rightpeak: dword; {von 0 bis 32768}
  end;

function getVersion: integer; stdcall;
begin
  result := 1;
end;

procedure draw(CanvasHandle: HDC; Backgroundcolor,Bordercolor,BalkenColor: Graphics.TColor; width,height: integer; var FFTData: TFFTandWaveData); stdcall;
var
  data: TFFTdata;
  i: integer;
  TempBitmap: TBitmap;
begin
  IF CanvasHandle=0 then exit;
  data := FFTData.FFTdata;

  TempBitmap := TBitmap.create;
  TempBitmap.Width := width;
  TempBitmap.height := height;

  for i := 1 to 256 do
  begin
    Data[i] := Data[i]*ln(i)*4*((height));
    if Data[i] > (height) then Data[i] := (height);
  end;
  TempBitmap.canvas.pen.color := Bordercolor;
  TempBitmap.canvas.brush.color := Backgroundcolor;
  TempBitmap.canvas.Rectangle(0,0,width,height);
  TempBitmap.canvas.pen.color := BalkenColor;
  for i := 1 to 256 do
  begin
    TempBitmap.Canvas.MoveTo(i,height);
    TempBitmap.canvas.lineTo(i,(height)-round(Data[i]));
  end;

  BitBlt(CanvasHandle, 0, 0, TempBitmap.width, TempBitmap.height, TempBitmap.canvas.Handle , 0, 0 , SRCCOPY);

  TempBitmap.free;
end;

exports
  draw;
  getVersion;

begin

end.
Edit: Die Procedure für die VersionsKontrolle wurde irgendwie gelöscht. Ich hab sie jetzt hinzugefügt.

Dann die dll noch in xyz.bvis umbenen und danach kann kann sie über das popup Menüe geladen werden.
Wäre nett wenn sich Leute finden würden, die Plugins programmieren würden.



mfg

dizzy 29. Aug 2005 11:57

Re: TBassDllPlayer + Visualisierung (Komponente)
 
Coole Sache! Ich werd mich mal dran machen, und versuchen meine Visuals vom FKBassPlayer in DLLs zu verpacken, da sie hier sicher modularer und hübscher aufgehoben sind :). Seit dem letzten Upload meines Players sind auch noch 2 nette Visuals dazu gekommen.
Das wird nen Spaß =)

dizzy 29. Aug 2005 22:43

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Sooo, ich habe mal ein wenig darin gewühlt, und es sind mir ein paar Dinge aufgefallen:
  1. Zunächst ein kleiner Fehler in dem DLL-Code oben: Exportierte Funktionen werden mit Kommata getrennt, nicht mit Semikola.
  2. Mit dieser Änderung kompilierts, jedoch meldet der Player (Demo) beim Ladeversuch, dass die Version nicht unterstützt würde. Ich habe aber nirgends eine aktuelle Versionsnummer gefunden.
  3. 256 FFT-Daten sind mir für ein paar meiner Visuals etwas zu wenig. Ich wünschte mir so 1024 :) (von denen ja nur 512 nutzbar sind)
  4. Die Zeichenfläche der Visuals erscheint mir recht statisch. Es wäre viel schöner wenn die Größe entweder frei durch den Benutzer definierbar wäre, oder aber auch durch ein Visual vorgegeben werden könnte. Ich habe in dem Source zur Demo nicht finden können wo dort die Randdaten für das Visual gesetzt werden :?
  5. Dem Visual werden eine Reihe Farbwerte mitgegeben. Hier frage ich mich warum - da ich denke dass ein Visual, wenn schon so öffen über ein PlugIn-System schreibbar, auch seine Farben frei wählen sollte. Klar, man kann die Werte ignorieren, aber es sind dann überflüssige Pushes da (*khorrintenkackerbin* :D)
  6. FFT- und Wavedaten als gemeinsamen Pointer zu übergeben find ich gut - spart ein Push ;) (Width & Height evtl. auch als TPoint übergeben?)

Najo, das waren die Punkte bisher, wobei mich insbesondere die Sache mit der Verison am Weitermachen hindert. Zudem bräuchte ich einen Nasenstubs dahin, wo das Visual auf dem Form eingebettet wird.

Schönen Gruss,
Fabian


\\edit: Hm, jetzt wo ich nochmal drüber nachdenke ist die Übergabe mit einem gemeinsamen Pointer evtl. doch nicht so sehr günstig, da dann ja bei jeder Verwendung 2 mal referenziert werden müsste, oder liege ich mit der Annahme falsch? Oder mit der Folgerung, dass dies Geschwindigkeitsnachteile haben könnte?

Gandalfus 30. Aug 2005 14:11

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Zitat:

Zitat von dizzy
Sooo, ich habe mal ein wenig darin gewühlt, und es sind mir ein paar Dinge aufgefallen:

gut, dass du dich damit beschäftigst.

Zitat:

Zitat von dizzy
[list=1][*] Zunächst ein kleiner Fehler in dem DLL-Code oben: Exportierte Funktionen werden mit Kommata getrennt, nicht mit Semikola.[*] Mit dieser Änderung kompilierts, jedoch meldet der Player (Demo) beim Ladeversuch, dass die Version nicht unterstützt würde. Ich habe aber nirgends eine aktuelle Versionsnummer gefunden.

Ich habe folgendes mit Delphi 7 comiliert uns es funktionierte.
Delphi-Quellcode:
library Project1;

{keine normalen strings übergeben sonder nur PChar}

uses
  Windows, Classes, Graphics,
  math, Controls, Messages, ExtCtrls, mmsystem, Dialogs, Contnrs, SysUtils;
{$R *.res}

type
  TFFTData= array[0..256] of Extended;
  TWaveData = array [ 0..2048] of DWORD;

  TFFTandWaveData = record
    FFTdata: TFFTdata;
    waveData: TwaveData;
    leftpeak,rightpeak: dword; {von 0 bis 32768}
  end;

function getVersion: integer;
begin
  result:=1;
end;


procedure draw(CanvasHandle: HDC; Backgroundcolor,Bordercolor,BalkenColor: Graphics.TColor; width,height: integer; var FFTData: TFFTandWaveData); stdcall;
var
  data: TFFTdata;
  i: integer;
  TempBitmap: TBitmap;
begin
  IF CanvasHandle=0 then exit;
  data := FFTData.FFTdata;

  TempBitmap := TBitmap.create;
  TempBitmap.Width := width;
  TempBitmap.height := height;

  for i := 1 to 256 do
  begin
    Data[i] := Data[i]*ln(i)*4*((height));
    if Data[i] > (height) then Data[i] := (height);
  end;
  TempBitmap.canvas.pen.color := Bordercolor;
  TempBitmap.canvas.brush.color := Backgroundcolor;
  TempBitmap.canvas.Rectangle(0,0,width,height);
  TempBitmap.canvas.pen.color := BalkenColor;
  for i := 1 to 256 do
  begin
    TempBitmap.Canvas.MoveTo(i,height);
    TempBitmap.canvas.lineTo(i,(height)-round(Data[i]));
  end;

  BitBlt(CanvasHandle, 0, 0, TempBitmap.width, TempBitmap.height, TempBitmap.canvas.Handle , 0, 0 , SRCCOPY);

  TempBitmap.free;
end;

exports
  draw,
  getVersion;

begin

end.
Zitat:

[*] 256 FFT-Daten sind mir für ein paar meiner Visuals etwas zu wenig. Ich wünschte mir so 1024 :) (von denen ja nur 512 nutzbar sind)
Hmm. Eigednlich wäre es ja am besten wenn man von der dll aus einstellen könnte welche Daten man haben will.

Zitat:

[*] Die Zeichenfläche der Visuals erscheint mir recht statisch. Es wäre viel schöner wenn die Größe entweder frei durch den Benutzer definierbar wäre, oder aber auch durch ein Visual vorgegeben werden könnte. Ich habe in dem Source zur Demo nicht finden können wo dort die Randdaten für das Visual gesetzt werden :?
Mann kann die grösse von der Visualiesierungs Komponenet ja im Programm verändern. wenn man die Grässe in der dll veändert würde sie unterumständen nichtmehr in das Design des Programms passe.
Der Sourcecode für dei Demo ist doch dabei oder nicht?

Zitat:

[*] Dem Visual werden eine Reihe Farbwerte mitgegeben. Hier frage ich mich warum - da ich denke dass ein Visual, wenn schon so öffen über ein PlugIn-System schreibbar, auch seine Farben frei wählen sollte. Klar, man kann die Werte ignorieren, aber es sind dann überflüssige Pushes da (*khorrintenkackerbin* :D)
Naja wenn man einene HIntergrundzecihenen will der zum Rest der Komponnete passt braucht man die Farben von dem Rest der Komponnete.
Dafür ist das gedacht.

Zitat:

Najo, das waren die Punkte bisher, wobei mich insbesondere die Sache mit der Verison am Weitermachen hindert. Zudem bräuchte ich einen Nasenstubs dahin, wo das Visual auf dem Form eingebettet wird.
CanvasHandle ist ein der Handel des TCanvas von einem TgraphicControll. Ich könnte auch einen Canvas oder eine TGraphicControll übergeben, wenn das besser passt.

Zitat:

\\edit: Hm, jetzt wo ich nochmal drüber nachdenke ist die Übergabe mit einem gemeinsamen Pointer evtl. doch nicht so sehr günstig, da dann ja bei jeder Verwendung 2 mal referenziert werden müsste, oder liege ich mit der Annahme falsch? Oder mit der Folgerung, dass dies Geschwindigkeitsnachteile haben könnte?
Vieleicht könntets du eine kleine liste der änderungen machen die brauchst.

mfg Henning
Du meinst, dass die höhe und Breite noch in den record mit rein kommt?

dizzy 30. Aug 2005 14:40

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Zitat:

Zitat von Gandalfus
Ich habe folgendes mit Delphi 7 comiliert uns es funktionierte.
[...code...]

Kompilieren tuts bei mir auch (D7), wenn ich aber dies versuche in der Demo als Visual zu laden, so kommt die Meldung dass die Dateiversion nicht unterstützt würde. Ich nehme einfach an, dass getVersion() einen anderen Wert zurückgeben müsste - den ich nicht kenne.

Zitat:

Zitat von Gandalfus
Hmm. Eigednlich wäre es ja am besten wenn man von der dll aus einstellen könnte welche Daten man haben will.

Das wäre natürlich der Knaller.

Zitat:

Zitat von Gandalfus
Mann kann die grösse von der Visualiesierungs Komponenet ja im Programm verändern. wenn man die Grässe in der dll veändert würde sie unterumständen nichtmehr in das Design des Programms passe.
Der Sourcecode für dei Demo ist doch dabei oder nicht?

Ja ist er, nur ich hab wohl die Stelle nicht gefunden an der der DLL der Canvas übergeben wird. Ich schau heut abend nochmal rein - war gestern schon was müde ;).

Zitat:

Zitat von Gandalfus
Naja wenn man einene HIntergrundzecihenen will der zum Rest der Komponnete passt braucht man die Farben von dem Rest der Komponnete.
Dafür ist das gedacht.

An sich keine schlechte Idee. Ließe sich das evtl. nicht auch über eine gesonderte Funktion lösen, die die DLL aus dem Host aufruft? (Geht das überhaupt?) Mir ging es nur darum, dass die Parameter ja für jeden Frame neu übergeben werden, und somit in den meisten Fällen überflüssig sind.
Sinnvoll wäre hier evtl. eine Init-Funktion in der DLL vorzuschreiben, der die Randdaten bei Änderung übergeben werden, so dass sie nicht jedes Frame, sondern nur bei Bedarf übergeben werden müssen. Gleiches gilt für die Größe, bei den Wave/FFT-Daten allerdings ist es idR erforderlich dass sie stets aktuell sind. Die würde ich bei der Draw-Routine belassen.

Zitat:

Zitat von Gandalfus
CanvasHandle ist ein der Handel des TCanvas von einem TgraphicControll. Ich könnte auch einen Canvas oder eine TGraphicControll übergeben, wenn das besser passt.

Nönö, ein HDC ist schon gut! Die Aussage war nur darauf bezogen dass ich wie o.g. nicht die Stelle im Source gefunden hatte, an der der DLL eben dieser übergeben wird ;).

Zitat:

Zitat von Gandalfus
Vieleicht könntets du eine kleine liste der änderungen machen die brauchst.

"Brauchen" ist zu viel gesagt. "Wünschen" wäre besser :D. Eigentlich wäre zunächst wie oben angesprochen eine separate Funktion zur Übergabe der Farb- und Größenwerte sinnvoll, und eine Lösung für das Versionsproblem. Ansonsten dürfte alles gut und klar sein.
Sahnehäubchen wäre wie angesprochen eine Möglichkeit, mit der die DLL die FFT-/Wavedaten in gewünschter Länge und Art anfordern könnte. Aber es würde schon ausreichen jeweils eine 1024 oder 2048 Werte lange Version zu übergeben. Ist ja eh nur nen Pointer, und wenn man nachher weniger braucht, kann das in der DLL ja immernoch leicht bewerkstelligt werden.

Zitat:

Zitat von Gandalfus
Du meinst, dass die höhe und Breite noch in den record mit rein kommt?

Ursprünglich ja, aber ich glaube dass das mehr Nach- als Vorteile bringt. Ignoriere diesen Teil einfach :stupid:


Gruss,
Fabian

Gandalfus 30. Aug 2005 15:59

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Hast du die Gross und klein Schreibung beachtet?
Das laden erfolgt so. Vieleicht hilft das den Fehler zu finden:

Delphi-Quellcode:
  TDrawDLLProcedure= procedure (CanvasHandle: HDC; Backgroundcolor,Bordercolor, BalkenColor: TColor; width,height: integer; var FFTData: TFFTandWaveData) stdcall;
  TVersionDLLProcedure= function: integer; stdcall;

procedure TVisualisierungEinstellungen.AddPlugin(filename: string);
begin
  IF FileExists(filename) then
  begin
    ListederVisualisierungen.Add(TEinzelneVisualisierung.Create);
    TEinzelneVisualisierung(ListederVisualisierungen.last).filename := filename;
    TEinzelneVisualisierung(ListederVisualisierungen.last).modus := 1;

    TEinzelneVisualisierung(ListederVisualisierungen.last).DllHandle:=LoadLibrary(PChar(filename));
    if TEinzelneVisualisierung(ListederVisualisierungen.last).DllHandle <> 0 then
    begin
      @TEinzelneVisualisierung(ListederVisualisierungen.last).VersionDLLProcedure := GetProcAddress(TEinzelneVisualisierung(ListederVisualisierungen.last).DllHandle, 'getVersion');
      IF nil<>@TEinzelneVisualisierung(ListederVisualisierungen.last).VersionDLLProcedure then
        begin
        If TEinzelneVisualisierung(ListederVisualisierungen.last).VersionDLLProcedure=1 then
        begin
          @TEinzelneVisualisierung(ListederVisualisierungen.last).DrawDLLProcedure := GetProcAddress(TEinzelneVisualisierung(ListederVisualisierungen.last).DllHandle, 'draw');
        end
        else
        begin
          ListederVisualisierungen.Delete(ListederVisualisierungen.count-1);
          showmessage('Dateiversion wird nicht unterstützt');
        end;
      end
      else
      begin
        ListederVisualisierungen.Delete(ListederVisualisierungen.count-1);
        showmessage('Dateiversion wird nicht unterstützt');
      end;
    end
    else
    begin
      ListederVisualisierungen.Delete(ListederVisualisierungen.count-1);
      showmessage('kein passendes Plugin');
    end;
  end;
end;

dizzy 30. Aug 2005 17:37

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
:shock: Frag mich nicht warum, aber ich habe meine DLL gerade einfach nochmal neu kompiliert - und nun klappts...

Und ich habe wirklich nichts anderes gemacht, als das Projekt zu öffnen und neu zu erstellen :gruebel:

Naja, wäre dieser Punkt geklärt =)

dizzy 30. Aug 2005 20:54

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Täterätäää, mein neustes Kick-Ass Visual, die "Disco-Sprites", hübsch in eine DLL verpackt die in diesem Player als Plugin läuft.

Leider haben meine MMX-Optimierungen in dieser Version nicht funktioniert, in meinem Player geht's. Komischerweise reicht es schon einen Farbwert in ein MMX-Register zu schieben und zurück, um alle Bits auf 0 zu setzen :(. Keine Ahnung wer da noch an der FPU rumpfuscht :D. (Wobei ich bei meinem Player ja genau so mit Threads und der Bass.dll arbeite :gruebel:)
Naja, dadurch wird's nicht weniger hübsch, nur etwas weniger performant.
Die optimale Canvasgröße wäre so bei ca. 400x400 Pixeln, es sieht aber auch in dem Demo-Player schick aus ;)


Das wäre btw. eines der Visuals, für die ich gern 512 (oder mehr) FFT-Werte hätte. Hab hier jetzt gepfuscht indem immer 2 Sprites den selben Wert bekommen, dann passte es.

Anm.: Kein DirectX/OGL - reine G32 ;)


Gruss,
Fabian

Gandalfus 1. Sep 2005 11:54

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Wow die Visual sieht ziemlich gut aus. :thumb:

Ich hab jetzt auch die entsprechenden Erweiterungen ergänzt.

Die Dll muss jetzt so aussehen:

Delphi-Quellcode:
library Project1;

{keine normalen strings übergeben sonder nur PChar}

uses
  Windows, Classes, Graphics,
  math, Controls, Messages, ExtCtrls, mmsystem, Dialogs, Contnrs, SysUtils;
{$R *.res}

type
  TFFTData256= array[0..256] of Extended;
  TFFTData512= array[0..512] of Extended;
  TWaveData = array [ 0..2048] of DWORD;

  TFFTandWaveData = record
    FFTdata256: TFFTdata256;
    FFTdata512: TFFTdata512;
    waveData: TwaveData;
    leftpeak,rightpeak: dword; {von 0 bis 32768}
  end;

  TVisInfo = record
    VisName: PChar;
    Author: Pchar;
    AuthorHomepage: Pchar;
    FFTdata256Flag: boolean;
    FFTdata512Flag: boolean;
    waveDataFlag: boolean;
    Peaks: boolean;
  end;

  TEinstellungen = record
    Backgroundcolor,Bordercolor,BalkenColor: Graphics.TColor;
    width,height: integer;
  end;

var
  Einstellungen: TEinstellungen;

function getVersion: integer; stdcall;
begin
  result:=2;
end;

procedure setEinstellungen(neuEinstellungen: TEinstellungen); stdcall;
begin
  Einstellungen := neuEinstellungen;
end;

function getVisInfo: TVisInfo; stdcall;
var
  temp: TVisInfo;
begin
  temp.VisName := 'test';
  temp.Author:= 'Henning Brackmann';
  temp.AuthorHomepage:= 'www.blubplayer.de';
  temp.FFTdata256Flag := true;
  temp.FFTdata512Flag := false;
  temp.waveDataFlag := false;
  temp.Peaks := false;
  result:=temp;
end;

procedure draw(CanvasHandle: HDC; var FFTData: TFFTandWaveData); stdcall;
var
  data: TFFTdata256;
  i: integer;
  TempBitmap: TBitmap;
begin
  IF CanvasHandle=0 then exit;
  data := FFTData.FFTdata256;

  TempBitmap := TBitmap.create;
  TempBitmap.Width := Einstellungen.width;
  TempBitmap.height := Einstellungen.height;

  for i := 1 to 256 do
  begin
    Data[i] := Data[i]*ln(i)*4*((Einstellungen.height));
    if Data[i] > (Einstellungen.height) then Data[i] := (Einstellungen.height);
  end;
  TempBitmap.canvas.pen.color := Einstellungen.Bordercolor;
  TempBitmap.canvas.brush.color := Einstellungen.Backgroundcolor;
  TempBitmap.canvas.Rectangle(0,0,Einstellungen.width,Einstellungen.height);
  TempBitmap.canvas.pen.color := Einstellungen.BalkenColor;
  for i := 1 to 256 do
  begin
    TempBitmap.Canvas.MoveTo(i,Einstellungen.height);
    TempBitmap.canvas.lineTo(i,(Einstellungen.height)-round(Data[i]));
  end;

  BitBlt(CanvasHandle, 0, 0, TempBitmap.width, TempBitmap.height, TempBitmap.canvas.Handle , 0, 0 , SRCCOPY);

  TempBitmap.free;
end;

exports
  draw,
  getVisInfo,
  setEinstellungen,
  getVersion;

begin

end.

dizzy 12. Sep 2005 01:53

Re: TBassDllPlayer + Visualisierung (Komponenten)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Södale, die neue Version. Sie ist nicht nur an das neue Interface angepasst, nein ich hab mich zu OpenGL hinreissen lassen :). Na denn: Fullscreen voraus!

Gruss,
Fabian


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.
Seite 1 von 2  1 2      

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