Problem load DSP Winamp Plugin DELPHI Firework(FMX)

Started by Lbaudio,

Lbaudio

I'm trying to migrate a simple MP3 player from Delphi VCL to FMX which has a very friendly appearance, but I can't get bass_wadsp.dll to work with bass.dll.
The same code works perfectly with Delphi VCL but not FMX.
_dspPluginA := BASS_WADSP_Load(PChar('dsp_stereo_tool.dll'), 0, 0, 0, 0, nil);

Ian @ un4seen

If you try opening the dsp_stereo_tool.dll file with normal file reading functions at the same place in your code, does that work? If not, you could try including the full path.

Lbaudio

It works in VCL in Delphi but in FIREWORKS (FMX) it doesn't work, even with the full path of the dll.

Lbaudio

So this is the code:

unit Unit1;

interface

uses
  windows, System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, Bass, bass_wadsp;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog: TOpenDialog;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

_streamA : HSTREAM;
hDsp: DWORD;

_dspPluginA, _dspPluginB: Integer;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // and load a Winamp DSP plugin
  _dspPluginA := BASS_WADSP_Load(PChar('vst_stereo_tool_7.23.dll'), 5, 5, 100, 100, nil);
  // and start it's first module (0)
  BASS_WADSP_Start(_dspPluginA, 0, 0);

  if OpenDialog.Execute then begin
      // create the stream
      _streamA := trunc(BASS_StreamCreateFile(FALSE,PChar(OpenDialog.FileName),0,0,0 {$IFDEF UNICODE} or BASS_UNICODE{$ENDIF}));
      //_streamA := BASS_StreamCreateFile(False, PChar(OpenDialog.FileName), 0, 0, BASS_STREAM_AUTOFREE);

      if _streamA <> 0  then begin
          // the next will setup a DSP on the channel - like a normal Bass DSP
          hDsp := BASS_WADSP_ChannelSetDSP(_dspPluginA, _streamA, 1);
          //BASS_WADSP_ChannelSetDSP(_dspPluginA, _streamA, 1);
          //showmessage(IntToStr(hDSP));
          // and finally start playing it...
          BASS_ChannelPlay(_streamA, false);
      end;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // when you exit your application call
    BASS_Stop();
  // needed in a catch, since some Winamp dsps might raise an exception when closing
    BASS_WADSP_Free();
    BASS_Free();
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  verW: DWORD;
begin
  // check the correct BASS was loaded
  if (HIWORD(BASS_GetVersion) <> BASSVERSION) then
  begin
    MessageBox(0,'Erro no sistema de audio! DLL faltando',nil,MB_ICONERROR);
    ExitProcess(0);
  end;

  // at startup of your application call this...
  if BASS_Init(-1, 44100, 0, DWORD(Handle), nil) then begin
      // init bass_dsp with your applications main window handle
      BASS_WADSP_Init(DWORD(Handle));
  end;
end;

end.

Ian @ un4seen

What return values are you getting from BASS_WADSP_Load and BASS_StreamCreateFile? Also, why are you using "trunc" on the BASS_StreamCreateFile return value?

Lbaudio

BASS_StreamCreateFile is OK. Problem only LOAD DSP DLL.
_dspPluginA return 0
_streamA is OK
Remembering that even before loading the audio, _dspPluginA should return 1. I think there is a problem in the bass_wadsp.pas module to access WND (HANDLE) in FMX. HWADSP is declared as DWORD and this may be the problem with Delphi's FIREMONKEY forms, because if I make a project without FireMonkey, it works normally.
function BASS_WADSP_Load(dspfile: PChar; x: HSTREAM; y: HSTREAM; width: HSTREAM; height: HSTREAM; proc: WINAMPWINPROC): HWADSP; stdcall; external basswadspdll;

Ian @ un4seen

What error code is BASS_WADSP_Load giving? Call BASS_ErrorGetCode afterwards to find out.

Lbaudio

It doesn't show any error, it simply plays the audio without the effect. When I call the _dspPluginA function, the plugin screen should appear, but it doesn't.

Chris

