Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

This tutorial will explain you how to set up your computer and create an environment for developing VST3 audio plug-ins.

The artefact will be an audio plug-in that can compute a Gain to a audio signal and can be loaded into VST3 hosts like Cubase, Wavelab,...

Part 1: Get and install the VST3 SDK

For downloading the SDK see this section "How to setup my system in order to build VST3 plug-ins".

You have the different possibilities to start a new project:

  • you can use the helloworld template included in the VST SDK and duplicate the folder into a new folder and then adapt each file where comment mentions it.
  • or, which is easier and recommanded, you can use the VST3 Project Generator application included in the VST SDK in the tools folder.

Part 2: Use the VST3 plug-in Project Generator application

The VST3 Project Generator application included in the VST SDK in the tools folder is available for Windows and for MacOS.

Start the application.

In the Preferences tab you have to enter some information about your company, and some paths (if not already predefined).

In the Create Plug-in Project tab you have to enter some information about your plug-in you want create:

... (link to VST3 Project Generator documentation)

Then when all field have been filled, you could click on Create, a script is started which creates in the Output Directory a project with adapted files, after this step the IDE (Visual Studio or XCode) is launched.

You can then compile the project and test your newly created plug-in.

If you have choose Audio Effect as Type a simple Stereo→Stereo plug-in is created.

A good way to understand how a VST3 Plug-in works is to add breakpoints in each function in the processor and controller files :d

tresult PLUGIN_API MyPluginController::initialize (FUnknown* context);
tresult PLUGIN_API MyPluginController::terminate ();
tresult PLUGIN_API MyPlugin::initialize (FUnknown* context);

and start a VST 3 host from the debugger.

Part 3: Coding your plug-in

Now you have an automatically generated frame for your plug-in. In the following sections, it will be explained how to add a new parameter, its associated processing algorithm, and others specific features like saving/loading project or presets, create a dedicated User Interface,...

A VST3 Plug-in contains two main classes: its PlugProcessor (the main part doing the processing and persistence) and its PlugController (taking care of communication with the DAW, handling parameters and the UI).

Add a parameter: Gain

In this basic Plug-in example, we will add a Gain parameter which should modify the volume of the audio going thru the Plug-in.

For this, each VST3 parameter requires a unique Identifier (a number).

  1. Open the file plugids.h and enter a new id kParamGainId, here we choose to assign the unique number 102.
enum GainParams : Vst::ParamID
    kParamGainId = 102,

2. Open now the plugcontroller.cpp file, and add the gain parameter with the parameters.addParameter

tresult PLUGIN_API PlugController::initialize (FUnknown* context)
    tresult result = EditController::initialize (context);
    if (result == kResultTrue)
        //---Create Parameters------------
         parameters.addParameter (STR16 ("Gain"), STR16 ("dB"), 0, .5, Vst::ParameterInfo::kCanAutomate, GainParams::kParamGainId, 0);
    return kResultTrue;


    • we add the flag kCanAutomate which will inform the DAW/Host that this parameter could be automated if wanted. (what is automation?)
    • a VST3 parameter is always normalized (its value is a floating point value between [0, 1]), here its default value is set to 0.5.

3. Now we will adapt the processor part for this new parameter. Open the file plugprocessor.h and add gain value  Vst::ParamValue mGain. This value will be used for the processing to apply the gain.

static FUnknown* createInstance (void*)
	return (Vst::IAudioProcessor*)new PlugProcessor (); 
	Vst::ParamValue mGain= 0;

Add the process applying the gain

  1. we need to set our internal mGain with its wanted value from the host, this is the first step of the process method, parse the parameter change coming from the host (data.inputParameterChanges) for the current audio block to process.
tresult PLUGIN_API PlugProcessor::process (Vst::ProcessData& data)
    //--- First : Read inputs parameter changes-----------
    if (data.inputParameterChanges)
        int32 numParamsChanged = data.inputParameterChanges->getParameterCount ();
        for (int32 index = 0; index < numParamsChanged; index++)
            Vst::IParamValueQueue* paramQueue = data.inputParameterChanges->getParameterData (index);
            if (paramQueue)
                Vst::ParamValue value;
                int32 sampleOffset;
                int32 numPoints = paramQueue->getPointCount ();
                switch (paramQueue->getParameterId ())
                    case GainParams::kParamGainId:
                        if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) == kResultTrue)
                            mGain = value;


    • data.inputParameterChanges could include more than 1 change for the same parameter inside a processing audio block. Here we take only the last change in the list and apply it our mGain.

Now the real processing part:

	//--- Here you have to implement your processing
	//---get audio buffers----------------
	uint32 sampleFramesSize = getSampleFramesSizeInBytes (processSetup, data.numSamples);
	void** in = getChannelBuffersPointer (processSetup, data.inputs[0]);
	void** out = getChannelBuffersPointer (processSetup, data.outputs[0]);
	// Here could check the silent flags
	// now we will produce the output
	// mark our outputs has not silent
	data.outputs[0].silenceFlags = 0;
	// for each channel (left and right)
	for (int32 i = 0; i < numChannels; i++)
		int32 samples = data.numSamples;
		Sample32* ptrIn = (Sample32*)in[i];
		Sample32* ptrOut = (Sample32*)out[i];
		Sample32 tmp;
		// for each sample in this channel
		while (--samples >= 0)
			// apply gain
			tmp = (*ptrIn++) * gain;
			(*ptrOut++) = tmp;

VST3 includes a way for the host to inform the plug-in that its inputs are silent or not, we will show how to take care of this:

	// Here could check the silent flags
    	//---check if silence---------------
	// normally we have to check each channel (simplification)
	if (data.inputs[0].silenceFlags != 0)
		// mark output silence too
		data.outputs[0].silenceFlags = data.inputs[0].silenceFlags;

		// the Plug-in has to be sure that if it sets the flags silence that the output buffer are clear
		for (int32 i = 0; i < numChannels; i++)
 			// do not need to be cleared if the buffers are the same (in this case input buffer are
			// already cleared by the host)
			if (in[i] != out[i])
				memset (out[i], 0, sampleFramesSize);
		// nothing to do at this point
		return kResultOk;

Add store/restore state

The Processor part represents the state of the Plug-in, so it is its job to implement the get/setState method used by the host to save/load projects and presets

  1. In the plugprocessor.cpp add in the getState method the mGain value to the state stream given by the host which will save it as project or preset.


tresult PLUGIN_API PlugProcessor::getState (IBStream* state)


    // here we need to save the model (preset or project)

    float toSaveParam1 = mGain;

    IBStreamer streamer (state, kLittleEndian);

    streamer.writeFloat (toSaveParam1);

    return kResultOk;


2. In the setState () method the Plug-in get from the host a new state (called after a project or preset is loaded).


tresult PLUGIN_API PlugProcessor::setState (IBStream* state)


    if (!state)

        return kResultFalse;

    // called when we load a preset or project, the model has to be reloaded

    IBStreamer streamer (state, kLittleEndian);

    float savedParam1 = 0.f;

    if (streamer.readFloat (savedParam1) == false)

        return kResultFalse;

    mGain = savedParam1;

    return kResultOk;


Add a UI using VSTGUI


IPlugView* PLUGIN_API PlugController::createView (const char* name)


    // someone wants my editor

    ConstString name (_name);

    if (name == ViewType::kEditor)


        auto* view = new VST3Editor (this, "view", "plug.uidesc");

        return view;


    return nullptr;


Add a Event Input

how to add a Event Bus + add use of NoteOn event in the processing

Add a Audio SideChain Mono

how to add a Audio Bus + add use of SC in the processing

On this page:

  • No labels