This project has moved. For the latest updates, please go here.

GetProgramNameIndexed

Sep 18, 2010 at 9:22 AM

Hello Marc, I'm back, finished 2 projects and started 3 new ones...

In free time I'm currently working on a custom VST host, and I would like to create Load/Save program and Load/Save program bank functionality. I noticed, that with some plugins GetProgramNameIndexed(int index) function returns empty strings while GetProgramName() returns correct value.

However I can still list all program names, if I at first set program at given index and then with GetProgramName() obtain program's name. The "problematic" plugin is (like allways) "TC Native Reverb VST", but with other hosts I have, it openes flawless. Is there anything (I'm doing wrong/you can look after) about this issue?

Regards, an

Sep 18, 2010 at 9:35 AM

I forgot to mention; I'm using vstnet-48968.

Regards, an

Sep 18, 2010 at 2:43 PM

Hello again, 2 more questions:

1. question is related to parameter properties;

        private void showParametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (vstPluginContext != null)
            {
                IVstPluginCommandStub pcs = vstPluginContext.PluginCommandStub;
                int n = vstPluginContext.PluginInfo.ParameterCount;
                VstParameterProperties vpp;
                string parameterName;
                for (int i = 0; i < n; i++)
                {
                    parameterName = pcs.GetParameterName(i);
                    vpp = pcs.GetParameterProperties(i);
                    if (parameterName == null || parameterName == "")
                        MessageBox.Show("Empty or null parameter name!", "Error!");
                    if (vpp == null)
                        MessageBox.Show("Null parameter properties!", "Error!");
                }
            }
        }

If I run the following code vpp is always null no matter which plugin I use. Parameter name makes sense with some plugins while with others empty string is returned. VST Host (from Hermann Seib) displays parameters correctly with all test plugins.

2. Question is related to saving vst parameters (to .fxp file);

        private void savePresetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (vstPluginContext != null)
            {
                if (savePresetDialog.ShowDialog() == DialogResult.OK)
                {
                    byte[] buffer = vstPluginContext.PluginCommandStub.GetChunk(true);
                    if (buffer == null)
                        MessageBox.Show("Buffer is null!", "Error!");
                    else
                    {
                        FileStream fs = new FileStream(savePresetDialog.FileName, FileMode.OpenOrCreate);
                        fs.Write(buffer, 0, buffer.Length);
                        fs.Flush();
                        fs.Close();
                    }
                }
            }
        }
If I run the following code, buffer I get is allways null no matter which plugin I choose.
Regards, an
Coordinator
Sep 19, 2010 at 1:12 PM
Edited Sep 19, 2010 at 1:16 PM

Hi An,

0) I'm not getting your first question (first message). What exactly is the problem? I understand that some plugins do not (correctly) implement the ByIndex method, its the last part I dont get.

Writing a host, you´ll find out that there is a lot of variance in implementation details across the various plugins. You sort of have to find a way that works for most while keeping to the intention of the specs a much as possible.

1) ParameterProperties is not something that every plugin would implement (unfortunatly). Assume a default value range for each parameter of [0.0, 1.0]. Please test this with the Delay Sample plugin to see if it works (that plugin implements the method). Please let me know if it doesn't - then we have a bug.

2) Thats not good (I assume it only happens with unmanaged plugins) . Can you set a breakpoint at the GetChunk in the source file. http://vstnet.codeplex.com/SourceControl/changeset/view/48968#343837
and check if the buffer is filled?

Thanx for bringing this to my attention and let me know how you do on these issues.

Hope it helps.

Marc

Sep 19, 2010 at 4:21 PM

Hello Marc,

My first question explanation:

To get the list of plugin programs I would do the following:

        /// <summary>
        /// Gets program names.
        /// </summary>
        /// <returns>Program names array.</returns>
        private string[] getAllProgramsNames()
        {
            string[] res = null;
            if (vstPluginContext != null)
            {
                int nProgs = vstPluginContext.PluginInfo.ProgramCount;
                res = new string[nProgs];
                IVstPluginCommandStub pcs = vstPluginContext.PluginCommandStub;
                for (int i = 0; i < nProgs; i++)
                    res[i] = pcs.GetProgramNameIndexed(i);
            }
            return res;
        }
But as I noticed GetProgramNameIndexed(int index) returns empty string with some plugins I've tested. To overcome this situation I did the the following:
        /// <summary>
        /// Gets program names.
        /// </summary>
        /// <param name="currentProgramIndex">Index of the current program.</param>
        /// <returns>Program names array.</returns>
        private string[] getAllProgramsNames(int currentProgramIndex)
        {
            string[] res = null;
            if (vstPluginContext != null)
            {
                int nProgs = vstPluginContext.PluginInfo.ProgramCount;
                res = new string[nProgs];
                IVstPluginCommandStub pcs = vstPluginContext.PluginCommandStub;
                for (int i = 0; i < nProgs; i++)
                {
                    pcs.SetProgram(i);
                    res[i] = pcs.GetProgramName();
                }
                pcs.SetProgram(currentProgramIndex);
            }
            return res;
        }
