Vst.Core Set & GetChunk

Topics: VST.NET Core
Oct 6, 2015 at 5:17 AM
Hi, I'm amazed at all the work you must have done to produce this interface. And free, thanks!

I'm have only intermediate programming ability (VB.NET) and have been working hit-and-miss but have managed to create a simple working VST in a WPFControlWrapper using the Vst.Core dll. But I've hit a snag with Set/GetChunk. That is, with my inability to utilize them :-)

Basically, I'm trying to get the host to save a simple string (file name) that it will save with the instance.
My Vst essentially has no parameters that the host has to save, only the associated file name. (The Vst merely retrieves vsttimeinfo when the host plays and does things to the associated file).

So, my investigation led me to see that it's possible to save a string using GetChunk and SetChunk, but I don't quite understand how to use these. My PluginCommandStub exposes these as a sub and function, and of course I can run SetChunk, but for GetChunk, I don't know what to return as the byte array value...?
The sample stub of course has "Return Nothing" for this function but how does one actually get the Chunk byte array that the host has saved?

Possibly an awfully daft question but that's where I'm stuck.
Cheers,
Coordinator
Oct 6, 2015 at 7:26 AM
You have not picked the easiest way to work with VST.NET. The Core sample demonstrates the Core API but that is only intended for when you have a large existing code base you wish to (re)use in a new VST.NET plugin. I would strongly recommend you reconsider this choice.

The other samples (except Host of course) use the VST.NET Framework that further simplifies working with the VST 2.4 API and provides a some boiler plate code for you. Also Get/SetChunk is perhaps simpler for you...?

At core level you have to set the plugin flag 'ProgramChunks' https://vstnet.codeplex.com/SourceControl/latest#Source/Code/Jacobi.Vst.Core/VstPluginFlags.cs
so the Host knows it has to call these methods instead of using Parameters to persist the plugin state.

The Host will call GetChunk in order to get an opaque byte array (blob) that contains your data. YOU have to decide how and what to pack into the array. I suggest you use a writable MemoryStream (you can get the underlying buffer) to do that. That exact same blob is passed to SetChunk when your plugin is loaded. Key here is to interpret the byte array in exactly the same way as you have written it when GetChunk was called.

Hope it helps,
Marc
Oct 6, 2015 at 1:28 PM
Ah! I see now, I had it totally backwards. ---
Was thinking GetChunk was how you get the data that the host had and SetChunk was when you set it.
Instead, Get and Set are from the host's perspective.
Got it, and it works perfectly, thanks.
After setting the ProgramChunks flag I successfully returned a byte array of the file string to the host in GetChunk, then was able to retrieve it later by converting the bytes back into a string inside SetChunk.

Yes, the reason I'm using Core is exactly as you say, because I'm using some pretty extensive code from a previous WPF project, imported into a VST. But so far it's working beautifully, and now much better that the host will remember my file names! ;)

I have two other questions, about unprocessed audio and the WPF control wrapper not resizing on demand but I'll raise them separately on different threads^^

Cheers,
Michael
Coordinator
Oct 6, 2015 at 1:33 PM
Ok cool.
Oct 25, 2015 at 12:34 AM
Edited Oct 25, 2015 at 12:35 AM
Just to chime in on this one...

obiwan is right. Using a memory stream is probably the easiest way of writing your object to a file and vice versa. But, I'd to point you to my thread on this:
https://vstnet.codeplex.com/discussions/643753

This was my post:

Here's a rundown of serialization technologies I've evaluated. I've ended sticking to WCF DataContract Serialization.

Here's my two cents. Firstly, I see serialization as something that should be simple, and should just work without having to do much. Obviously, you're always going to have to define which properties and types you want to serialize, and those that you do not. But, the technology should be flexible enough to allow for scenarios that would not be expected. One of the constant issues that comes up is when the serializer encounters a type that it does not know about. While I think that the DataContractSerializer is clunky, it at least allows for dealing with unexpected types. Of course verbosity and performance are factors, but I haven't been focused on those much.

Standard .Net Serialization
This has been around since the early days of .Net. It uses XML. It works when dealing with properties like floats and strings etc. but gets a bit clunky when dealing with anything more complex. It works by including all properties unless you explicitly exclude them. It can deal with unexpected types, but you have to define these with attributes at compile time. So, for me, this renders the technology useless. On top of this, it inexplicably complains when your collections contain type arguments for polymorphism. The dumb thing about that it is that its perfectly happy to accept types of "object" for type arguments. You can get around these issues with custom serialization, but that really defeats the purpose.

Newtonsoft Json.Net
https://json.codeplex.com/
This is a pretty decent library. It uses Json so it's a bit less verbose than XML. It's very straight forward to get started, but it seems pretty difficult to define which properties and types should be serialized. I didn't delve in to it deeply, but it's not as simple as just marking properties with attributes. I don't even know how you would tell it not to serialize a particular field. This would be worth having a go, but as yet, I've never really successfully used it for anything very complex. This library is very popular and has a lot of support.

Sharp Serializer
www.sharpserializer.com/
To be honest, I haven't got much to say about this. I just remember trying it, and instantly giving up because it seemed to hard to get it to work. That doesn't mean to say that it is too hard - it just didn't work for me right away.

WCF DataContract Serialization

This is the library behind the way WCF works. It is markup language agnostic so it has the flexibility to be serialized in any supported language, although I haven't really played with this. It defaults to XML. I chose this for one main reason. The reason is that this library accepts collections with a type argument where the type argument is an interface - i.e. polymorphic. This is what I needed for my project because I do not know what I will be putting in the collection until I hit the save button. Actually, because the user can define types, it's necessary for the serializer to be able to do this. With this serializer you can provide a list of known types so that it is not surprised by types when it attempts to serialize/deserialize. Basically, I've had success with this, without have to do much. The one downside (or perhaps upside) is that you have to explicitly elect which properties and types to serialize by marking them with attributes. I think this is overkill, but what are you gonna do?

I ended up settling on DataContractSerialization (XML) because it suited my purpose for now. I'd say that the biggest reason is that it's easy to specify which properties get serialized and which don't (DataMembers). But, Json.Net is also excellent.
Oct 25, 2015 at 7:42 AM
Kruddler wrote:
Just to chime in on this one...

obiwan is right. Using a memory stream is probably the easiest way of writing your object to a file and vice versa. But, I'd to point you to my thread on this:
https://vstnet.codeplex.com/discussions/643753
I can see that memory stream would be best for writing/reading files, but in this particular case all I needed GetChunk/SetChunk for was for the host to store a file name with the DAW project. (a file that I subsequently manipulate separately once the VST is loaded).
That being the goal, I just convert the file name string to a byte array and vice-versa.

But thx anyway!