Are you sure you are loading the the correct Stereo-Tool File?
In your Sourcecode : BASS_WADSP_Load(PChar('vst_stereo_tool_7.23.dll')
VST is for VST Host and not for Winamp.

dsp_stereo_tool  is for Winamp/BASS_WADSP

by the way the BASS_WADSP_Load should to be

function BASS_WADSP_Load(dspfile: PChar; x: Integer; y: Integer; width: Integer; height: Integer; proc: WINAMPWINPROC): HWADSP; stdcall; external basswadspdll;and not
function BASS_WADSP_Load(dspfile: PChar; x: HSTREAM; y: HSTREAM; width: HSTREAM; height: HSTREAM; proc: WINAMPWINPROC): HWADSP; stdcall; external basswadspdll;

Lbaudio

Sorry, I put the name VST because I also tested the STEREO TOOL with VST, but this plugin is very slow in VST. I made the change you suggested, but no results in Delphi's FMX forms. As I said, with VCL forms, it works normally. I'm not an expert in programming, but I believe the problem is in the way the plugin in FMX executes. I believe the problem must be in WINAMPWINPROC = function(hwnd: HWND; msg: DWORD; wParam: DWORD; lParam: DWORD):DWORD; stdcall; Below is the test code.


unit Unit1;

interface

uses
  windows, System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, Bass, bass_wadsp;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog: TOpenDialog;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

_streamA : HSTREAM;
hDsp: DWORD;

_dspPluginA, _dspPluginB: Integer;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // and load a Winamp DSP plugin
  _dspPluginA := BASS_WADSP_Load(PChar('./plugins/dsp_stereo_tool.dll'), 5, 5, 100, 100, nil);

  // and start it's first module (0)
  BASS_WADSP_Start(_dspPluginA, 0, 0);

  if OpenDialog.Execute then begin
      // create the stream
      _streamA := trunc(BASS_StreamCreateFile(FALSE,PChar(OpenDialog.FileName),0,0,0 {$IFDEF UNICODE} or BASS_UNICODE{$ENDIF}));
      //_streamA := BASS_StreamCreateFile(False, PChar(OpenDialog.FileName), 0, 0, BASS_STREAM_AUTOFREE);

      if _streamA <> 0  then begin
          // the next will setup a DSP on the channel - like a normal Bass DSP
          hDsp := BASS_WADSP_ChannelSetDSP(_dspPluginA, _streamA, 1);
          //BASS_WADSP_ChannelSetDSP(_dspPluginA, _streamA, 1);
          //showmessage(IntToStr(hDSP));
          // and finally start playing it...
          BASS_ChannelPlay(_streamA, false);
      end;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // when you exit your application call
    BASS_Stop();
  // needed in a catch, since some Winamp dsps might raise an exception when closing
    BASS_WADSP_Free();
    BASS_Free();
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  verW: DWORD;
begin
  // check the correct BASS was loaded
  if (HIWORD(BASS_GetVersion) <> BASSVERSION) then
  begin
    MessageBox(0,'Erro no sistema de audio! DLL faltando',nil,MB_ICONERROR);
    ExitProcess(0);
  end;

  // at startup of your application call this...
  if BASS_Init(-1, 44100, 0, DWORD(Handle), nil) then begin
      // init bass_dsp with your applications main window handle
      BASS_WADSP_Init(DWORD(Handle));
  end;
end;

end.

Chris

Your Form Handle is wrong.
Just Change it to

uses
  FMX.Platform.Win;

var
  FormHandle : HWND;

.......
FormHandle := FormToHWND(Form1);or
FormHandle := WindowHandleToPlatform(form1.Handle).wnd;
BASS_WADSP_Init(FormHandle);.......

Lbaudio

Thank you very much, that was it and it worked.
Quote from: ChrisYour Form Handle is wrong.
Just Change it to

uses
  FMX.Platform.Win;

var
  FormHandle : HWND;

.......
FormHandle := FormToHWND(Form1);or
FormHandle := WindowHandleToPlatform(form1.Handle).wnd;
BASS_WADSP_Init(FormHandle);.......