Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

VSTs with changing number of inputs/outputs #43

Open
Boscop opened this issue Apr 26, 2018 · 3 comments
Open

VSTs with changing number of inputs/outputs #43

Boscop opened this issue Apr 26, 2018 · 3 comments

Comments

@Boscop
Copy link
Member

Boscop commented Apr 26, 2018

Do we want to support VSTs with changing number of input/output channels?

The VST standard allows that and these exist (but they are very rare).

I don't have any demand for this feature myself, and I think there are more pressing issues to work on right now, but we should be aware of this, and maybe make a decision.

For now I think we can just not support it until someone needs it (probably a long time).

(The VST standard also allows shell plugins, which this crate also doesn't fully support atm, but they are also very very rare and I'm not sure about their details.)

@askeksa
Copy link
Contributor

askeksa commented Apr 27, 2018

I would be interested in such a feature, in theory. I wanted to have that (number of inputs depending on configuration of the individual VST instance) in my MetaSynth: https://github.com/askeksa/MetaSynth

However, my experience is that hosts can't be expected to support it. In Renoise at least, plugins are characterized as either instruments or effects when they are first loaded, depending on the number of inputs. These end up in two entirely different lists in the Renoise UI.

For MetaSynth, I ended up building two separate VSTs which are identical apart from the number of inputs and the IsSynth flag.

Is there perhaps some specific communication that needs to happen with the host to change the number of inputs/outputs?

@Boscop
Copy link
Member Author

Boscop commented Apr 28, 2018

Yes, there is audioMasterIOChanged / AudioEffectX::ioChanged:

//-------------------------------------------------------------------------------------------------------
/** VST 2.x dispatcher Opcodes (Plug-in to Host). Extension of #AudioMasterOpcodes */
//-------------------------------------------------------------------------------------------------------
enum AudioMasterOpcodesX
{
//-------------------------------------------------------------------------------------------------------
	DECLARE_VST_DEPRECATED (audioMasterWantMidi) = DECLARE_VST_DEPRECATED (audioMasterPinConnected) + 2,	///< \deprecated deprecated in VST 2.4

	audioMasterGetTime,				///< [return value]: #VstTimeInfo* or null if not supported [value]: request mask  @see VstTimeInfoFlags @see AudioEffectX::getTimeInfo
	audioMasterProcessEvents,		///< [ptr]: pointer to #VstEvents  @see VstEvents @see AudioEffectX::sendVstEventsToHost

	DECLARE_VST_DEPRECATED (audioMasterSetTime),	///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterTempoAt),	///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterGetNumAutomatableParameters),	///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterGetParameterQuantization),		///< \deprecated deprecated in VST 2.4

	audioMasterIOChanged,			///< [return value]: 1 if supported  @see AudioEffectX::ioChanged

	DECLARE_VST_DEPRECATED (audioMasterNeedIdle),	///< \deprecated deprecated in VST 2.4
	
	audioMasterSizeWindow,			///< [index]: new width [value]: new height [return value]: 1 if supported  @see AudioEffectX::sizeWindow
	audioMasterGetSampleRate,		///< [return value]: current sample rate  @see AudioEffectX::updateSampleRate
	audioMasterGetBlockSize,		///< [return value]: current block size  @see AudioEffectX::updateBlockSize
	audioMasterGetInputLatency,		///< [return value]: input latency in audio samples  @see AudioEffectX::getInputLatency
	audioMasterGetOutputLatency,	///< [return value]: output latency in audio samples  @see AudioEffectX::getOutputLatency

	DECLARE_VST_DEPRECATED (audioMasterGetPreviousPlug),			///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterGetNextPlug),				///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterWillReplaceOrAccumulate),	///< \deprecated deprecated in VST 2.4

	audioMasterGetCurrentProcessLevel,	///< [return value]: current process level  @see VstProcessLevels
	audioMasterGetAutomationState,		///< [return value]: current automation state  @see VstAutomationStates

	audioMasterOfflineStart,			///< [index]: numNewAudioFiles [value]: numAudioFiles [ptr]: #VstAudioFile*  @see AudioEffectX::offlineStart
	audioMasterOfflineRead,				///< [index]: bool readSource [value]: #VstOfflineOption* @see VstOfflineOption [ptr]: #VstOfflineTask*  @see VstOfflineTask @see AudioEffectX::offlineRead
	audioMasterOfflineWrite,			///< @see audioMasterOfflineRead @see AudioEffectX::offlineRead
	audioMasterOfflineGetCurrentPass,	///< @see AudioEffectX::offlineGetCurrentPass
	audioMasterOfflineGetCurrentMetaPass,	///< @see AudioEffectX::offlineGetCurrentMetaPass

