VST plugins .net host

Jan 4, 2010 at 8:09 PM

Hello.

At first I must say that vst.net is a great idea. In a quite short time I was able to create my own plugin without crushing into VST SDK c++ code making creepycrawler interopability to .Net. I was also able to run VST.NET samples with Cubase and Wavelab as well.

For now, I would like to create a host for VST plugins. I used Jacobi.Vst.Samples.Host project as a starting point. In general I succeeded, with some issues.

First problem is, when using unmanaged (factory) plugins, EditorGetRect function allways returns false and rectangle I get is zero in width and height. With demo plugins (Jacobi.Vst.Samples.CorePlugin) it returns true with valid rectangle.

Second problem is, when using plugin with two inputs and two outputs (stereo->stereo), output samples (extracted from VstAudioBuffer of VstAudioBufferManager) are the same on all two channels. As I can see from level meters of factory (unmanaged) plugins, plugin receives and outputs correct samples but retrieving of output samples fails.  To be more precise: if I create simple 2-in 2-out plugin that just passes input samples to outputs I get the following result: ch1 input sample = 0.5, ch2 input sample = -0.3 --> ch1 output sample = -0.3, ch2 output sample = -0.3, instead of 0.5 and -0.3. The same plugin works correct in WaveLab.

unmanaged (factory) VST plugins used: TC Native Reverb VST v2.03 and Classic Delay from Kjaerhus Audio

Am I doing something wrong or...?

Thanks in advance.

Coordinator
Jan 5, 2010 at 6:10 AM

Good to hear that you were able to create a plugin in a short time. I hope it was an easy experience.

EditorGetRect: I have to look into that. I've noticed that some 'functions' return 0 (zero) even when completing correctly. So I will have to test if this is one of those odd cases. The code checks the return value and only when non-zero is returned, is the rectangle copied thru. So that could be the problem. That would be easy to fix tho.

AudioBufferManager: Do you use one buffer manager for input and one for output (two in total)? I will look into this also and use the Host sample to do some testing.

In short: I get back to you on these items. When I have a fix I will checkin the code so you can use it in your projects.

Thanx for using VST.NET and posting your questions.

Marc

Jan 5, 2010 at 7:50 AM

Hello, and thanx for fast reply.

AudioBufferManager: I use one for input and one for output - two in total.

During looking at samples project I also noticed one thing (that is not related to my problems described in the first post): At Jacobi.Vst.Samples.Host project at rotine PluginForm.GenerateNoiseBtn_Click there were crashes with some unmanaged (factory) plugins (TC Native Reverb) because sample rate is set to 44.1 instead to 1000 times greater 44100.

An

Coordinator
Jan 6, 2010 at 9:30 AM

Checkout the latest source code. I've added a little to the Process Noise method. It attempts to detect if a plugin processes audio (changes it) or just passes it through. The sample plugins report the expected behavior, so please recheck your findings. Also fixed the sample rate.

Hope it helps.

Jan 6, 2010 at 11:22 AM

Hello Marc,

I downloaded the latest source code using SVN. I have troubles building it. At the very beginning of compiling of Jacobi.Vst.sln (source) I get 3 errors: Error 1 Source file 'D:\_AssemblyInfo\AssemblyInfo.General.cs' could not be opened ('Unspecified error ') at Jacobi.Vst.Core, Error 2 Metadata file 'D:\VST\Source\Code\Jacobi.Vst.Core\bin\Debug\Jacobi.Vst.Core.dll' could not be found at Jacobi.Vst.Framework, Error 3 fatal error C1192: #using failed on 'd:\vst\source\code\jacobi.vst.core\bin\debug\jacobi.vst.core.dll' d:\VST\Source\Code\Jacobi.Vst.Interop\stdafx.cpp 1 Jacobi.Vst.Interop.

Is it possible to find out what is wrong? There is quite a lot of code so setting up solution and projects from the zero point could take quite a lot of time. I use Visual Studio 2008 Proffesional Edition.

Thanx in advance

Coordinator
Jan 6, 2010 at 11:32 AM
Edited Jan 6, 2010 at 5:42 PM

Follow the instrcutions on the main wiki page. ;-)

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

There are some files that are not in source control (on purpose) that are private to an official build. This is important for the license.

You can basically remove all files that aren't found from the project files.

Jan 6, 2010 at 12:25 PM

Hello,