This works with all plugins I've tested, but is a little unpractical because of two reasons:
First is, I have to handle current program index in my code (to obtain state before function call).
Second reason is, that changing program (parameter values) can cause unexpected things with some plugins (transients or discontinuity in sound) and of course, unwanted cpu usage. Is there maybe better solution?
I tested the Delay Sample plugin like you suggested and it works fine, I can get parameter properties and also serialize parameters in .fxp file. Most my problems relate to hosting unmanaged plugins.
regards, an
Coordinator
Sep 20, 2010 at 6:51 AM
Edited Sep 21, 2010 at 6:29 AM

Hi An,

Like I said: programming a host is living with compromise. So I would make a routine like you've showed that uses the ByIndex method to retrieve the program names from the plugin. That routine should detect if its getting null or valid strings. Fall back to the second scenario if you do get nulls returned from the ByIndeex method. So you attempt to be most optimal, but if the plugin does not support it, fallback to blunt-force tactics. I dont see any other way (other than changing the requirement that needs this functionality in the first place).

Are you sure these plugins you test with support chunks? (assuming you didnt know this already) A host has two serialization mechanisms. One default way when the plugin does not support (need) custom serialization (chunks) and one when it does.
In the first scenario the Host just uses the parameter values published by the plugin to save its state. In the second you call Get/SetChunk (there is a flag set (ProgramChunks) on the plugin info when it supports it).

So check to see the plugins you're testing with have this flag set.

Hope it helps.

Marc

Sep 20, 2010 at 11:21 AM

Hi marc.

Sorry for bugging you, unmanaged plugins I tested don't support chunks. I get some strange flag values from them like 23 or 25. I also did not know about the two serialisation mechanisms; I taught vst plugins MUST strictly implement serialisation by itself. Now I know.

 

regards, an

Coordinator
Sep 21, 2010 at 6:31 AM

Remember that those flag-values are multiple flags bit-wise or-ed together.

So convert the value to binary (or Hex) so you can easily see what bits are set to 1. Then look those up in the VST SDK.

Hope it helps.

Marc

Sep 21, 2010 at 3:55 PM

Hi an,

I had similar problems with empty parameter names, if you haven't done it yet I suggest you rebuild the binaries from source instead of using the precompiled ones in the archive. It solved this problem along with many others in my case.

regards, Yury

Sep 21, 2010 at 4:31 PM

Hi,

@ YuryK:

I'm using vstnet-48968, I downloaded the source code and compiled it myself.

@ Marc:

Ooops, did not think of that... Tnx. Just general question:

If plugin does not support chunks, host is resposible to collect data and save it... Should be data stored in some "general" format or is format host dependent. I attached to Delay sample and I see how it formats (writes) data. Is that the way also my host should do it?

regards, kasaudio

Coordinator
Sep 21, 2010 at 5:57 PM

I dont know if there are any standard formats for writing that information. If there are, I suggest you use those. That way the user can transfer program settings between hosts.

If you choose to write it with a host-specific format you can choose anything you want.

VST.NET framework uses a binary format (not human readble) but you could also choose Xml and use the XmlSerializer to read and write it.

Hope it helps.

Sep 21, 2010 at 6:15 PM

Hi Marc, tnx for fast answer.

Again question about chunks... I have unmanaged VST plugin which has ProgramChunks flag set (reaeq-standalone.dll, minimal.dll). If I call GetChunk(true/false) I allways get null. Is that ok or not. Delay demo works fine...

effFlagsProgramChunks = 1 << 5; as I understand all plugins with flag value less than 32 will not support chunks.

This is how I get current program chunks in my code:

        /// <summary>
        /// Gets current program chunks.
        /// </summary>
        /// <returns>Byte array.</returns>
        private byte[] getCurrentProgramChunks()
        {
            if (vstPluginContext != null)
            {
                if ((vstPluginContext.PluginInfo.Flags & VstPluginFlags.ProgramChunks) == 0) // Chunks not supported.
                    return getCurrentProgramChunksByHost();
                else // Chuks supported.
                    return vstPluginContext.PluginCommandStub.GetChunk(true);
            }
            else
                return null;
        }
Looks OK or not?
regards, an
Coordinator
Sep 22, 2010 at 6:29 AM

Hmm, looks fine by me.

Correct: 1 << 5 == 32

You could try to set that breakpoint in the VST.NET code (http://vstnet.codeplex.com/SourceControl/changeset/view/48968#343837) and see if the buffer is filled. Perhaps the plugin returns zero but it does fill the buffer?

 

Sep 22, 2010 at 8:14 AM

Hello Marc,

another stupid question (I asked something simmilar in the past allready but it is a different case now). How to debug with unmanaged plugins - no breakpoint gets hit?

Im using Jacobi.Vst.Samples.Host.exe and Jacobi.Vst.sln. At first I start Host.exe, and then attach to Jacobi.Vst.Samples.Host.exe using Visual studio (Jacobi.Vst loaded). In the "Attach to" field I set Managed code, Native code. Then I set breakpoins (where you suggested in the last post), but nothing gets hit. What am I doing wrong? I compiled code and samples using Debug configuration.

regards an

Coordinator
Sep 26, 2010 at 9:37 AM

Yeah, sometimes the debugger doesn't 'take'. Make sure the project is freshly build. That will sometimes do the trick.

Sorry I can't help you further.