Author Topic: Dynamic_BassVST  (Read 493 times)

Ed1966

  • Posts: 166
Dynamic_BassVST
« on: 17 Feb '20 - 10:30 »
I am using Dynamic_BassVST Delphi Headers but could not find the following:

BASS_VST_GetChunk

BASS_VST_SetChunk

Can you add these if it's possible for w32 platform?

Or what to do?

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 23288
Re: Dynamic_BassVST
« Reply #1 on: 17 Feb '20 - 14:40 »
I've added those 2 functions to the Dynamic_BassVST.pas file now. I also changed "Char" to "AnsiChar" in some places. I'm not a Delphi user myself, so please let me know if there are any mistakes.

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #2 on: 17 Feb '20 - 16:42 »
Thank you.  :D

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #3 on: 18 Feb '20 - 08:11 »
Hi,

Not so easy to write for Delphi because it works a lot with pointers.
Is there perhaps a small example for BASS_VST_GetChunk & BASS_VST_SetChunk.
Thans in advanced.

I now use this and it's working:
BASS_VST_GetParamInfo, BASS_VST_SetParam, BASS_VST_GetParam
But not all VST are correctly saved.

Regards,
Eduard.

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #4 on: 18 Feb '20 - 18:12 »
I made something but result #0 and sometimes small text (5 letters)?

Code: [Select]
var
  Str: AnsiString;
  VstParams: PAnsiChar;
  ParamCnt: DWORD;
begin
  ParamCnt := BASS_VST_GetParamCount(AHandle);
  VstParams := BASS_VST_GetChunk(AHandle, False, @ParamCnt);
  Str := AnsiString(VstParams); // Test
end;

Am I forgotten something?

Falcosoft

  • Posts: 50
Re: Dynamic_BassVST
« Reply #5 on: 18 Feb '20 - 20:52 »
I think the problem is the function declarations deceived you. VST chunks are not character data (strings) but usually raw binary data. Chunks can contain anything, even #0 is perfectly legal. So when you interpret it as string (remember that long strings end with #0) you can get broken/partial data.
 If I were Ian I would have written the declarations as:   
Code: [Select]
BASS_VST_GetChunk: function (VSTHandle: DWORD; IsPreset: BOOL; var Length: DWORD): Pointer; stdcall;
BASS_VST_SetChunk: function (VSTHandle: DWORD; IsPreset: BOOL; Chunk: Pointer;  length: DWORD): DWORD; stdcall;
Using var DWORD instead of PDWORD would be much more Delphi like and using untyped Pointer instead of PAnsiChar could avoid misunderstanding like yours.

So the point is you should not convert Chunk data to string but handle it as raw binary data.
For saving Chunk data to a file you can do this:

Code: [Select]
Var
len: DWORD;
p: Pointer;
f: File;
fileName: String;

p := BASS_VST_GetChunk(AHandle, False, len);
if p <> nil then
Begin
 fileName := 'vstdata.bin';
 AssignFile(f, fileName);
 Rewrite(f, 1);
     Try     
      BlockWrite(f, p^, len);
     Finally
        CloseFile(f);
      End;
End;

And for loading data back to plugin:
Code: [Select]
...
  AssignFile(f, fileName);
  Reset(f, 1);
  len := FileSize(f);

  Try   
   GetMem(p, len);
   BlockRead(f, p^, len);
   BASS_VST_SetChunk(AHandle, False, p, len);
  Finally
   FreeMem(p);
   CloseFile(f);
  End;
 
« Last Edit: 18 Feb '20 - 22:25 by Falcosoft »

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #6 on: 19 Feb '20 - 03:42 »
Thanks Falcosoft. I give it a try.  :)

A few hours later ... Everything works.  :D
I first try BASS_VST_GetChunk and if that gives a BASS_ERROR_NOTAVAIL then I try BASS_VST_GetParam.
Is this the right (or good) way?
I see here that one Plugin writes a Chunk and the other prefers a GetParam.

Small question about BASS_VST_EmbedEditor
Now I use the Handle of TForm and that works:
Result: = VSTPluginForm.Handle;
I actually want to use the handle of a TPanel:
Result: = VSTPluginForm.MainPanel.Handle;
But that doesn't work. Do you know why?

PS: BASS_VST does not support vst3?

