Browse Source

VST3: Implement programs on DSP side, update TODO items

Signed-off-by: falkTX <falktx@falktx.com>
pull/330/head
falkTX 4 years ago
parent
commit
cfb1873d85
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
4 changed files with 119 additions and 24 deletions
  1. +105
    -18
      distrho/src/DistrhoPluginVST3.cpp
  2. +5
    -0
      distrho/src/DistrhoUIPrivateData.hpp
  3. +8
    -5
      distrho/src/DistrhoUIVST3.cpp
  4. +1
    -1
      distrho/src/travesty/base.h

+ 105
- 18
distrho/src/DistrhoPluginVST3.cpp View File

@@ -27,11 +27,24 @@

/* TODO items:
* - base component refcount handling
* - program support
* - parameter enumeration as lists
* - hide parameter outputs?
* - hide program parameter?
* - state support
* - save and restore current program
* - midi cc parameter mapping
* - full MIDI1 encode and decode
* - call component handler restart with params-changed flag when setting program
* - decode version number (0x102030 -> 1.2.3)
* - bus arrangements
* - optional audio buses, create dummy buffer of max_block_size length for them
* - routing info, do we care?
* - set sidechain bus name from port group
* - implement getParameterValueForString
* - set factory class_flags
* - set factory sub_categories
* - set factory email (needs new DPF API, useful for LV2 as well)
* - do something with get_controller_class_id and set_io_mode?
* - call component handler restart with params-changed flag after changing program
* - call component handler restart with latency-changed flag when latency changes
*/

@@ -227,9 +240,14 @@ public:
PluginVst3()
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback),
fComponentHandler(nullptr),
fParameterOffset(fPlugin.getParameterOffset()),
fParameterValues(nullptr)
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
, fHostEventOutputHandle(nullptr)
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
, fCurrentProgram(0),
fProgramCountMinusOne(fPlugin.getProgramCount()-1)
#endif
{
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
@@ -417,7 +435,7 @@ public:
{
const AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));

// TODO find port group name
// TODO find port group name for sidechain buses
if (port.busId == busId)
{
strncpy_utf16(busName, port.name, 128);
@@ -469,7 +487,7 @@ public:
{
const AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));

// TODO find port group name
// TODO find port group name for sidechain buses
if (port.busId == busId)
{
strncpy_utf16(busName, port.name, 128);
@@ -558,6 +576,9 @@ public:
#if DISTRHO_PLUGIN_WANT_STATE
// TODO
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
// TODO
#endif

if (const uint32_t paramCount = fPlugin.getParameterCount())
{
@@ -1027,14 +1048,27 @@ public:

int32_t getParameterCount() const noexcept
{
return fPlugin.getParameterCount();
return fPlugin.getParameterCount() + fParameterOffset;
}

v3_result getParameterInfo(const int32_t index, v3_param_info* const info) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(index >= 0, V3_INVALID_ARG);

const uint32_t uindex = static_cast<uint32_t>(index);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
{
std::memset(info, 0, sizeof(v3_param_info));
info->param_id = index;
info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE;
info->step_count = fProgramCountMinusOne;
strncpy_utf16(info->title, "Current Program", 128);
strncpy_utf16(info->short_title, "Program", 128);
return V3_OK;
}
#endif

const uint32_t uindex = static_cast<uint32_t>(index) - fParameterOffset;
DISTRHO_SAFE_ASSERT_RETURN(uindex < fPlugin.getParameterCount(), V3_INVALID_ARG);

// set up flags
@@ -1082,15 +1116,35 @@ public:

v3_result getParameterStringForValue(const v3_param_id index, const double normalised, v3_str_128 output)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);

snprintf_f32_utf16(output, fPlugin.getParameterRanges(index).getUnnormalizedValue(normalised), 128);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
{
DISTRHO_SAFE_ASSERT_RETURN(normalised >= 0.0 && normalised <= 1.0, V3_INVALID_ARG);

const uint32_t program = std::round(normalised * fProgramCountMinusOne);
strncpy_utf16(output, fPlugin.getProgramName(program), 128);
return V3_OK;
}
#endif

const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
snprintf_f32_utf16(output, ranges.getUnnormalizedValue(normalised), 128);
return V3_OK;
}

v3_result getParameterValueForString(const v3_param_id index, int16_t*, double*)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
{
// TODO find program index based on name
return V3_NOT_IMPLEMENTED;
}
#endif

// TODO
return V3_NOT_IMPLEMENTED;
@@ -1098,29 +1152,57 @@ public:

double normalisedParameterToPlain(const v3_param_id index, const double normalised)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
return std::round(normalised * fProgramCountMinusOne);
#endif

return fPlugin.getParameterRanges(index).getUnnormalizedValue(normalised);
const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
return ranges.getUnnormalizedValue(normalised);
};