	DECLARE_VST_DEPRECATED (audioMasterSetOutputSampleRate),			///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterGetOutputSpeakerArrangement),	///< \deprecated deprecated in VST 2.4

	audioMasterGetVendorString,			///< [ptr]: char buffer for vendor string, limited to #kVstMaxVendorStrLen  @see AudioEffectX::getHostVendorString
	audioMasterGetProductString,		///< [ptr]: char buffer for vendor string, limited to #kVstMaxProductStrLen  @see AudioEffectX::getHostProductString
	audioMasterGetVendorVersion,		///< [return value]: vendor-specific version  @see AudioEffectX::getHostVendorVersion
	audioMasterVendorSpecific,			///< no definition, vendor specific handling  @see AudioEffectX::hostVendorSpecific
	
	DECLARE_VST_DEPRECATED (audioMasterSetIcon),		///< \deprecated deprecated in VST 2.4
	
	audioMasterCanDo,					///< [ptr]: "can do" string [return value]: 1 for supported
	audioMasterGetLanguage,				///< [return value]: language code  @see VstHostLanguage

	DECLARE_VST_DEPRECATED (audioMasterOpenWindow),		///< \deprecated deprecated in VST 2.4
	DECLARE_VST_DEPRECATED (audioMasterCloseWindow),	///< \deprecated deprecated in VST 2.4

	audioMasterGetDirectory,			///< [return value]: FSSpec on MAC, else char*  @see AudioEffectX::getDirectory
	audioMasterUpdateDisplay,			///< no arguments	
	audioMasterBeginEdit,               ///< [index]: parameter index  @see AudioEffectX::beginEdit
	audioMasterEndEdit,                 ///< [index]: parameter index  @see AudioEffectX::endEdit
	audioMasterOpenFileSelector,		///< [ptr]: VstFileSelect* [return value]: 1 if supported  @see AudioEffectX::openFileSelector
	audioMasterCloseFileSelector,		///< [ptr]: VstFileSelect*  @see AudioEffectX::closeFileSelector
	
	DECLARE_VST_DEPRECATED (audioMasterEditFile),		///< \deprecated deprecated in VST 2.4
	
	DECLARE_VST_DEPRECATED (audioMasterGetChunkFile),	///< \deprecated deprecated in VST 2.4 [ptr]: char[2048] or sizeof (FSSpec) [return value]: 1 if supported  @see AudioEffectX::getChunkFile

	DECLARE_VST_DEPRECATED (audioMasterGetInputSpeakerArrangement)	///< \deprecated deprecated in VST 2.4
};
/*!
	The Host could call a suspend() (if the plug-in was enabled (in resume() state)) and then ask for 
	getSpeakerArrangement() and/or check the \e numInputs and \e numOutputs and \e initialDelay and then call a 
	resume().

	\return \e true on success

	\sa setSpeakerArrangement(), getSpeakerArrangement() 
*/
bool AudioEffectX::ioChanged ()
{
	if (audioMaster)
		return (audioMaster (&cEffect, audioMasterIOChanged, 0, 0, 0, 0) != 0);
	return false;
}
<a class="anchor" name="fd1663ca60afd2f9b7288d10004cf575"></a><!-- doxytag: member="AudioEffectX::ioChanged" ref="fd1663ca60afd2f9b7288d10004cf575" args="()" -->
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool AudioEffectX::ioChanged           </td>
          <td>(</td>
          <td class="paramname">          </td>
          <td>&nbsp;)&nbsp;</td>
          <td width="100%"><code> [virtual]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
Tell Host numInputs and/or numOutputs and/or initialDelay (and/or numParameters: to be avoid) have changed. 
<p>
The Host could call a <a class="el" href="class_audio_effect.html#a60d4dddc772c46cf20ee3552230e36a">suspend()</a> (if the plug-in was enabled (in <a class="el" href="class_audio_effect.html#83eca400d6a8cb044139c5c8e196505b">resume()</a> state)) and then ask for <a class="el" href="class_audio_effect_x.html#bdc7ed0ea2ae1c8c3fdb419d803309ff">getSpeakerArrangement()</a> and/or check the <em>numInputs</em> and <em>numOutputs</em> and <em>initialDelay</em> and then call a <a class="el" href="class_audio_effect.html#83eca400d6a8cb044139c5c8e196505b">resume()</a>.<p>
<dl compact><dt><b>Returns:</b></dt><dd><em>true</em> on success</dd></dl>
<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="class_audio_effect_x.html#eb17011a1b4cdef8e089353aa1449b90">setSpeakerArrangement()</a>, <a class="el" href="class_audio_effect_x.html#bdc7ed0ea2ae1c8c3fdb419d803309ff">getSpeakerArrangement()</a> </dd></dl>

@zyvitski
Copy link
Member

I think this would be worth implementing. It would enable support for side-chain processing.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants