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,45 @@
if(NOT SMTG_ENABLE_VSTGUI_SUPPORT)
return()
endif()
cmake_minimum_required(VERSION 3.25.0)
project(smtg-vst3-panner
VERSION ${vstsdk_VERSION}.0
DESCRIPTION "Steinberg VST 3 Panner example"
)
smtg_add_vst3plugin(panner
include/plugcontroller.h
include/plugids.h
include/plugprocessor.h
include/version.h
source/plugfactory.cpp
source/plugcontroller.cpp
source/plugprocessor.cpp
resource/plug.uidesc
)
target_link_libraries(panner
PRIVATE
vstgui_support
)
smtg_target_add_plugin_resources(panner
RESOURCES
resource/plug.uidesc
resource/background.png
resource/animation_knob.png
resource/background_2x.png
resource/background_3x.png
resource/animation_knob_3x.png
)
smtg_target_add_plugin_snapshots(panner
RESOURCES
resource/A2EAF7DB320640F48EDE380DDF89562C_snapshot.png
resource/A2EAF7DB320640F48EDE380DDF89562C_snapshot_2.0x.png
)
smtg_target_setup_as_vst3_example(panner)
@@ -0,0 +1,18 @@
# Panner
## Introduction
**Panner** is a simple Panner plug-in showing how to support Panner category [Vst::PlugType::kSpatial](https://steinbergmedia.github.io/vst3_doc/vstinterfaces/group__plugType.html#gaa334568999d986b4e50627646e51a8b4) (mono to Stereo).
> See also: [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#panner).
## Getting Started
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
## Getting Help
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
@@ -0,0 +1,61 @@
///------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/include/plugcontroller.h
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#pragma once
#include "vstgui/plugin-bindings/vst3editor.h"
#include "public.sdk/source/vst/vsteditcontroller.h"
#include "pluginterfaces/vst/ivstparameterfunctionname.h"
namespace Steinberg {
namespace Panner {
//-----------------------------------------------------------------------------
class PlugController : public Vst::EditController,
public VSTGUI::VST3EditorDelegate,
public Vst::IParameterFunctionName
{
public:
//------------------------------------------------------------------------
// create function required for plug-in factory,
// it will be called to create new instances of this controller
//------------------------------------------------------------------------
static FUnknown* createInstance (void*)
{
return (Vst::IEditController*)new PlugController ();
}
//---from IPluginBase--------
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
//---from EditController-----
IPlugView* PLUGIN_API createView (const char* name) SMTG_OVERRIDE;
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
//---from IParameterFunctionName----
tresult PLUGIN_API getParameterIDFromFunctionName (Vst::UnitID unitID, FIDString functionName,
Vst::ParamID& paramID) override;
OBJ_METHODS (PlugController, Vst::EditController)
DEFINE_INTERFACES
DEF_INTERFACE (Vst::IParameterFunctionName)
END_DEFINE_INTERFACES (Vst::EditController)
DELEGATE_REFCOUNT (Vst::EditController)
};
//------------------------------------------------------------------------
} // namespace Panner
} // namespace Steinberg
@@ -0,0 +1,38 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/include/plugids.h
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#pragma once
namespace Steinberg {
namespace Panner {
// HERE are defined the parameter Ids which are exported to the host
enum PannerParams : Vst::ParamID
{
kBypassId = 100,
kParamPanId = 102,
};
// HERE you have to define new unique class ids: for processor and for controller
// you can use GUID creator tools like https://www.guidgenerator.com/
static const FUID MyProcessorUID (0xA2EAF7DB, 0x320640F4, 0x8EDE380D, 0xDF89562C);
static const FUID MyControllerUID (0x239F80C2, 0x4F1442C4, 0x8B58AE6E, 0x7C8644EB);
//------------------------------------------------------------------------
} // namespace Panner
} // namespace Steinberg
@@ -0,0 +1,65 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/include/plugprocessor.h
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/vstaudioeffect.h"
namespace Steinberg {
namespace Panner {
//-----------------------------------------------------------------------------
class PlugProcessor : public Vst::AudioEffect
{
public:
PlugProcessor ();
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API setBusArrangements (Vst::SpeakerArrangement* inputs, int32 numIns,
Vst::SpeakerArrangement* outputs,
int32 numOuts) SMTG_OVERRIDE;
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
tresult PLUGIN_API setupProcessing (Vst::ProcessSetup& setup) SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API process (Vst::ProcessData& data) SMTG_OVERRIDE;
//------------------------------------------------------------------------
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
static FUnknown* createInstance (void*) { return (Vst::IAudioProcessor*)new PlugProcessor (); }
enum
{
kPanLawEqualPower = 0,
};
protected:
void getStereoPanCoef (int32 panType, float pan, float& left, float& right) const;
template <typename SampleType>
tresult processAudio (Vst::ProcessData& data);
tresult (PlugProcessor::*processAudioPtr) (Vst::ProcessData& data);
Vst::ParamValue mPanValue = 0;
bool mBypass = false;
};
//------------------------------------------------------------------------
} // namespace Panner
} // namespace Steinberg
@@ -0,0 +1,37 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/include/version.h
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/fplatform.h"
// Plain project version file generated by cmake
#include "projectversion.h"
// HERE you have to define your plug-in, company name, email and web
#define stringPluginName "Panner"
#define stringOriginalFilename "Panner.vst3"
#if SMTG_PLATFORM_64
#define stringFileDescription stringPluginName" VST3-SDK (64Bit)"
#else
#define stringFileDescription stringPluginName" VST3-SDK"
#endif
#define stringCompanyWeb "http://www.steinberg.net"
#define stringCompanyEmail "mailto:info@steinberg.de"
#define stringCompanyName "Steinberg Media Technologies"
#define stringLegalCopyright " 2024 Steinberg Media Technologies"
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

@@ -0,0 +1,44 @@
#include <windows.h>
#include "../include/version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Version
/////////////////////////////////////////////////////////////////////////////
VS_VERSION_INFO VERSIONINFO
FILEVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
PRODUCTVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040004e4"
BEGIN
VALUE "FileVersion", FULL_VERSION_STR
VALUE "ProductVersion", FULL_VERSION_STR
VALUE "OriginalFilename", stringOriginalFilename
VALUE "FileDescription", stringFileDescription
VALUE "InternalName", stringFileDescription
VALUE "ProductName", stringFileDescription
VALUE "CompanyName", stringCompanyName
VALUE "LegalCopyright", stringLegalCopyright
VALUE "LegalTrademarks", stringLegalTrademarks
//VALUE "PrivateBuild", " \0"
//VALUE "SpecialBuild", " \0"
//VALUE "Comments", " \0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x400, 1252
END
END
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<vstgui-ui-description version="1">
<fonts>
</fonts>
<colors>
</colors>
<template background-color="~ BlackCColor" background-color-draw-style="filled and stroked" bitmap="background" class="CViewContainer" mouse-enabled="true" name="view" opacity="1" origin="0, 0" size="350, 120" transparent="false" wants-focus="false">
<view angle-range="270" angle-start="135" bitmap="animation_knob" class="CAnimKnob" control-tag="ParamPan" default-value="0.5" height-of-one-image="111" inverse-bitmap="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="197, 4" size="111, 111" sub-pixmaps="61" tooltip="This is my Panning (Equal Power)" transparent="false" value-inset="0" wants-focus="true" wheel-inc-value="0.1" zoom-factor="1.5"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ BlackCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="230, 5" round-rect-radius="6" shadow-color="~ RedCColor" size="50, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" text-shadow-offset="1, 1" title="C" transparent="true" value-precision="2" wants-focus="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ BlackCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="195, 90" round-rect-radius="6" shadow-color="~ RedCColor" size="40, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" text-shadow-offset="1, 1" title="L" transparent="true" value-precision="2" wants-focus="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ BlackCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="270, 90" round-rect-radius="6" shadow-color="~ RedCColor" size="50, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" text-shadow-offset="1, 1" title="R" transparent="true" value-precision="2" wants-focus="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextEdit" control-tag="ParamPan" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" immediate-text-change="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="150, 50" round-rect-radius="6" secure-style="false" shadow-color="~ RedCColor" size="55, 20" style-3D-in="false" style-3D-out="false" style-doubleclick="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" text-shadow-offset="1, 1" title="R 100" transparent="false" value-precision="2" wants-focus="true" wheel-inc-value="0.1"/>
</template>
<custom>
<attributes name="FocusDrawing"/>
<attributes Path="N:\SVN\devpluginset\public.sdk\samples\vst\panner\resource\plug.uidesc" name="VST3Editor"/>
<attributes Grids="1x 1,5x 5,10x 10,12x 12,15x 15" Size="5, 5" name="UIGridController"/>
<attributes SelectedTemplate="view" name="UITemplateController"/>
<attributes EditViewScale="1" EditorSize="0, 0, 800, 707" SplitViewSize_0_0="0.8105726872246695746682121352932881563902" SplitViewSize_0_1="0.1600587371512481593693877357509336434305" SplitViewSize_1_0="0.5095447870778266885594121049507521092892" SplitViewSize_1_1="0.4831130690161526963777305354597046971321" SplitViewSize_2_0="0.5200000000000000177635683940025046467781" SplitViewSize_2_1="0.4737500000000000044408920985006261616945" TabSwitchValue="0" Version="1" name="UIEditController"/>
<attributes name="UIAttributesController"/>
<attributes SelectedRow="26" name="UIViewCreatorDataSource"/>
<attributes SelectedRow="0" name="UIBitmapsDataSource"/>
<attributes SelectedRow="0" name="UITagsDataSource"/>
</custom>
<bitmaps>
<bitmap name="background" path="background.png"/>
<bitmap name="animation_knob" path="animation_knob.png"/>
<bitmap name="background_2x" path="background_2x.png" scale-factor="2"/>
<bitmap name="animation_knob_2x" path="animation_knob_2x.png" scale-factor="2"/>
<bitmap name="background_3x" path="background_3x.png" scale-factor="3"/>
<bitmap name="animation_knob_3x" path="animation_knob_3x.png" scale-factor="3"/>
</bitmaps>
<control-tags>
<control-tag name="Bypass" tag="100"/>
<control-tag name="ParamPan" tag="102"/>
</control-tags>
</vstgui-ui-description>
@@ -0,0 +1,196 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/source/plugcontroller.cpp
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#include "../include/plugcontroller.h"
#include "../include/plugids.h"
#include "base/source/fstreamer.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/base/ustring.h"
#include <string_view>
using namespace VSTGUI;
namespace Steinberg {
namespace Panner {
// example of custom parameter (overwriting to and fromString)
//------------------------------------------------------------------------
class PanParameter : public Vst::Parameter
{
public:
PanParameter (int32 flags, int32 id);
void toString (Vst::ParamValue normValue, Vst::String128 string) const SMTG_OVERRIDE;
bool fromString (const Vst::TChar* string, Vst::ParamValue& normValue) const SMTG_OVERRIDE;
};
//------------------------------------------------------------------------
// PanParameter Implementation
//------------------------------------------------------------------------
PanParameter::PanParameter (int32 flags, int32 id)
{
Steinberg::UString (info.title, USTRINGSIZE (info.title)).assign (USTRING ("Pan"));
Steinberg::UString (info.units, USTRINGSIZE (info.units)).assign (USTRING (""));
info.flags = flags;
info.id = id;
info.stepCount = 0;
info.defaultNormalizedValue = 0.5f;
info.unitId = Vst::kRootUnitId;
setNormalized (.5f);
}
//------------------------------------------------------------------------
void PanParameter::toString (Vst::ParamValue normValue, Vst::String128 string) const
{
char text[32];
if (normValue >= 0.505)
{
snprintf (text, 32, "R %d", int32 ((normValue - 0.5f) * 200 + 0.5f));
}
else if (normValue <= 0.495)
{
snprintf (text, 32, "L %d", int32 ((0.5f - normValue) * 200 + 0.5f));
}
else
{
strcpy (text, "C");
}
Steinberg::UString (string, 128).fromAscii (text);
}
//------------------------------------------------------------------------
bool PanParameter::fromString (const Vst::TChar* string, Vst::ParamValue& normValue) const
{
std::u16string_view stringView (string);
auto pos = stringView.find_first_of (u"C");
if (pos != std::string::npos)
{
normValue = 0.5;
return true;
}
else
{
bool left = stringView.find_first_of (u"L") == 0;
bool right = stringView.find_first_of (u"R") == 0;
if (left || right)
stringView = {stringView.data () + 1, stringView.size () - 1};
auto string8 = Vst::StringConvert::convert (stringView.data ());
char* end = nullptr;
double tmp = strtod (string8.data (), &end);
if (end != string8.data ())
{
if (tmp < 0)
{
left = true;
if (tmp < -100)
tmp = 100;
else
tmp = -tmp;
}
else if (tmp > 100.0)
{
normValue = 1;
return true;
}
if (!left)
normValue = tmp / 200 + 0.5;
else
normValue = 0.5 - tmp / 200;
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugController::initialize (FUnknown* context)
{
tresult result = EditController::initialize (context);
if (result == kResultTrue)
{
//---Create Parameters------------
parameters.addParameter (STR16 ("Bypass"), nullptr, 1, 0,
Vst::ParameterInfo::kCanAutomate | Vst::ParameterInfo::kIsBypass,
PannerParams::kBypassId);
auto* panParam = new PanParameter (Vst::ParameterInfo::kCanAutomate, PannerParams::kParamPanId);
parameters.addParameter (panParam);
}
return kResultTrue;
}
//------------------------------------------------------------------------
IPlugView* PLUGIN_API PlugController::createView (const char* _name)
{
std::string_view name (_name);
if (name == Vst::ViewType::kEditor)
{
auto* view = new VST3Editor (this, "view", "plug.uidesc");
return view;
}
return nullptr;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugController::getParameterIDFromFunctionName (Vst::UnitID unitID,
FIDString functionName,
Vst::ParamID& paramID)
{
using namespace Vst;
paramID = kNoParamId;
if (unitID == kRootUnitId && FIDStringsEqual (functionName, FunctionNameType::kPanPosCenterX))
paramID = PannerParams::kParamPanId;
return (paramID != kNoParamId) ? kResultOk : kResultFalse;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugController::setComponentState (IBStream* state)
{
// we receive the current state of the component (processor part)
// we read our parameters and bypass value...
if (!state)
return kResultFalse;
IBStreamer streamer (state, kLittleEndian);
float savedParam1 = 0.f;
if (streamer.readFloat (savedParam1) == false)
return kResultFalse;
setParamNormalized (PannerParams::kParamPanId, savedParam1);
// read the bypass
int32 bypassState;
if (streamer.readInt32 (bypassState) == false)
return kResultFalse;
setParamNormalized (kBypassId, bypassState ? 1 : 0);
return kResultOk;
}
//------------------------------------------------------------------------
} // namespace
} // namespace Steinberg
@@ -0,0 +1,49 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/source/plugfactory.cpp
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#include "public.sdk/source/main/pluginfactory.h"
#include "../include/plugcontroller.h" // for createInstance
#include "../include/plugprocessor.h" // for createInstance
#include "../include/plugids.h" // for uids
#include "../include/version.h" // for version and naming
#define stringSubCategory Vst::PlugType::kSpatialFx // Subcategory for this plug-in (to be changed if needed, see PlugType in ivstaudioprocessor.h)
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail)
DEF_CLASS2 (INLINE_UID_FROM_FUID(Steinberg::Panner::MyProcessorUID),
PClassInfo::kManyInstances, // cardinality
kVstAudioEffectClass, // the component category (do not change this)
stringPluginName, // here the plug-in name (to be changed)
Vst::kDistributable, // means that component and controller could be distributed on different computers
stringSubCategory, // 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 change this, always use this define)
Steinberg::Panner::PlugProcessor::createInstance) // function pointer called when this component should be instantiated
DEF_CLASS2 (INLINE_UID_FROM_FUID(Steinberg::Panner::MyControllerUID),
PClassInfo::kManyInstances, // cardinality
kVstComponentControllerClass,// the Controller category (do not change this)
stringPluginName "Controller", // controller name (can be the same as the 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 change this, always use this define)
Steinberg::Panner::PlugController::createInstance)// function pointer called when this component should be instantiated
END_FACTORY
@@ -0,0 +1,245 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/panner/source/plugprocessor.cpp
// Created by : Steinberg, 02/2020
// Description : Panner Example for VST 3
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#include "../include/plugprocessor.h"
#include "../include/plugids.h"
#include "public.sdk/source/vst/vstaudioprocessoralgo.h"
#include "base/source/fstreamer.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
namespace Steinberg {
namespace Panner {
#ifndef kPI
#define kPI 3.14159265358979323846
#endif
#define kRampingTimeMs 10.0 // in ms
//-----------------------------------------------------------------------------
PlugProcessor::PlugProcessor ()
{
// register its editor class
setControllerClass (MyControllerUID);
// default init
processAudioPtr = &PlugProcessor::processAudio<float>;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::initialize (FUnknown* context)
{
//---always initialize the parent-------
tresult result = AudioEffect::initialize (context);
if (result != kResultTrue)
return kResultFalse;
//---create Audio In/Out busses------
// we want a Mono Input and a Stereo Output
addAudioInput (STR16 ("AudioInput"), Vst::SpeakerArr::kMono);
addAudioOutput (STR16 ("AudioOutput"), Vst::SpeakerArr::kStereo);
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::canProcessSampleSize (int32 symbolicSampleSize)
{
return ((symbolicSampleSize == Vst::kSample32) || (symbolicSampleSize == Vst::kSample64)) ?
kResultTrue :
kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::setBusArrangements (Vst::SpeakerArrangement* inputs, int32 numIns,
Vst::SpeakerArrangement* outputs,
int32 numOuts)
{
// we only support mono to stereo
if (numIns == 1 && numOuts == 1 && inputs[0] == Vst::SpeakerArr::kMono &&
outputs[0] == Vst::SpeakerArr::kStereo)
{
return AudioEffect::setBusArrangements (inputs, numIns, outputs, numOuts);
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::setupProcessing (Vst::ProcessSetup& setup)
{
if (setup.symbolicSampleSize == Vst::kSample64)
processAudioPtr = &PlugProcessor::processAudio<double>;
else
processAudioPtr = &PlugProcessor::processAudio<float>;
return AudioEffect::setupProcessing (setup);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::setActive (TBool state)
{
return AudioEffect::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::process (Vst::ProcessData& data)
{
//--- Read inputs parameter changes-----------
if (data.inputParameterChanges)
{
int32 numParamsChanged = data.inputParameterChanges->getParameterCount ();
for (int32 index = 0; index < numParamsChanged; index++)
{
if (Vst::IParamValueQueue* paramQueue =
data.inputParameterChanges->getParameterData (index))
{
Vst::ParamValue value;
int32 sampleOffset;
int32 numPoints = paramQueue->getPointCount ();
switch (paramQueue->getParameterId ())
{
case PannerParams::kParamPanId:
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
kResultTrue)
mPanValue = value;
break;
case PannerParams::kBypassId:
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
kResultTrue)
mBypass = (value > 0.5f);
break;
}
}
}
}
//--- Process Audio---------------------
//--- ----------------------------------
if (data.numInputs == 0 || data.numOutputs == 0 || data.numSamples == 0)
{
// nothing to do
return kResultOk;
}
return (this->*processAudioPtr) (data);
}
//------------------------------------------------------------------------
template <typename SampleType>
tresult PlugProcessor::processAudio (Vst::ProcessData& data)
{
int32 numFrames = data.numSamples;
uint32 sampleFramesSize = getSampleFramesSizeInBytes (processSetup, numFrames);
auto** currentInputBuffers =
(SampleType**)Vst::getChannelBuffersPointer (processSetup, data.inputs[0]);
auto** currentOutputBuffers =
(SampleType**)Vst::getChannelBuffersPointer (processSetup, data.outputs[0]);
// if we have only silence clear the output and do nothing.
data.outputs->silenceFlags = data.inputs->silenceFlags ? 0x7FFFF : 0;
if (data.inputs->silenceFlags)
{
memset (currentOutputBuffers[0], 0, sampleFramesSize);
memset (currentOutputBuffers[1], 0, sampleFramesSize);
return kResultOk;
}
float leftPan;
float rightPan;
if (mBypass)
getStereoPanCoef (kPanLawEqualPower, 0.f, leftPan, rightPan);
else
getStereoPanCoef (kPanLawEqualPower, static_cast<float> (mPanValue), leftPan, rightPan);
//---pan : 1 -> 2---------------------
SampleType tmp;
SampleType* inputMono = currentInputBuffers[0];
SampleType* outputLeft = currentOutputBuffers[0];
SampleType* outputRight = currentOutputBuffers[1];
for (int32 n = 0; n < numFrames; n++)
{
tmp = inputMono[n];
outputLeft[n] = tmp * leftPan;
outputRight[n] = tmp * rightPan;
}
return kResultOk;
}
//------------------------------------------------------------------------
void PlugProcessor::getStereoPanCoef (int32 panType, float pan, float& left, float& right) const
{
if (panType == kPanLawEqualPower)
{
pan = pan * static_cast<float> (kPI) * 0.5f;
left = cosf (pan);
right = sinf (pan);
}
else
{
left = 0.5f;
right = 0.5f;
}
}
//------------------------------------------------------------------------
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 savedPan= 0.f;
if (streamer.readFloat (savedPan) == false)
return kResultFalse;
int32 savedBypass = 0;
if (streamer.readInt32 (savedBypass) == false)
return kResultFalse;
mPanValue = savedPan;
mBypass = savedBypass > 0;
return kResultOk;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugProcessor::getState (IBStream* state)
{
// here we need to save the model (preset or project)
float toSavePan = static_cast<float> (mPanValue);
int32 toSaveBypass = mBypass ? 1 : 0;
IBStreamer streamer (state, kLittleEndian);
streamer.writeFloat (toSavePan);
streamer.writeInt32 (toSaveBypass);
return kResultOk;
}
//------------------------------------------------------------------------
} // namespace
} // namespace Steinberg