This project has moved and is read-only. For the latest updates, please go here.

Plug-in seems not to be VST

Topics: Audio, Getting Started, Plugin Development
May 25, 2011 at 2:37 PM

Hi Obiwan! I'm developing my first audio plug-in and I am in troubles...

In .NET technology, I have written small application, which catches audio-in stream and, using the FFT, transforms the data into MIDI and sends them to MIDI-out channel.

This stuff is being built as the .dll library project, with its own GUI, written in C#.

My aim si to use this library as the VST plug-in, which is not working now, audio workstations [VST hosts] fail in attempt to initialize it.

My question is, where is the point of being / not-being the VST plug-in? What do I have to do to make my common-.dll-file stand as VST?

I have read somewhere, that InitModule() bool method is called when the library is loaded [and DeinitModule() when unloaded], are there any rules like this one which are enough to follow?

 

Thanks a lot for the answer

Dix

May 26, 2011 at 8:08 AM
Edited May 26, 2011 at 8:12 AM

Hi Dix,

Assuming you want to use VST.NET plugin framework, I suggest you start with the Delay sample plugin, or use the VS2008/2010 project template to create a new audio plugin project. Call your FFT logic from the Process method of the audio processor and output the midi calling the ProcessEvents on the Host reference. Start your custom UI using the plugin editor class, optionally using the WinFormsControlWrapper class.

Important to note is that the Audio buffers in a VST plugin contain sample data for one channel (so for stereo you get 2 buffers) and use floats in the [-1, 1] value range. So you may have to convert the incoming audio before passing it to your custom processing logic.

If all these calls can be made into your custom dll (you expose the API for it), it'll be a simple matter of glueing them in the plugin framework. Make sure you deploy your custom dll along side of the dlls VST.NET produces for the plugin. Open de [myplugin].dll in the host and you should be up and running.

Hope it helps,
Marc

PS: If you get the hang of it, you might also try to implement it without using the VST.NET plugin framework. Take a look at the CorePlugin sample on how to do that. It takes away the overhead of the plugin Framework but leaves you in charge of implementing all the VST interfacing details.

May 26, 2011 at 4:18 PM

ObiWan, thank you for your rapid answer!

I'm going to try that immediately. My app hasn't used VST.NET libraries until now, originally the question was meant for the cases with no plugin, if it is possible to write into the code some more lines which make it VST-compatible, because I actually still don't know where is the fundamental essence of 'being VST'.

Maybe I'll find the answer inside the CorePlugin sample.

My input stream provides data for one channel - those are doubles from <-1;1> range, output should be the MIDI stream into the host app. So this perhaps brings no more problems.

Thanks! ... Going to notify again after having a look.

Dix

May 28, 2011 at 2:18 AM

Hello out there again, I'm back with new experiences...

CorePlugin is exactly what I was looking for. Now it is possible just to fill its content with my stuff [I hope].

When I did this for the first time, plugin was able to be loaded by the host [FL Studio in this case - Cubase seems to behave very specifically as I have realized from other threads in this discussion] but showed no GUI. The problem was in using 'Windows form' instead of 'User control' like you in your CorePlugin sample, so this was solved too.

Now I have a few seconds to relocate my work here and try to debug it. When I meet some unsolvable problem, I'm gonna shout for help again... Otherwise I will refer the success.

However, I'd like to thank you very very much, Obiwan, this VST.NET is wonderful project and you are very helpful in giving this assistance with a big patience and also very fast. My respect!

Dix

May 28, 2011 at 8:14 AM

Hello,

I copiead all the code into the project based on CorePlugin sample. It seemed to be working fine [tested in VSThost] until I applied some .dll referencies out from the Jacobi's namespace. Since then, I'm still getting an error called

System.Reflection.TargetInvocationException at System.Runtime.CreateInstance ... Inner exception: System.IO.FileNotFoundException: Could not load file or assembly or one of its dependencies. The system cannot find the file specified.

I tried to put that [those] dll into the same directory as my plugin, even to system32 dir, but with no effect. Where am I missing something?

Thanks

Dix

May 30, 2011 at 9:11 AM
Edited May 30, 2011 at 9:12 AM

Does it say what the file name is of the assembly that cant be loaded?

Are you sure "System.Runtime.CreateInstance" is correct? Or is it System.Runtime.Activator.CreateInstance ??

Do you do the standard renaming of the assemblies? Take a look in the post build events in the project file of one of the samples.

Rename Jacobi.Vst.Interop to [MyPlugin].dll and the .net assembly of you plugin to [MyPlugin].net.vstdll. Deploy all these assemblies as well as the Jacobi.Vst.Core assembly (and optionally the Jacobi.Vst.Framework assembly) to the same folder and it should work.

See also http://vstnet.codeplex.com/wikipage?title=Using%20VST.NET (note that deployment to the GAC is not a requirement anymore)

May 31, 2011 at 7:16 AM

