Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,19 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/vst/vsttypes.h"
namespace Steinberg::Tutorial {
//------------------------------------------------------------------------
static const FUID ProcessorUID (0xC18D3C1E, 0x719E4E29, 0x924D3ECA, 0xA5E4DA18);
static const FUID ControllerUID (0xC244B7E6, 0x24084E20, 0xA24A8C43, 0xF84C8BE8);
#define DataExchangeVST3Category "Fx"
//------------------------------------------------------------------------
} // namespace Steinberg::Tutorial
@@ -0,0 +1,59 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#include "pids.h"
#include "public.sdk/source/vst/vsteditcontroller.h"
#include "base/source/fstreamer.h"
//------------------------------------------------------------------------
namespace Steinberg::Tutorial {
using namespace Steinberg::Vst;
//------------------------------------------------------------------------
class Controller : public EditController
{
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
};
//------------------------------------------------------------------------
tresult PLUGIN_API Controller::initialize (FUnknown* context)
{
tresult result = EditController::initialize (context);
if (result != kResultOk)
{
return result;
}
parameters.addParameter (STR ("Gain"), STR ("%"), 0, 1., ParameterInfo::kCanAutomate,
ParameterID::Gain);
return kResultOk;
}
//------------------------------------------------------------------------
tresult PLUGIN_API Controller::setComponentState (IBStream* state)
{
if (!state)
return kInvalidArgument;
IBStreamer streamer (state, kLittleEndian);
ParamValue value;
if (!streamer.readDouble (value))
return kResultFalse;
if (auto param = parameters.getParameter (ParameterID::Gain))
param->setNormalized (value);
return kResultTrue;
}
//------------------------------------------------------------------------
FUnknown* createControllerInstance (void*)
{
return static_cast<IEditController*> (new Controller);
}
//------------------------------------------------------------------------
} // Steinberg::Tutorial
@@ -0,0 +1,60 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#include "cids.h"
#include "version.h"
#include "public.sdk/source/main/pluginfactory.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#define stringPluginName "advanced-techniques-tutorial"
using namespace Steinberg;
using namespace Steinberg::Vst;
using namespace Steinberg::Tutorial;
//------------------------------------------------------------------------
namespace Steinberg::Tutorial {
FUnknown* createProcessorInstance (void*);
FUnknown* createControllerInstance (void*);
}
//------------------------------------------------------------------------
// VST Plug-in Entry
//------------------------------------------------------------------------
// Windows: do not forget to include a .def file in your project to export
// GetPluginFactory function!
//------------------------------------------------------------------------
BEGIN_FACTORY_DEF ("Steinberg Media Technologies",
"https://steinberg.net",
"mailto:info@steinberg.de")
//---First Plug-in included in this factory-------
// its kVstAudioEffectClass component
DEF_CLASS2 (INLINE_UID_FROM_FUID(ProcessorUID),
PClassInfo::kManyInstances, // cardinality
kVstAudioEffectClass, // the component category (do not changed this)
stringPluginName, // here the Plug-in name (to be changed)
Vst::kDistributable, // means that component and controller could be distributed on different computers
DataExchangeVST3Category, // Subcategory for this Plug-in (to be changed)
FULL_VERSION_STR, // Plug-in version (to be changed)
kVstVersionString, // the VST 3 SDK version (do not changed this, use always this define)
createProcessorInstance)// function pointer called when this component should be instantiated
// its kVstComponentControllerClass component
DEF_CLASS2 (INLINE_UID_FROM_FUID (ControllerUID),
PClassInfo::kManyInstances, // cardinality
kVstComponentControllerClass,// the Controller category (do not changed this)
stringPluginName "Controller", // controller name (could be the same than component name)
0, // not used here
"", // not used here
FULL_VERSION_STR, // Plug-in version (to be changed)
kVstVersionString, // the VST 3 SDK version (do not changed this, use always this define)
createControllerInstance)// function pointer called when this component should be instantiated
//----for others Plug-ins contained in this factory, put like for the first Plug-in different DEF_CLASS2---
END_FACTORY
@@ -0,0 +1,17 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#pragma once
//------------------------------------------------------------------------
namespace Steinberg::Tutorial {
//------------------------------------------------------------------------
enum ParameterID
{
Gain = 1,
};
//------------------------------------------------------------------------
} // Steinberg::Tutorial
@@ -0,0 +1,208 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#include "cids.h"
#include "pids.h"
#include "public.sdk/source/vst/utility/audiobuffers.h"
#include "public.sdk/source/vst/utility/processdataslicer.h"
#include "public.sdk/source/vst/utility/rttransfer.h"
#include "public.sdk/source/vst/utility/sampleaccurate.h"
#include "public.sdk/source/vst/vstaudioeffect.h"
#include "base/source/fstreamer.h"
#include <array>
#include <cassert>
#include <limits>
#include <vector>
//------------------------------------------------------------------------
namespace Steinberg::Tutorial {
using namespace Steinberg::Vst;
//------------------------------------------------------------------------
struct StateModel
{
double gain;
};
//------------------------------------------------------------------------
struct MyEffect : public AudioEffect
{
using RTTransfer = RTTransferT<StateModel>;
MyEffect ();
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
SpeakerArrangement* outputs,
int32 numOuts) SMTG_OVERRIDE;
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
void handleParameterChanges (IParameterChanges* changes);
template <SymbolicSampleSizes SampleSize>
void process (ProcessData& data);
SampleAccurate::Parameter gainParameter {ParameterID::Gain, 1.};
RTTransfer stateTransfer;
};
//------------------------------------------------------------------------
MyEffect::MyEffect ()
{
setControllerClass (ControllerUID);
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::initialize (FUnknown* context)
{
auto result = AudioEffect::initialize (context);
if (result == kResultTrue)
{
addAudioInput (STR ("Input"), SpeakerArr::kStereo);
addAudioOutput (STR ("Output"), SpeakerArr::kStereo);
}
return result;
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::terminate ()
{
stateTransfer.clear_ui ();
return AudioEffect::terminate ();
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::setState (IBStream* state)
{
if (!state)
return kInvalidArgument;
IBStreamer streamer (state, kLittleEndian);
uint32 numParams;
if (streamer.readInt32u (numParams) == false)
return kResultFalse;
auto model = std::make_unique<StateModel> ();
ParamValue value;
if (!streamer.readDouble (value))
return kResultFalse;
model->gain = value;
stateTransfer.transferObject_ui (std::move (model));
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::getState (IBStream* state)
{
if (!state)
return kInvalidArgument;
IBStreamer streamer (state, kLittleEndian);
streamer.writeDouble (gainParameter.getValue ());
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
SpeakerArrangement* outputs, int32 numOuts)
{
if (numIns != 1 || numOuts != 1)
return kResultFalse;
if (SpeakerArr::getChannelCount (inputs[0]) == SpeakerArr::getChannelCount (outputs[0]))
{
getAudioInput (0)->setArrangement (inputs[0]);
getAudioOutput (0)->setArrangement (outputs[0]);
return kResultTrue;
}
return kResultFalse;
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::canProcessSampleSize (int32 symbolicSampleSize)
{
return (symbolicSampleSize == SymbolicSampleSizes::kSample32 ||
symbolicSampleSize == SymbolicSampleSizes::kSample64) ?
kResultTrue :
kResultFalse;
}
//------------------------------------------------------------------------
template <SymbolicSampleSizes SampleSize>
void MyEffect::process (ProcessData& data)
{
ProcessDataSlicer slicer (8);
auto doProcessing = [this] (ProcessData& data) {
// get the gain value for this block
ParamValue gain = gainParameter.advance (data.numSamples);
// process audio
AudioBusBuffers* inputs = data.inputs;
AudioBusBuffers* outputs = data.outputs;
for (auto channelIndex = 0; channelIndex < inputs[0].numChannels; ++channelIndex)
{
auto inputBuffers = getChannelBuffers<SampleSize> (inputs[0])[channelIndex];
auto outputBuffers = getChannelBuffers<SampleSize> (outputs[0])[channelIndex];
for (auto sampleIndex = 0; sampleIndex < data.numSamples; ++sampleIndex)
{
auto sample = inputBuffers[sampleIndex];
outputBuffers[sampleIndex] = sample * gain;
}
}
};
slicer.process<SampleSize> (data, doProcessing);
}
//------------------------------------------------------------------------
void MyEffect::handleParameterChanges (IParameterChanges* changes)
{
if (!changes)
return;
int32 changeCount = changes->getParameterCount ();
for (auto i = 0; i < changeCount; ++i)
{
if (auto queue = changes->getParameterData (i))
{
auto paramID = queue->getParameterId ();
if (paramID == ParameterID::Gain)
{
gainParameter.beginChanges (queue);
}
}
}
}
//------------------------------------------------------------------------
tresult PLUGIN_API MyEffect::process (ProcessData& data)
{
stateTransfer.accessTransferObject_rt (
[this] (const auto& stateModel) { gainParameter.setValue (stateModel.gain); });
handleParameterChanges (data.inputParameterChanges);
if (processSetup.symbolicSampleSize == SymbolicSampleSizes::kSample32)
process<SymbolicSampleSizes::kSample32> (data);
else
process<SymbolicSampleSizes::kSample64> (data);
gainParameter.endChanges ();
return kResultTrue;
}
//------------------------------------------------------------------------
FUnknown* createProcessorInstance (void*)
{
return static_cast<IAudioProcessor*> (new MyEffect);
}
} // Steinberg::Tutorial
@@ -0,0 +1,20 @@
//------------------------------------------------------------------------
// Copyright(c) 2023 Steinberg Media Technologies.
//------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/fplatform.h"
// Plain project version file generated by cmake
#include "projectversion.h"
#define stringOriginalFilename "advanced-techniques-tutorial.vst3"
#if SMTG_PLATFORM_64
#define stringFileDescription "advanced-techniques-tutorial VST3 (64Bit)"
#else
#define stringFileDescription "advanced-techniques-tutorial VST3"
#endif
#define stringCompanyName "Steinberg Media Technologies\0"
#define stringLegalCopyright "Copyright(c) 2023 Steinberg Media Technologies."
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"