VST3 SDK returns wrong channel count on duplicating track

We develop a plugin that compiles the VST SDK to support both VST2 and VST3 hosts. We are noticing a potential bug in VST3 hosts (Cubase/Nuendo) with the following reproducing steps:
i) create an audio track with stereo configuration/stereo out routing
ii) instantiate plugin on the track, during our plugin init sequence we query for the channel count and for this plugin instance we get 2
iii) duplicate the track

Result: when the new duplicate track is created, it instantiates a new object of our plugin and runs its init sequence. During this init sequence, when we query for the channel count of the track, it returns 1 (mono) even though both the original and duplicated tracks are stereo, and in the init sequence of the original track, the query for the channel count returned 2.

Here is how we query for the channel count during init:

Steinberg::Vst::SpeakerArrangement speakerArr;
if (getBusArrangement(Steinberg::Vst::kOutput, 0, speakerArr) != Steinberg::kResultTrue)
return 0;
return Steinberg::Vst::SpeakerArr::getChannelCount(speakerArr);

Is this the correct way to query for the channel count for a plugin instance on a duplicated track?

We are using Cubase 9 for the testing.

Thanks,
Hari

Hi Hari,
you cannot query the host for channel configurations.
The host will try to set the channel configuration on your plug-in via a call to setBusArrangements ().

Cheers
Arne

Hi Arne,

Is there any way to differentiate during plugin init between duplicated tracks and restored tracks? I see setState() being called in both cases, but there doesn’t seem to be a way to differentiate at that point whether this is being called on a duplicated track or on a restored track.

Thanks,
Hari

Hi Hari,
what is your use case that you need to know the difference if your plug-in is duplicated or restored ?

Cheers
Arne

Hi Arne,

Our plugin has unique left and right channel assignments for a multichannel output that are set to default values when each plugin is instantiated. This channel assignment is different from the audio routing in the host, we use the plugin internal channel assignment to write panning metadata.

For example, if 2 plugins are instantiated on the same track or 2 different tracks, the channel assignments will be defaulted to:
1+2
3+4

However, the user also has the ability to change these channel assignments to anything they like, eg:
7+2
5+4

We also do not allow 2 plugin instances to have the same channel assignment.

When we duplicate a track currently, we restore the plugin session because setState() is called just like when a session is restored. Hence, we try to assign the channel assignment of the plugin in the duplicate track to be the same as that of the plugin in the original track (based on the session chunk data)- this is bad behavior. We would instead like to assign to the next available channel ID in this scenario. However, this exact same call sequence happens when a session is restored and in that case we don’t want to be assigning to the next available channel ID but instead to the ID that was saved in the session chunk data.

This is why we will need to differentiate between a plugin that is duplicated vs restored.

Thanks,
Hari

Hi Hari,
you can try to use IStreamAttributes on the stream in setState() and check the PresetAttributes::kStateType. Maybe when a track is duplicated it is not set. See ivstattributes.h for an example on how to use this.

Cheers
Arne

Thanks Arne, I will check it out!