double plainParameterToNormalised(const v3_param_id index, const double plain)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
return std::max(0.0, std::min(1.0, plain / fProgramCountMinusOne));
#endif

return fPlugin.getParameterRanges(index).getNormalizedValue(plain);
const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
return ranges.getNormalizedValue(plain);
};

double getParameterNormalized(const v3_param_id index)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), 0.0);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, 0.0);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
return std::max(0.0, std::min(1.0, (double)fCurrentProgram / fProgramCountMinusOne));
#endif

const float value = fPlugin.getParameterValue(index);
return fPlugin.getParameterRanges(index).getNormalizedValue(value);
const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
return ranges.getNormalizedValue(value);
}

v3_result setParameterNormalized(const v3_param_id index, const double value)
{
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount(), V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(value >= 0.0 && value <= 1.0, V3_INVALID_ARG);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (index == 0)
{
fCurrentProgram = std::round(value * fProgramCountMinusOne);
fPlugin.loadProgram(fCurrentProgram);
return V3_OK;
}
#endif

const uint32_t hints = fPlugin.getParameterHints(index);
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
@@ -1158,6 +1240,7 @@ private:
v3_component_handler** fComponentHandler;

// Temporary data
const uint32_t fParameterOffset;
float* fParameterValues;
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
MidiEvent fMidiEvents[kMaxMidiEvents];
@@ -1165,6 +1248,10 @@ private:
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
v3_event_list** fHostEventOutputHandle;
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
uint32_t fCurrentProgram;
const uint32_t fProgramCountMinusOne;
#endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS
TimePosition fTimePosition;
#endif
@@ -2276,7 +2363,7 @@ struct dpf_factory : v3_plugin_factory_cpp {
info->class_flags = 0;
// DISTRHO_NAMESPACE::strncpy(info->sub_categories, "", sizeof(info->sub_categories)); // TODO
DISTRHO_NAMESPACE::strncpy(info->vendor, gPluginInfo.getMaker(), ARRAY_SIZE(info->vendor));
DISTRHO_NAMESPACE::snprintf_u32(info->version, gPluginInfo.getVersion(), ARRAY_SIZE(info->version));
DISTRHO_NAMESPACE::snprintf_u32(info->version, gPluginInfo.getVersion(), ARRAY_SIZE(info->version)); // FIXME
DISTRHO_NAMESPACE::strncpy(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); // TESTING use "VST 3.7" ?
return V3_OK;
};
@@ -2297,7 +2384,7 @@ struct dpf_factory : v3_plugin_factory_cpp {
info->class_flags = 0;
// DISTRHO_NAMESPACE::strncpy(info->sub_categories, "", ARRAY_SIZE(info->sub_categories)); // TODO
DISTRHO_NAMESPACE::strncpy_utf16(info->vendor, gPluginInfo.getMaker(), sizeof(info->vendor));
DISTRHO_NAMESPACE::snprintf_u32_utf16(info->version, gPluginInfo.getVersion(), ARRAY_SIZE(info->version));
DISTRHO_NAMESPACE::snprintf_u32_utf16(info->version, gPluginInfo.getVersion(), ARRAY_SIZE(info->version)); // FIXME
DISTRHO_NAMESPACE::strncpy_utf16(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); // TESTING use "VST 3.7" ?
return V3_OK;
};


+ 5
- 0
distrho/src/DistrhoUIPrivateData.hpp View File

@@ -331,6 +331,11 @@ struct UI::PrivateData {
# if (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || DISTRHO_PLUGIN_WANT_STATE)
parameterOffset += 1;
# endif
#endif
#ifdef DISTRHO_PLUGIN_TARGET_VST3
# if DISTRHO_PLUGIN_WANT_PROGRAMS
parameterOffset += 1;
# endif
#endif
}



+ 8
- 5
distrho/src/DistrhoUIVST3.cpp View File

@@ -42,12 +42,15 @@
#include "travesty/view.h"

/* TODO items:
* - see how to handle external non-embed UI build
* - program listener
* - state listener and sender
* - disable UI if non-embed UI build
* - parameter change listener
* - parameter change sender
* - program change listener
* - program change sender
* - state change listener
* - state change sender
* - sample rate change listener
* - call component handler restart with params-changed flag when setting program
* - call component handler restart with latency-changed flag when latency changes
* - call component handler restart with params-changed flag when setting program?
*/

START_NAMESPACE_DISTRHO


+ 1
- 1
distrho/src/travesty/base.h View File

@@ -29,7 +29,7 @@ struct v3_funknown;
template<class T> static inline
constexpr T* v3_cpp_obj(T** obj)
{
return (T*)((v3_funknown*)*obj + 1);
return (T*)((uint8_t*)*obj + sizeof(void*)*3);
}
#else
# ifndef constexpr


Loading…
Cancel
Save