At first I apolgise for bugging around compiling the code. Missed the instructions :). So I built up the code (noticed the CanDo(string cando) instead of CanDo(VstHostCanDo cando) in my derived host command stub implementation... But I noticed no change. Output rectangle of EditorGetRect is still zero in size and i get non-stereo output from 2 channel reverb plugin (TC Native Reverb VST v2.03 and Classic Delay from Kjaerhus Audio). Level meters on editor clearly shows non identical L/R audio material on inputs and outputs.

Thanx in advance

Jan 6, 2010 at 12:54 PM
Hello again,
Am I figuring something wrong? If I do, than that could be the reason for my problems. I think the following code snippet shold in any case show message box, but it doesn't.
            inputCount = 2;
            blockSize = 1024;
            VstAudioBufferManager inputMgr = new VstAudioBufferManager(inputCount, blockSize);
            VstAudioBuffer[] inputBuffers = inputMgr.ToArray();
            Random rnd = new Random();
            for (int j = 0; j < blockSize; j++)
                inputBuffers[0][j] = (float)((rnd.NextDouble() * 2.0) - 1.0);
            for (int j = 0; j < blockSize; j++)
                inputBuffers[1][j] = (float)((rnd.NextDouble() * 2.0) - 1.0);
            for (int j = 0; j < blockSize; j++)
            {
                if (inputBuffers[0][j] != inputBuffers[1][j])
                {
                    MessageBox.Show("STEREO!");
                }
            }
Tnx in advance again.
Coordinator
Jan 6, 2010 at 1:09 PM

Hmm, the code looks ok. And you should indeed see the messagebox. There might be a bug in the buffer manager.

If you cast both audio buffers in the array to the IDirectBufferAccess32 interface, you can compare the unmanaged buffer pointer values. They should be different.

I will try this when I get home, tonight.

You can try to see what happens to the second audio buffer when you write into the first in a debug session. My hunch is that the pointer arithmetic inside the buffer manager is not correct. The buffer manager allocates one piece of unmanaged memory (buffer count * buffer size) and sub-devides it into chunks (buffer size) and each chunk is managed by one instance of the VstAudioBuffer.

I would not trust what a plugin shows on its UI to draw any conclusions from that. Better is to set a debug break point in the code and look at the values of the buffer directly.

BTW: I hadn't fixed the GetEditorRect yet ;-)

Jan 6, 2010 at 1:59 PM

The pointer values ar the same... I agree that any conclusions from plugin's UI could easily be misleading... I try things with numbers of course as stated in my first post. I use TC Native Reverb VST v2.03 for several years and I trust to it.

Thanx in advance

Coordinator
Jan 6, 2010 at 2:48 PM

Just checked in a fix for the buffer manager. The first two instances were using the same memory.

Please try it and let me know if this works for you.

(in the meantime I will work on the EditorRect ;-)

Jan 6, 2010 at 4:39 PM

Hello!

It works fine now! Stereo IN -> Stereo OUT

Tnx Marc a lot!

Coordinator
Jan 6, 2010 at 5:41 PM

Good!

Also get the latest source code (again). Just checked in a fix for GetEditorRect and extended the Host sample to show the Plugin editor UI.

Hope it helps.

Jan 6, 2010 at 10:22 PM

Hello Again!

After latest svn update everything works FINE now. Thank You again for fast response and for wonderful VST framework. For now, all I have to do is list/read/write effect parameters and programs (create .fxp file) and VST host is born. I hope I wasn't  to annoying with my questions and that I can post them in future also.

An

Coordinator
Jan 7, 2010 at 7:02 AM
Edited Jan 7, 2010 at 7:02 AM

You are always welcome to ask your VST.NET question here (and they're not annoying ;-).
You even found some bugs and we fixed them. So that is always good.

Good luck with your project.

Jan 7, 2010 at 8:44 AM

Hello!

I have one question (hope I haven't missed something written about that here)... I cannot load Jacobi.Vst.Core.dll and Jacobi.Vst.Framework (built from latest source code) into GAC. I get the message, that assemblies must be strongly named. I think this is related to unchecked signing of assemblies in project properties. Loading into GAC is required for WaveLab or Cubase to accept managed plugins. Using built and signed assemblies from VST.NET 0.8 Samples VS2008 Express (download) is no longer compatible to the latest source code --> CRASH.

An

Jan 7, 2010 at 9:29 AM

Hello again!

If I may I would recommend one thing that would be helpful for less-enthusiastic developers... Demo project Jacobi.Vst.Samples.CorePlugin is very useful as it writes out how host app deals with plugin and from that we learn... I noticed that some plugins have their own GUI "pump" for indicators (level meters, etc.) and some not. And those require EditorIdle() method to be invoked from host-side in order to refresh. From that point of view, it would be helpful that you add Log method inside empty procedure EditorIdle(). That would then clearly show what is going on. For the reason noted in the latest post I was not able to test if that works or causes deadlock.

An

Coordinator
Jan 7, 2010 at 9:36 AM
Edited Jan 7, 2010 at 9:39 AM

The key file that is needed to sign your assembly so it can be placed in the GAC is one of those files that is not in Source Control (private to me). You do not need to deploy the Core and Framework assemblies in the GAC (place them next to your plugin assemblies), but if you have to, you just create your own key file and include that in the projects and rebuild.

One of the new features of VST.NET 0.8 is that it supports tracing of all interop calls. Refer to the app.config file of the Interop assembly or the Host sample. Basically you can declare trace listeners and trace level switches for a plugin (by name). Dependent on how you route these trace you could use DebugView.exe (search for it online, by sysinternals/microsoft) to show these traces. If you want to see editor idle, look for "effEditorIdle". You can also see the parameters and the return value in the trace.

Hope it helps.