Hello,

I realized that VSThost looks for all the referenced libraries into its directory (e.g. C:/VSThost/) only and not into the directory where plugin is. So this problem has been solved with copying them in here.

In VSThost, everything is working correctly now, which makes me suppose it IS correctly written VST plugin.

But none of the attempts to load it inside some DAW (tried at Cubase, FL Studio and Reaper as well) led to the success.

In the reaction to your last post, I have followed getting-started part from your documentation, as to the post build events (Plugin.dll and Plugin.net.vstdll that's what I have) and it is also deployed to the Core assembly (not using Framework) which I always put together into the same directory.

Unlike VSThost, other DAWs don't send me any error message, they just freeze while loading or even can't see this file in the directory, so I have no idea where the mistake could be.

Is it possible to send you the project or only some classes via mail?

Well, looking at the article you linked, I am not sure about my plugin's IVstPluginCommandStub implementation, if there is one. Unfortunately I'm not with the code now, I'll have a look in few hours.

Thank you very much, Obiwan!

 

Dix

Jun 1, 2011 at 5:29 AM

In addition: Yes, there is an implementation of IVstPluginCommandStub from PluginCommandStub class.

Jun 1, 2011 at 8:36 AM
Edited Jun 1, 2011 at 8:37 AM

VST.NET supports version before VST 2.4 in the Deprecated namespace (Core). Note that Cubase queries the plugin for olders methods (Specifically the Identify method). You can implement these methods by implementing the IVstPluginCommandsDeprecated20 in the same class the IVstPluginCommandStub is implemented (refer to Framework Plugin namespace for an example of how to implement it).

When you cannot see any errors you can always try to debug the plugin while its in the host. Start the host, attach the VS debugger to the host process and then load the plugin. Note that most hosts instantiate the plugin when it startsup, just to discover its properties, so you want to find a way to activate the plugin after you've attached your debugger.

You can send me your code to obiwanjacobi at hotmail dot com. But I cannot make any promises on when I will be able to comment on it.

Hope it helps.
Marc

Jun 6, 2011 at 2:03 PM

Hello Obiwan!

I actually still don't understand why it does what it does, but due to today's deadline I can't try anything else in this project, maybe someday in the future. I tried a lot and the only thing which made the hosts (FLStudio and Reaper) accept, load and initialize my plugin was to copy all the referenced dlls into the application's work directory [C:/Program Files/REAPER and C:/Program Files/Image-Line/FL Studio 9]. I guess there is some reason written down in my code why they look for it into their own dirs and not into the plugin's dir, but I have no idea what is that.

Thanks a lot for all your help, I would have achieved nothing without it. Next time, I'm gonna build it on VST.NET only, with no other references, hoping in better results.

Have a nice time!

Dix

Feb 13, 2012 at 3:51 PM

Hi DixQ, Hi Obiwan!

When I came across this topic i realised that I am building the same plugin as DixQ (Voice to MIDI).

I was searching for an answer to same problem that DixQ had.

When i use other assemblies (my own WPF controls) and I put all of them in VstPlugins directory along with the plugin i got the same error:

System.Reflection.TargetInvocationException at System.Runtime.CreateInstance ... Inner exception: System.IO.FileNotFoundException: Could not load file or assembly or one of its dependencies. The system cannot find the file specified.

When i put my custom .dll's in Host's directory (in my example FlStudio 10) there is no error displayied. 

I don't understand why: Jacobi.Vst.Core.dll, Jacobi.Vst.Framework.dll, Jacobi.Vst.Interop need to be in VstPlugins directory and other .dll's in main Host directory.

I wish to be able to put all of the .dll's in one directory, so that in VstPlugins would be only C++ to C# renamed wrapper and rest of dlls (along with plugin written in C#) in other place. I know that Obiwan designed the wrapper to search for plugin file in the same directory and similar name, but my point is to make plugin that could be "installed" on others users machines which don't own Cotre.dll, Framework.dll and Interop.dll in GAC but have .NET 4.0 installed and put only one .dll to VstPlugins like all VST plugins does.

I need some help with that.

Thanx in advance,

Tomek

Feb 13, 2012 at 6:09 PM
Edited Feb 13, 2012 at 6:11 PM

The installation of the Core and Framework dlls in the GAC is no longer necessary. All assemblies should be installed in the same folder (point the host towards this folder to load the plugin). Note that for a plugin, Interop is NOT needed. You have renamed interop to your plugin name and point the host towards this dll, it does not need to be distributed under its original name. (Host applications that use the VstPluginContext do need to distribute this dll using its original name).

As an extra option, VST.NET allows a plugin configuration file (.config) to be deployed as well. This config can contain a vstnetProbePaths app-setting that points to other folders (semi-colon separated) that will be used to resolve dependent assemblies. The WrapperPlugin sample uses a plugin configuration file (to store the path to the plugin it wraps).

However, these mechanisms were only tested using a stand-alone plugin assembly. So the managed plugin assembly itself had no (custom) dependencies. I suspect that there is a bug in the loading code in the scenario where the managed plugin assembly has custom dependencies of its own.

I am very busy right now, but I will try to test is this is the case.

If anyone has any additional information that is related to this issue, please post it here.

Thanx for your patience.
Marc. 

Feb 13, 2012 at 7:07 PM

Ok, I threw together a quick test plugin using the Visual Studio solution/project templates and a normal class library (set to .net2). Referenced the library from the plugin project and added a dummy class to the library with a property.

Next I added a default ctor for the PluginCommandStub and in the ctor newed up an instance of the class out of the library and assigned a value to the property.

Used a DEBUG build (so code optimization will not remove my bogus test code ;-) and pointed vsthost.exe towards my bin directory that contains all the assembly files. Attached my debugger to vsthost.exe before loading the plugin so any load exceptions (early in the plugin life cycle) would be caught.

Vsthost.exe had no problem opening an instance of my test plugin and both the custom UI and the host generated UI worked. The plugin was loaded correctly.

 

So, if you keep having trouble with managing dependencies I need a little more information to get to the bottom of it. Perhaps a scaled down version of the project you actually work on (I promise I will not steal your code ;-).

Hope it helps.
Marc. 

May 7, 2012 at 7:52 PM
Edited May 7, 2012 at 8:56 PM
obiwanjacobi wrote:

Next I added a default ctor for the PluginCommandStub and in the ctor newed up an instance of the class out of the library and assigned a value to the property.

Used a DEBUG build (so code optimization will not remove my bogus test code ;-) and pointed vsthost.exe towards my bin directory that contains all the assembly files. Attached my debugger to vsthost.exe before loading the plugin so any load exceptions (early in the plugin life cycle) would be caught.

Vsthost.exe had no problem opening an instance of my test plugin and both the custom UI and the host generated UI worked. The plugin was loaded correctly.

I think I don't understand what you did there. Especially by "pointing vsthost.exe towards your bin directory".

I am using WPF for GUI (all GUI is in WPF-based separate .dll). That file with GUI has to be in the host executable directory. Also Microsoft.Expression.Drawing.dll is needed there too. Only my plugin.net.vstdll and renamed interop are in the true VSTPlugins directory. Right now i tried to merge it all with ILMerge program but some exceptions were thrown during merging and it failed.

If you could tell me bit simplier what did you do to make it work....

I want to put all files in VSTPlugins directory. But it would be even better to merge them all into one .dll (excluding renamed interop [it can't be merged as far as i know])

------ edit -------------

I tried to make one assembly with my VST effect and WPF GUI. I used SmartAssembly 6 trial because ILMerge can't merge WPF files :(. I think SmartAssembly managed to merge my dll's into one, but somehow i get the biggest error window i ever seen when i try to load my VST. It says there that host can't find things in GUI's dll (which is MERGED!) in HOST! directory (but the merged DLL is in VSTPlugins). It's very strange... and I don't get it

May 8, 2012 at 6:29 AM

ILMerge will not merge CLI assemblies (one of the first things I've tried ;-)

Anyway here are the steps to test and debug your plugin in vsthost.exe (by Hermann Seib).

- (Re)Build your entire project. Make sure all binaries are in the project's bin folder.
- Start vsthost.exe
- Optionally attach Visual Studio to the running instance of vsthost.exe.
- Choose Load Plugin (File Menu I believe) and browse to your project's bin folder and select the [myplugin].dll assembly (the renamed interop assembly).
- You should now be ably to break into any debug breakpoint you have set.
- Close all plugins before exiting vsthost.
- Restart vsthost.exe for each run (provides you with a clean memory space) otherwise you might be chasing ghosts.

Hope it helps,
Marc

May 8, 2012 at 11:04 AM

Thank you for your quick reply.

I tried vsthost.exe but it can't open my VST at all... there are alot of index out of range exceptions in my audio processing function (which is strange because i have already tested my plugin in real host (FL Studio) and it worked pretty well http://www.youtube.com/watch?v=b40od5GsFsI ). And when i try to show the GUI, vsthost.exe breaks down...

I will try to build delay-example-based simple vst with WPF gui and check again...

But there were exceptions with missing .dll's too. (i had to copy them to vsthost.exe directory just like in FL studio case, but vsthost.exe couldn't handle it after all...)

Maybe it's because of my custom build .NET 4 compatibile of your library?

May 10, 2012 at 8:05 AM

The 0.9 release binaries are .NET 2.0. (for now) you have to build your own .NET (Clr) 4 binaries. If you download the source code you'll find .cmd files that will build a Clr 4 version for you. Be sure to read this

http://vstnet.codeplex.com/wikipage?title=Building%20the%20Source%20Code

and this

http://vstnet.codeplex.com/wikipage?title=Build%20Configurations

first.

Hope it helps,
Marc