Thanks and Regards,
Eduard.
« Last Edit: 19 Feb '20 - 05:21 by Ed1966 »

tcp2000

  • Posts: 23
Re: Dynamic_BassVST
« Reply #7 on: 10 Jan '21 - 15:48 »
Have you got a C++ version please?

Got this so far:

Code: [Select]
//Gets the VST plug-in state as a plain byte array (memory chunk storage).
void* chunk;
DWORD len;

//get VSTi state
chunk = BASS_VST_GetChunk(vststream, 0, &len);

//write to FXB file

.....

//Sets the VST plug-in state with a plain byte array (memory chunk storage).
void* chunk;
DWORD len;

       //read from FXB file


const char* const ptrToPass = reinterpret_cast<const char* const>(chunk);
BASS_VST_SetChunk(vststream, 0, ptrToPass, len);


« Last Edit: 11 Jan '21 - 11:13 by tcp2000 »

saga

  • Posts: 2463
Re: Dynamic_BassVST
« Reply #8 on: 10 Jan '21 - 17:18 »
Note that the example above doesn't write FXB/FXP files; it just reads/writes the binary chunk to a file. An FXB/FXP files contains a header that is documented in vstfxstore.h from the VST SDK. Do you plan to write FXB/FXP files to interact with other VST hosts, or do you just want to write the chunk to a file so that you can use it later?

tcp2000

  • Posts: 23
Re: Dynamic_BassVST
« Reply #9 on: 11 Jan '21 - 10:47 »
Sorry if not clear - the reading and writing is the bit i can't work out!

saga

  • Posts: 2463
Re: Dynamic_BassVST
« Reply #10 on: 11 Jan '21 - 13:32 »
You could use an fstream to read / write:

Code: [Select]
#include <fstream>
...
void* chunk;
DWORD len;

chunk = BASS_VST_GetChunk(vststream, 0, &len);

std::ofstream f("out.bin", std::ios::binary | std::ios::trunc);
f.write(static_cast<char*>(chunk), len);

Code: [Select]
#include <fstream>
#include <vector>
...
std::ifstream f("in.bin", std::ios::binary);

// get length of file
f.seekg(0, std::ios::end);
auto len= f.tellg();
f.seekg(0, std::ios::beg);

std::vector<char> chunk(len);

f.read(chunk.data(),len);
BASS_VST_SetChunk(vststream, 0, chunk, len);

But as mentioned, what this code writes and reads are not FXB files; it's just a raw memory dump of the plugin chunk. An actual FXB file would contain a header that tells you which plugin the data is for, whether it's a whole bank or just a single program, etc...

tcp2000

  • Posts: 23
Re: Dynamic_BassVST
« Reply #11 on: 11 Jan '21 - 15:35 »
The save appears to work :)  but the read has a problem as I get the error:

no suitable conversion function from "std::vector<char, std::allocator<char>>" to "const char *" exists   



tcp2000

  • Posts: 23
Re: Dynamic_BassVST
« Reply #12 on: 11 Jan '21 - 18:21 »
Added the following line after the read

Code: [Select]
const char* chunk2 = &chunk[0];
And it works!!

Many thanks for your help  :) :)

saga

  • Posts: 2463
Re: Dynamic_BassVST
« Reply #13 on: 11 Jan '21 - 18:41 »
You can also use use chunk.data() (just like in the read call), which is cleaner.

tcp2000

  • Posts: 23
Re: Dynamic_BassVST
« Reply #14 on: 11 Jan '21 - 19:20 »
Cool - that works!

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #15 on: 11 Jan '21 - 21:05 »
Reminder?
BASS_VST does not support vst3?
or more then stereo?

Falcosoft

  • Posts: 50
Re: Dynamic_BassVST
« Reply #16 on: 12 Jan '21 - 10:53 »
Reminder?
BASS_VST does not support vst3?
or more then stereo?

VST3 is not supported. And it's not likely it will be supported soon(ever). VST3 is a completely different beast so a complete rewrite would be required.
AFAIK more than stereo channels are supported. But be aware that your VST/VSTi plugins should also support more than 2 channels.   

Ed1966

  • Posts: 166
Re: Dynamic_BassVST
« Reply #17 on: 12 Jan '21 - 15:16 »
I know enough. Thanks.  :)