Make sure to check the Requirements documentation for information about which VST3 SDK Jamba supports and how to get it.
FetchContent_Populate
/FetchContent_MakeAvailable
with SOURCE_SUBDIR
option (see CMake discussion)create-plugin.py
tool on WindowsFetchContent_Populate
JAMBA_VST3SDK_PATCH_DIR
(Jamba uses it on Windows/DLL build to fix an issue with win32resourcestream.cpp
, but you can also use it for your own purposes): by defining this variable, 2 things happen
${JAMBA_VST3SDK_PATCH_DIR}
on top of this copy while never modifying a local version of the SDKstringToFloat
by changing its return convention (0
instead of NaN
) due to fast-math
option which assumes that there is no NaN in the code.version.h
file generated on WindowsLINK_LIBRARIES
) to the universal build (M1 builds)AudioBuffer
API// Parameters
VstParams<bool, 2> fArrayVst;
// State
RTVstParams<bool, 2> fArrayVst;
inspect
command to run the VST3Inspector
toolinfo
command to run the moduleinfotool
tool (new since SDK 3.7.5)moduleinfo.json
(new since SDK 3.7.5).vst3
folder) instead of a DLL when VST2
is disabledInfo.plist
through CMake replacement, thus allowing to inject dates, versions, etc…Info.plist
through Xcode preprocessing when using Xcode generatorInfo.plist
without
proper versiongtest_discover_tests
instead of gtest_add_tests
to minimize CMake invocation when building tests.rc
file gets regenerated properly when resource files change (Windows)Info.plist
processing, you should replace:
<-- File mac/Info.plist -->
<-- Replace this (processed only via Xcode preprocessing) -->
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<-- With this (processed with all generators) -->
<key>CFBundleExecutable</key>
<string>@MACOSX_BUNDLE_EXECUTABLE_NAME@</string>
audio-unit/Info.plist
ARCHIVE_FILENAME
and ARCHIVE_ARCHITECTURE
to the main jamba_add_vst_plugin
CMake apiCMakeLists.txt
CMakeLists.txt
as an example.JambaPluginFactory::GetNonDistributableVST3PluginFactory
function to create a plugin that would not be distributableIParamSerializer
methodsuninstall-au
command to jamba.py
EXPORT_FACTORY
into SMTG_EXPORT_SYMBOL
. Jamba is adding it back for backward compatibility (in PluginFactory.h
) but you may want to update it.Migrated Jamba to use VST3 SDK 3.7.0
Major refactoring of CMake files to make it easier to use and extend/customize (check CMake Build)
Replaced main dev script implementation with a python script (with the added benefit that the Windows version is now on par with the macOS one).
The wrapper shell scripts (jamba.sh
and jamba.bat
) are still the official way to invoke it and jamba.py
should be treated as an implementation detail.
Improved main script to run multiple commands (ex: jamba.sh test validate
)
Replaced configure script with a python script (blank plugin now uses it)
Added many new (cmake) targets so that you no longer have to rely on the script. For example running the editor can now simply be achieved by building the jmb_run_editor
target.
Jamba itself has not changed (no new API) and only very few tweaks were required to migrate to 3.7.0
CMakeLists.txt
to invoke jamba_add_vst_plugin
which is the new (cmake) API to add a VST3 plugin (single call).
CMakeLists.txt
as an example.cpack
(but due to the CMake refactoring it is easy to turn it off entirely or implement your own)VST2_SDK_ROOT
)JAMBA_ENABLE_DEV_SCRIPT
in which case python is not required)install
command no longer deletes the folder before installation. Use ./jamba.sh uninstall install
if you want this behavior.prod
command has been removed from main dev script (equivalent to jamba.sh -r -b test validate archive
but check migration guide for details on how to add it back as a target if you really need it)If you want to benefit from the new configure python script (configure.py
), simply copy it from the blank plugin (it is 100% generic so it will work for any Jamba project)
FastWriteMemoryStream
(a faster implementation of MemoryStream
)// Example from some controller (aboutButton is a TextButtonView)
aboutButton->setOnClickListener([this] {
fState->showDialog("about_dialog");
});
// From another controller tied to the about_dialog view (set via the sub-controller attribute)
dismissButton->setOnClickListener([this] {
fState->dismissDialog();
});
Updated loguru to latest (as of master on 2020-03-31)
Added missing using
types and toUTF8String()
methods to XXXParam
classes
Added resetToDefault()
method to all parameters (since a default value is provided when the parameter is created, it is a very convenient way to get back to it without having to know about it and using some global constant)
Added ExpiringDataCache
concept (using Timer
from the VST3 SDK)
Renamed the plugin file from the blank plugin to Plugin.h
(instead of the name of the plugin)
Changed the way the plugin gets registered to the VST3 world (implements the main GetPluginFactory()
function) with an easier and less error prone syntax:
EXPORT_FACTORY Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory()
{
return JambaPluginFactory::GetVST3PluginFactory<
pongasoft::test::jamba::RT::JambaTestPluginProcessor, // processor class (Real Time)
pongasoft::test::jamba::GUI::JambaTestPluginController // controller class (GUI)
>("pongasoft", // vendor
"https://www.pongasoft.com", // url
"support@pongasoft.com", // email
stringPluginName, // plugin name
FULL_VERSION_STR, // plugin version
Vst::PlugType::kFx // plugin category (can be changed to other like kInstrument, etc...)
);
}
This new syntax is optional and the old/macro based syntax is still valid and acceptable (new blank plugins will be created using this new methodology). If you want to migrate your codebase to the new factory you can check this commit for the JambaSampleGain
project as an example.
googletest
to 1.10.0
(due to CMake caching, this requires deleting the CMake build folder to take effect on existing projects)T
for all params (RTRawVstParam
, RTParam
, GUIRawVstParam
, GUIVstParam
, GUIJmbParam
, GUIOptionalParam
).operator *
) to all params as a shortcut to invoke .value()
(which is the preferred way to fix the deprecated warnings)T
) in many instancestoUTF8String()
for Jmb parameter when no serializer is provided by checking the availability of ostream<<
for T
_
for the switch container view (for example to use as an overlay that is shown/hidden)This release contains a lot of big changes. Although I tried my best to be backward compatible there may be a few changes that might be breaking.
Build requirements: Jamba now requires C++17 and Visual Studio Build Tools 2019 (for Windows) (note that XCode 9.2 remains the requirement for macOS)
Major GUI parameter refactoring:
IGUIParameter
and typed hierarchy (ITGUIParameter<T>
) as the base of all GUI parametersGUIOptionalParam
to handle Vst, Jmb or no parameter in a consistent fashionIGUIParameter::asDiscreteParameter(int32 iStepCount)
) to convert (if possible) any parameter
into a discrete parameter (which is a parameter backed by an int32
with a given number of steps)MomentaryButtonView
and ToggleButtonView
to use discrete parameter concept (thus allowing other types than bool
) and allowing
to override the value of the steps representing on and off.SwitchViewContainer
to use discrete parameter concept, thus allowing to use any Vst or Jmb parameter that is
(or can be interpreted as) a discrete parameter.Major renaming: introduced ParamAware
(formerly GUIParamCxAware
) and StateAware
(formerly PluginAccessor
) (added deprecation warnings for old names) and related.
Jmb GUI parameters no longer needed to be explicitly added to GUIState
(similar to Vst parameters)
Added IDiscreteConverter<T>
concept for Jmb parameters to be able to convert a Jmb parameter to a discrete parameter
Added ParamDisplayView
to display the value of any parameter (Vst or Jmb)
Added DebugParamDisplayView
to display and highlight the value of a parameter (very useful during development)
Added ListAttribute
to handle attributes backed by a list of values (for example enumeration)
// Example (from StepButtonView.h)
registerListAttribute<EArrowDirection>("arrow-direction",
&StepButtonView::getArrowDirection,
&StepButtonView::setArrowDirection,
{
{"auto", EArrowDirection::kAuto},
{"up", EArrowDirection::kUp},
{"right", EArrowDirection::kRight},
{"down", EArrowDirection::kDown},
{"left", EArrowDirection::kLeft}
}
Simplified parameter initialization by allowing to use initializer list and added more generic DiscreteTypeParamConverter
:
// Example: with DiscreteTypeParamConverter, no need to specify size in advance. Also note the
// use of the initializer list to initialize it.
fEnumClassVst =
vst<DiscreteTypeParamConverter<EEnumClass>>(EJambaTestPluginParamID::kEnumClassVst, STR16("EnumClassVst"),
{
{EEnumClass::kEnumClass0, STR16("kEC0 (vst)")},
{EEnumClass::kEnumClass1, STR16("kEC1 (vst)")},
{EEnumClass::kEnumClass2, STR16("kEC2 (vst)")},
{EEnumClass::kEnumClass3, STR16("kEC3 (vst)")},
})
.add();
Added jamba-test-plugin
to the Jamba project as a unit test/development plugin for Jamba (demonstrates ALL available views)
Added test.sh
to conveniently run the jamba tests (which are declared by jamba-test-plugin
) from the command line
Added test_jamba
target to run the jamba tests from the IDE
Added 2 different sets of UUIDs in blank plugin to handle Debug vs Release deployments
ICustomViewLifecycle
which is now used instead of GUIParamCxAware
(in CustomViewFactory
)ParamAware::unregisterAll()
followed by ParamAware::registerParameters()
registerParameters
method that you implement in your view is much simpler because
it does not have to handle previously registered parameters (which was not trivial to keep an accurate track of)StepButtonView
and DiscreteButtonView
now use discrete values only (no longer double
). Check the documentation on how to use it instead (ex: an increment of 0.1
can be converted to an increment of 1
with a step count of 10
).TagID
to be an unsigned int (ParamID
aka uint32
)DiscreteValueParamConverter
to be an int32
initialize
API to match superclassbuild_vst3
, test_vst3
, install_vst3
, install_vst2
, build_au
and install_au
install_vst2
or install_vst3
)jamba.sh
and jamba.bat
to use the new cmake targets (making the scripts more generic)build_vst3
by setting an optional BUILD_VST3_TARGET
variabletest_vst3
by setting an optional TEST_VST3_TARGET
variablebuild_au
by setting an optional BUILD_AU_TARGET
variablejamba.sh
script to handle filename with white spaces and install audio unit before validation (validation tool unfortunately works from an installed component, not a file…)jamba.sh
script (jamba.sh validate-au
) which runs the auvaltool
utility on the audio unit pluginViews::SwitchContainerView
)Views::TextButtonView
)Views::MomentaryButtonView
)step
value). This button can be used for radio groups, tabs, etc… (check Views::DiscreteButtonView
)Views::createCustomView
(defined in Views/CustomViewCreator.h
). Check commit. The function takes an additional 2 parameters which can be safely ignored if you don’t need them.Views::registerGlobalKeyboardHook
)AudioBuffers
and Channel
(copyFrom
and forEachSample
). Defined const
and non const
versions.This is a major release with many changes (a few breaking APIs)
Added TextViewButton
on which you can register a onClickListener
or implement onClick
. Also handles disabled state.
Added ScrollbarView
which implements a scrollbar tied to 2 parameters (offset and zoom)
Added CustomController
to implement a custom controller tied into Jamba (access to Vst/Jmb parameters and state)
Added ability to easily switch to a new view (GUIController::switchToView
)
Added GUIJmbParameter::updateIf
to update the value in place when necessary
Added callback APIs to GUIParamCxAware
registerCallback<bool>(fParams->fMyParam,
[this] (GUIVstParam<bool> &iParam) {
flushCache();
});
Added registering callbacks and parameters on a view without inheriting from it (can be used from controllers verifyView
method):
auto button = dynamic_cast<Views::TextButtonView *>(iView);
if(button) {
auto callback = [] (Views::TextButtonView *iButton,
GUIJmbParam<SampleData> &iParam) {
iButton->setMouseEnabled(iParam->hasUndoHistory());
};
fState->registerConnectionFor(button)
->registerCallback<SampleData>(fState->fSampleData,
std::move(callback),
true);
}
Added optional arguments to Parameters::vst<>()
(resp. Parameters::jmb<>()
) that get passed through the converter (resp. serializer) allowing syntax like
fPlayModeHold =
vst<BooleanParamConverter>(1201, // param ID
STR16("Play Mode"), // param title
STR16("Trigger"), STR16("Hold")) // BooleanParamConverter args
Requires C++14
Added EnumParamConverter
for Vst parameters backed by an enum
Added Range
concept
Refactored CustomViewCreator
code to simplify writing individual attributes. Introduced MarginAttribute
, RangeAttribute
, and GradientAttribute
Refactored Lerp
class to deal with type parameters differently (TFloat
for math precision, X
for type of x, Y
for type of y). Introduced SPLerp
(single precision) and DPLerp
(double precision) as well as several convenient methods. Example:
// this will interpolate (SP=single precision)
// X -> the time (long) from the range [0, fFadeDuration]
// Y -> to the alpha (uint8_t) range [255, 0] (opaque -> transparent)
// Note that although X and Y types are integer flavors, the interpolation will use floats
// and the value returned will be cast to uint8_t
fColor.alpha = Utils::mapValueSPXY<long, uint8_t>(iTime, 0, fFadeDuration, 255, 0);
GUIParamCxAware
(which is the class used for registering parameters) has been simplified with registerParam
methods (when the type is known).
Moved PluginAccessor
into its own header file
Removed CustomViewInitializer
AudioBuffers
now properly handles null buffersjamba.sh
(resp jamba.bat
) scriptXcode
as the cmake generator on macOSIntroduced Jamba parameters to handle non VST parameters and messaging RT <-> GUI
Added Debug::ParamTable
and Debug::ParamLine
to display parameters => example
| ID | TITLE | TYP | OW | TRS | SHA | DEF.N | DEF.S | STP | FLG | SHORT | PRE | UID | UNS |
--------------------------------------------------------------------------------------------------------------
| 1000 | Bypass | vst | rt | | | 0.000 | Off | 1 | 65537 | Bypass | 4 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 2010 | Left Gain | vst | rt | | | 0.700 | +0.00dB | 0 | 1 | GainL | 2 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 2011 | Right Gain | vst | rt | | | 0.700 | +0.00dB | 0 | 1 | GainR | 2 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 2012 | Link | vst | ui | | | 1.000 | On | 1 | 1 | Link | 4 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 2020 | Reset Max | vst | rt | | | 0.000 | Off | 1 | 1 | Reset | 4 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 2000 | VuPPM | vst | rt | x | | 0.000 | 0.0000 | 0 | 1 | VuPPM | 4 | 0 | |
--------------------------------------------------------------------------------------------------------------
| 3000 | Stats | jmb | rt | x | x | | -oo | | | | | | |
--------------------------------------------------------------------------------------------------------------
| 2030 | Input Text | jmb | ui | | | | Hello from GUI | | | | | | |
--------------------------------------------------------------------------------------------------------------
| 3010 | UIMessage | jmb | ui | x | x | | | | | | | | |
--------------------------------------------------------------------------------------------------------------
Implemented lock free, memory allocation free and copy free version of SingleElementQueue and AtomicValue
Generate build, test, validate, edit and install scripts
Added jamba-sample-gain documentation project