Browse Source

Move common code to DistrhoDetails.hpp; add constexpr attributes

Signed-off-by: falkTX <falktx@falktx.com>
pull/421/head
falkTX 2 years ago
parent
commit
b29e345b8c
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
13 changed files with 1178 additions and 992 deletions
  1. +1097
    -0
      distrho/DistrhoDetails.hpp
  2. +2
    -941
      distrho/DistrhoPlugin.hpp
  3. +2
    -1
      distrho/DistrhoUI.hpp
  4. +10
    -11
      distrho/DistrhoUtils.hpp
  5. +15
    -1
      distrho/extra/String.hpp
  6. +7
    -6
      distrho/src/DistrhoPlugin.cpp
  7. +5
    -5
      distrho/src/DistrhoPluginCLAP.cpp
  8. +5
    -1
      distrho/src/DistrhoPluginChecks.h
  9. +15
    -7
      distrho/src/DistrhoPluginInternal.hpp
  10. +7
    -7
      distrho/src/DistrhoPluginLV2export.cpp
  11. +3
    -3
      distrho/src/DistrhoPluginVST2.cpp
  12. +8
    -8
      distrho/src/DistrhoPluginVST3.cpp
  13. +2
    -1
      distrho/src/DistrhoUI.cpp

+ 1097
- 0
distrho/DistrhoDetails.hpp
File diff suppressed because it is too large
View File


+ 2
- 941
distrho/DistrhoPlugin.hpp View File

@@ -17,951 +17,12 @@
#ifndef DISTRHO_PLUGIN_HPP_INCLUDED
#define DISTRHO_PLUGIN_HPP_INCLUDED

#include "extra/String.hpp"
#include "DistrhoDetails.hpp"
#include "extra/LeakDetector.hpp"
#include "src/DistrhoPluginChecks.h"

START_NAMESPACE_DISTRHO

/* ------------------------------------------------------------------------------------------------------------
* Audio Port Hints */

/**
@defgroup AudioPortHints Audio Port Hints

Various audio port hints.
@see AudioPort::hints
@{
*/

/**
Audio port can be used as control voltage (LV2 and JACK standalone only).
*/
static const uint32_t kAudioPortIsCV = 0x1;

/**
Audio port should be used as sidechan (LV2 and VST3 only).
This hint should not be used with CV style ports.
@note non-sidechain audio ports must exist in the plugin if this flag is set.
*/
static const uint32_t kAudioPortIsSidechain = 0x2;

/**
CV port has bipolar range (-1 to +1, or -5 to +5 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasBipolarRange = 0x10;

/**
CV port has negative unipolar range (-1 to 0, or -10 to 0 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasNegativeUnipolarRange = 0x20;

/**
CV port has positive unipolar range (0 to +1, or 0 to +10 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasPositiveUnipolarRange = 0x40;

/**
CV port has scaled range to match real values (-5 to +5v bipolar, +/-10 to 0v unipolar).
One other range flag is required if this flag is set.

When enabled, this makes the port a mod:CVPort, compatible with the MOD Devices platform.
*/
static const uint32_t kCVPortHasScaledRange = 0x80;

/**
CV port is optional, allowing hosts that do no CV ports to load the plugin.
When loaded in hosts that don't support CV, the float* buffer for this port will be null.
*/
static const uint32_t kCVPortIsOptional = 0x100;

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Parameter Hints */

/**
@defgroup ParameterHints Parameter Hints

Various parameter hints.
@see Parameter::hints
@{
*/

/**
Parameter is automatable (real-time safe).
@see Plugin::setParameterValue(uint32_t, float)
*/
static const uint32_t kParameterIsAutomatable = 0x01;

/** It was a typo, sorry.. */
DISTRHO_DEPRECATED_BY("kParameterIsAutomatable")
static const uint32_t kParameterIsAutomable = kParameterIsAutomatable;

/**
Parameter value is boolean.@n
It's always at either minimum or maximum value.
*/
static const uint32_t kParameterIsBoolean = 0x02;

/**
Parameter value is integer.
*/
static const uint32_t kParameterIsInteger = 0x04;

/**
Parameter value is logarithmic.
*/
static const uint32_t kParameterIsLogarithmic = 0x08;

/**
Parameter is of output type.@n
When unset, parameter is assumed to be of input type.

Parameter inputs are changed by the host and typically should not be changed by the plugin.@n
One exception is when changing programs, see Plugin::loadProgram().@n
The other exception is with parameter change requests, see Plugin::requestParameterValueChange().@n
Outputs are changed by the plugin and never modified by the host.

If you are targetting VST2, make sure to order your parameters so that all inputs are before any outputs.
*/
static const uint32_t kParameterIsOutput = 0x10;

/**
Parameter value is a trigger.@n
This means the value resets back to its default after each process/run call.@n
Cannot be used for output parameters.

@note Only officially supported under LV2. For other formats DPF simulates the behaviour.
*/
static const uint32_t kParameterIsTrigger = 0x20 | kParameterIsBoolean;

/**
Parameter should be hidden from the host and user-visible GUIs.@n
It is still saved and handled as any regular parameter, just not visible to the user
(for example in a host generated GUI)
*/
static const uint32_t kParameterIsHidden = 0x40;

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* State Hints */

/**
@defgroup StateHints State Hints

Various state hints.
@see State::hints
@{
*/

/**
State is visible and readable by hosts that support string-type plugin parameters.
*/
static const uint32_t kStateIsHostReadable = 0x01;

/**
State is writable by the host, allowing users to arbitrarily change the state.@n
For obvious reasons a writable state is also readable by the host.
*/
static const uint32_t kStateIsHostWritable = 0x02 | kStateIsHostReadable;

/**
State is a filename path instead of a regular string.@n
The readable and writable hints are required for filenames to work, and thus are automatically set.
*/
static const uint32_t kStateIsFilenamePath = 0x04 | kStateIsHostWritable;

/**
State is a base64 encoded string.
*/
static const uint32_t kStateIsBase64Blob = 0x08;

/**
State is for Plugin/DSP side only, meaning there is never a need to notify the UI when it changes.
*/
static const uint32_t kStateIsOnlyForDSP = 0x10;

/**
State is for UI side only.@n
If the DSP and UI are separate and the UI is not available, this property won't be saved.
*/
static const uint32_t kStateIsOnlyForUI = 0x20;

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Base Plugin structs */

/**
@defgroup BasePluginStructs Base Plugin Structs
@{
*/

/**
Parameter designation.@n
Allows a parameter to be specially designated for a task, like bypass.

Each designation is unique, there must be only one parameter that uses it.@n
The use of designated parameters is completely optional.

@note Designated parameters have strict ranges.
@see ParameterRanges::adjustForDesignation()
*/
enum ParameterDesignation {
/**
Null or unset designation.
*/
kParameterDesignationNull = 0,

/**
Bypass designation.@n
When on (> 0.5f), it means the plugin must run in a bypassed state.
*/
kParameterDesignationBypass = 1
};

/**
Predefined Port Groups Ids.

This enumeration provides a few commonly used groups for convenient use in plugins.
For preventing conflicts with user code, negative values are used here.
When rolling your own port groups, you MUST start their group ids from 0 and they MUST be sequential.

@see PortGroup
*/
enum PredefinedPortGroupsIds {
/**
Null or unset port group.
*/
kPortGroupNone = (uint32_t)-1,

/**
A single channel audio group.
*/
kPortGroupMono = (uint32_t)-2,

/**
A 2-channel discrete stereo audio group,
where the 1st audio port is the left channel and the 2nd port is the right channel.
*/
kPortGroupStereo = (uint32_t)-3
};

/**
Audio Port.

Can be used as CV port by specifying kAudioPortIsCV in hints,@n
but this is only supported in LV2 and JACK standalone formats.
*/
struct AudioPort {
/**
Hints describing this audio port.
@see AudioPortHints
*/
uint32_t hints;

/**
The name of this audio port.@n
An audio port name can contain any character, but hosts might have a hard time with non-ascii ones.@n
The name doesn't have to be unique within a plugin instance, but it's recommended.
*/
String name;

/**
The symbol of this audio port.@n
An audio port symbol is a short restricted name used as a machine and human readable identifier.@n
The first character must be one of _, a-z or A-Z and subsequent characters can be from _, a-z, A-Z and 0-9.
@note Audio port and parameter symbols MUST be unique within a plugin instance.
*/
String symbol;

/**
The group id that this audio/cv port belongs to.
No group is assigned by default.

You can use a group from PredefinedPortGroups or roll your own.@n
When rolling your own port groups, you MUST start their group ids from 0 and they MUST be sequential.
@see PortGroup, Plugin::initPortGroup
*/
uint32_t groupId;

/**
Default constructor for a regular audio port.
*/
AudioPort() noexcept
: hints(0x0),
name(),
symbol(),
groupId(kPortGroupNone) {}
};

/**
Parameter ranges.@n
This is used to set the default, minimum and maximum values of a parameter.

By default a parameter has 0.0 as minimum, 1.0 as maximum and 0.0 as default.@n
When changing this struct values you must ensure maximum > minimum and default is within range.
*/
struct ParameterRanges {
/**
Default value.
*/
float def;

/**
Minimum value.
*/
float min;

/**
Maximum value.
*/
float max;

/**
Default constructor, using 0.0 as default, 0.0 as minimum, 1.0 as maximum.
*/
ParameterRanges() noexcept
: def(0.0f),
min(0.0f),
max(1.0f) {}

/**
Constructor using custom values.
*/
ParameterRanges(float df, float mn, float mx) noexcept
: def(df),
min(mn),
max(mx) {}

/**
Fix the default value within range.
*/
void fixDefault() noexcept
{
fixValue(def);
}

/**
Fix a value within range.
*/
void fixValue(float& value) const noexcept
{
if (value < min)
value = min;
else if (value > max)
value = max;
}

/**
Get a fixed value within range.
*/
float getFixedValue(const float& value) const noexcept
{
if (value <= min)
return min;
if (value >= max)
return max;
return value;
}

/**
Get a value normalized to 0.0<->1.0.
*/
float getNormalizedValue(const float& value) const noexcept
{
const float normValue = (value - min) / (max - min);

if (normValue <= 0.0f)
return 0.0f;
if (normValue >= 1.0f)
return 1.0f;
return normValue;
}

/**
Get a value normalized to 0.0<->1.0.
Overloaded function using double precision values.
*/
double getNormalizedValue(const double& value) const noexcept
{
const double normValue = (value - min) / (max - min);

if (normValue <= 0.0)
return 0.0;
if (normValue >= 1.0)
return 1.0;
return normValue;
}

/**
Get a value normalized to 0.0<->1.0, fixed within range.
*/
float getFixedAndNormalizedValue(const float& value) const noexcept
{
if (value <= min)
return 0.0f;
if (value >= max)
return 1.0f;

const float normValue = (value - min) / (max - min);

if (normValue <= 0.0f)
return 0.0f;
if (normValue >= 1.0f)
return 1.0f;

return normValue;
}

/**
Get a value normalized to 0.0<->1.0, fixed within range.
Overloaded function using double precision values.
*/
double getFixedAndNormalizedValue(const double& value) const noexcept
{
if (value <= min)
return 0.0;
if (value >= max)
return 1.0;

const double normValue = (value - min) / (max - min);

if (normValue <= 0.0)
return 0.0;
if (normValue >= 1.0)
return 1.0;

return normValue;
}

/**
Get a proper value previously normalized to 0.0<->1.0.
*/
float getUnnormalizedValue(const float& value) const noexcept
{
if (value <= 0.0f)
return min;
if (value >= 1.0f)
return max;

return value * (max - min) + min;
}

/**
Get a proper value previously normalized to 0.0<->1.0.
Overloaded function using double precision values.
*/
double getUnnormalizedValue(const double& value) const noexcept
{
if (value <= 0.0)
return min;
if (value >= 1.0)
return max;

return value * (max - min) + min;
}
};

/**
Parameter enumeration value.@n
A string representation of a plugin parameter value.@n
Used together can be used to give meaning to parameter values, working as an enumeration.
*/
struct ParameterEnumerationValue {
/**
Parameter value.
*/
float value;

/**
String representation of this value.
*/
String label;

/**
Default constructor, using 0.0 as value and empty label.
*/
ParameterEnumerationValue() noexcept
: value(0.0f),
label() {}

/**
Constructor using custom values.
*/
ParameterEnumerationValue(float v, const char* l) noexcept
: value(v),
label(l) {}
};

/**
Collection of parameter enumeration values.@n
Handy class to handle the lifetime and count of all enumeration values.
*/
struct ParameterEnumerationValues {
/**
Number of elements allocated in @values.
*/
uint8_t count;

/**
Wherever the host is to be restricted to only use enumeration values.

@note This mode is only a hint! Not all hosts and plugin formats support this mode.
*/
bool restrictedMode;

/**
Array of @ParameterEnumerationValue items.@n
This pointer must be null or have been allocated on the heap with `new ParameterEnumerationValue[count]`.
*/
ParameterEnumerationValue* values;

/**
Default constructor, for zero enumeration values.
*/
ParameterEnumerationValues() noexcept
: count(0),
restrictedMode(false),
values() {}

/**
Constructor using custom values.@n
The pointer to @values must have been allocated on the heap with `new`.
*/
ParameterEnumerationValues(uint32_t c, bool r, ParameterEnumerationValue* v) noexcept
: count(c),
restrictedMode(r),
values(v) {}

~ParameterEnumerationValues() noexcept
{
count = 0;
restrictedMode = false;

if (values != nullptr)
{
delete[] values;
values = nullptr;
}
}

DISTRHO_DECLARE_NON_COPYABLE(ParameterEnumerationValues)
};

/**
Parameter.
*/
struct Parameter {
/**
Hints describing this parameter.
@see ParameterHints
*/
uint32_t hints;

/**
The name of this parameter.@n
A parameter name can contain any character, but hosts might have a hard time with non-ascii ones.@n
The name doesn't have to be unique within a plugin instance, but it's recommended.
*/
String name;

/**
The short name of this parameter.@n
Used when displaying the parameter name in a very limited space.
@note This value is optional, the full name is used when the short one is missing.
*/
String shortName;

/**
The symbol of this parameter.@n
A parameter symbol is a short restricted name used as a machine and human readable identifier.@n
The first character must be one of _, a-z or A-Z and subsequent characters can be from _, a-z, A-Z and 0-9.
@note Parameter symbols MUST be unique within a plugin instance.
*/
String symbol;

/**
The unit of this parameter.@n
This means something like "dB", "kHz" and "ms".@n
Can be left blank if a unit does not apply to this parameter.
*/
String unit;

/**
An extensive description/comment about the parameter.
@note This value is optional and only used for LV2.
*/
String description;

/**
Ranges of this parameter.@n
The ranges describe the default, minimum and maximum values.
*/
ParameterRanges ranges;

/**
Enumeration values.@n
Can be used to give meaning to parameter values, working as an enumeration.
*/
ParameterEnumerationValues enumValues;

/**
Designation for this parameter.
*/
ParameterDesignation designation;

/**
MIDI CC to use by default on this parameter.@n
A value of 0 or 32 (bank change) is considered invalid.@n
Must also be less or equal to 120.
@note This value is only a hint! Hosts might map it automatically or completely ignore it.
*/
uint8_t midiCC;

/**
The group id that this parameter belongs to.
No group is assigned by default.

You can use a group from PredefinedPortGroups or roll your own.@n
When rolling your own port groups, you MUST start their group ids from 0 and they MUST be sequential.
@see PortGroup, Plugin::initPortGroup
*/
uint32_t groupId;

/**
Default constructor for a null parameter.
*/
Parameter() noexcept
: hints(0x0),
name(),
shortName(),
symbol(),
unit(),
ranges(),
enumValues(),
designation(kParameterDesignationNull),
midiCC(0),
groupId(kPortGroupNone) {}

/**
Constructor using custom values.
*/
Parameter(uint32_t h, const char* n, const char* s, const char* u, float def, float min, float max) noexcept
: hints(h),
name(n),
shortName(),
symbol(s),
unit(u),
ranges(def, min, max),
enumValues(),
designation(kParameterDesignationNull),
midiCC(0),
groupId(kPortGroupNone) {}

/**
Initialize a parameter for a specific designation.
*/
void initDesignation(ParameterDesignation d) noexcept
{
designation = d;

switch (d)
{
case kParameterDesignationNull:
break;
case kParameterDesignationBypass:
hints = kParameterIsAutomatable|kParameterIsBoolean|kParameterIsInteger;
name = "Bypass";
shortName = "Bypass";
symbol = "dpf_bypass";
unit = "";
midiCC = 0;
groupId = kPortGroupNone;
ranges.def = 0.0f;
ranges.min = 0.0f;
ranges.max = 1.0f;
break;
}
}
};

/**
Port Group.@n
Allows to group together audio/cv ports or parameters.

Each unique group MUST have an unique symbol and a name.
A group can be applied to both inputs and outputs (at the same time).
The same group cannot be used in audio ports and parameters.

When both audio and parameter groups are used, audio groups MUST be defined first.
That is, group indexes start with audio ports, then parameters.

An audio port group logically combines ports which should be considered part of the same stream.@n
For example, two audio ports in a group may form a stereo stream.

A parameter group provides meta-data to the host to indicate that some parameters belong together.

The use of port groups is completely optional.

@see Plugin::initPortGroup, AudioPort::group, Parameter::group
*/
struct PortGroup {
/**
The name of this port group.@n
A port group name can contain any character, but hosts might have a hard time with non-ascii ones.@n
The name doesn't have to be unique within a plugin instance, but it's recommended.
*/
String name;

/**
The symbol of this port group.@n
A port group symbol is a short restricted name used as a machine and human readable identifier.@n
The first character must be one of _, a-z or A-Z and subsequent characters can be from _, a-z, A-Z and 0-9.
@note Port group symbols MUST be unique within a plugin instance.
*/
String symbol;
};

/**
State.

In DPF states refer to key:value string pairs, used to store arbitrary non-parameter data.@n
By default states are completely internal to the plugin and not visible by the host.@n
Flags can be set to allow hosts to see and/or change them.

TODO API under construction
*/
struct State {
/**
Hints describing this state.
@note Changing these hints can break compatibility with previously saved data.
@see StateHints
*/
uint32_t hints;

/**
The key or "symbol" of this state.@n
A state key is a short restricted name used as a machine and human readable identifier.
@note State keys MUST be unique within a plugin instance.
TODO define rules for allowed characters, must be usable as URI non-encoded parameters
*/
String key;

/**
The default value of this state.@n
Can be left empty if considered a valid initial state.
*/
String defaultValue;

/**
String representation of this state.
*/
String label;

/**
An extensive description/comment about this state.
@note This value is optional and only used for LV2.
*/
String description;

#ifdef __MOD_DEVICES__
/**
The file types that a filename path state supports, written as a comma-separated string without whitespace.
Currently supported file types are:
- audioloop: Audio Loops, meant to be used for looper-style plugins
- audiorecording: Audio Recordings, triggered by plugins and stored in the unit
- audiosample: One-shot Audio Samples, meant to be used for sampler-style plugins
- audiotrack: Audio Tracks, meant to be used as full-performance/song or backtrack
- cabsim: Speaker Cabinets, meant as small IR audio files
- h2drumkit: Hydrogen Drumkits, must use h2drumkit file extension
- ir: Impulse Responses
- midiclip: MIDI Clips, to be used in sync with host tempo, must have mid or midi file extension
- midisong: MIDI Songs, meant to be used as full-performance/song or backtrack
- sf2: SF2 Instruments, must have sf2 or sf3 file extension
- sfz: SFZ Instruments, must have sfz file extension

@note This is a custom extension only valid in builds MOD Audio.
*/
String fileTypes;
#endif

/**
Default constructor for a null state.
*/
State() noexcept
: hints(0x0),
key(),
defaultValue(),
label(),
description() {}
};

/**
MIDI event.
*/
struct MidiEvent {
/**
Size of internal data.
*/
static const uint32_t kDataSize = 4;

/**
Time offset in frames.
*/
uint32_t frame;

/**
Number of bytes used.
*/
uint32_t size;

/**
MIDI data.@n
If size > kDataSize, dataExt is used (otherwise null).

When dataExt is used, the event holder is responsible for
keeping the pointer valid during the entirety of the run function.
*/
uint8_t data[kDataSize];
const uint8_t* dataExt;
};

/**
Time position.@n
The @a playing and @a frame values are always valid.@n
BBT values are only valid when @a bbt.valid is true.

This struct is inspired by the [JACK Transport API](https://jackaudio.org/api/structjack__position__t.html).
*/
struct TimePosition {
/**
Wherever the host transport is playing/rolling.
*/
bool playing;

/**
Current host transport position in frames.
@note This value is not always monotonic,
with some plugin hosts assigning it based on a source that can accumulate rounding errors.
*/
uint64_t frame;

/**
Bar-Beat-Tick time position.
*/
struct BarBeatTick {
/**
Wherever the host transport is using BBT.@n
If false you must not read from this struct.
*/
bool valid;

/**
Current bar.@n
Should always be > 0.@n
The first bar is bar '1'.
*/
int32_t bar;

/**
Current beat within bar.@n
Should always be > 0 and <= @a beatsPerBar.@n
The first beat is beat '1'.
*/
int32_t beat;

/**
Current tick within beat.@n
Should always be >= 0 and < @a ticksPerBeat.@n
The first tick is tick '0'.
@note Fraction part of tick is only available on some plugin formats.
*/
double tick;

/**
Number of ticks that have elapsed between frame 0 and the first beat of the current measure.
*/
double barStartTick;

/**
Time signature "numerator".
*/
float beatsPerBar;

/**
Time signature "denominator".
*/
float beatType;

/**
Number of ticks within a beat.@n
Usually a moderately large integer with many denominators, such as 1920.0.
*/
double ticksPerBeat;

/**
Number of beats per minute.
*/
double beatsPerMinute;

/**
Default constructor for a null BBT time position.
*/
BarBeatTick() noexcept
: valid(false),
bar(0),
beat(0),
tick(0),
barStartTick(0.0),
beatsPerBar(0.0f),
beatType(0.0f),
ticksPerBeat(0.0),
beatsPerMinute(0.0) {}

/**
Reinitialize this position using the default null initialization.
*/
void clear() noexcept
{
valid = false;
bar = 0;
beat = 0;
tick = 0;
barStartTick = 0.0;
beatsPerBar = 0.0f;
beatType = 0.0f;
ticksPerBeat = 0.0;
beatsPerMinute = 0.0;
}
} bbt;

/**
Default constructor for a time position.
*/
TimePosition() noexcept
: playing(false),
frame(0),
bbt() {}

/**
Reinitialize this position using the default null initialization.
*/
void clear() noexcept
{
playing = false;
frame = 0;
bbt.clear();
}
};

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* DPF Plugin */

@@ -991,7 +52,7 @@ struct TimePosition {
When enabled you need to implement initProgramName() and loadProgram().

DISTRHO_PLUGIN_WANT_STATE activates internal state features.@n
When enabled you need to implement initStateKey() and setState().
When enabled you need to implement initState() and setState().

The process function run() changes wherever DISTRHO_PLUGIN_WANT_MIDI_INPUT is enabled or not.@n
When enabled it provides midi input events.


+ 2
- 1
distrho/DistrhoUI.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -17,6 +17,7 @@
#ifndef DISTRHO_UI_HPP_INCLUDED
#define DISTRHO_UI_HPP_INCLUDED

#include "DistrhoDetails.hpp"
#include "extra/LeakDetector.hpp"
#include "src/DistrhoPluginChecks.h"



+ 10
- 11
distrho/DistrhoUtils.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -58,7 +58,7 @@ inline float round(float __x)
#define DISTRHO_MACRO_AS_STRING_VALUE(MACRO) #MACRO
#define DISTRHO_MACRO_AS_STRING(MACRO) DISTRHO_MACRO_AS_STRING_VALUE(MACRO)

/* ------------------------------------------------------------------------------------------------------------
/* --------------------------------------------------------------------------------------------------------------------
* misc functions */

/**
@@ -94,7 +94,7 @@ void d_pass() noexcept {}

/** @} */

/* ------------------------------------------------------------------------------------------------------------
/* --------------------------------------------------------------------------------------------------------------------
* string print functions */

/**
@@ -240,7 +240,7 @@ void d_safe_exception(const char* const exception, const char* const file, const

/** @} */

/* ------------------------------------------------------------------------------------------------------------
/* --------------------------------------------------------------------------------------------------------------------
* math functions */

/**
@@ -254,7 +254,7 @@ void d_safe_exception(const char* const exception, const char* const file, const
Returns true if they match.
*/
template<typename T>
static inline
static inline constexpr
bool d_isEqual(const T& v1, const T& v2)
{
return std::abs(v1-v2) < std::numeric_limits<T>::epsilon();
@@ -265,7 +265,7 @@ bool d_isEqual(const T& v1, const T& v2)
Returns true if they don't match.
*/
template<typename T>
static inline
static inline constexpr
bool d_isNotEqual(const T& v1, const T& v2)
{
return std::abs(v1-v2) >= std::numeric_limits<T>::epsilon();
@@ -275,7 +275,7 @@ bool d_isNotEqual(const T& v1, const T& v2)
Safely check if a floating point number is zero.
*/
template<typename T>
static inline
static inline constexpr
bool d_isZero(const T& value)
{
return std::abs(value) < std::numeric_limits<T>::epsilon();
@@ -285,7 +285,7 @@ bool d_isZero(const T& value)
Safely check if a floating point number is not zero.
*/
template<typename T>
static inline
static inline constexpr
bool d_isNotZero(const T& value)
{
return std::abs(value) >= std::numeric_limits<T>::epsilon();
@@ -311,7 +311,8 @@ uint32_t d_nextPowerOf2(uint32_t size) noexcept

/** @} */

// -----------------------------------------------------------------------
/* --------------------------------------------------------------------------------------------------------------------
* math functions */

#ifndef DONT_SET_USING_DISTRHO_NAMESPACE
// If your code uses a lot of DISTRHO classes, then this will obviously save you
@@ -320,6 +321,4 @@ uint32_t d_nextPowerOf2(uint32_t size) noexcept
using namespace DISTRHO_NAMESPACE;
#endif

// -----------------------------------------------------------------------

#endif // DISTRHO_UTILS_HPP_INCLUDED

+ 15
- 1
distrho/extra/String.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -22,6 +22,10 @@

#include <algorithm>

#if __cplusplus >= 201703L
# include <string_view>
#endif

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
@@ -87,6 +91,16 @@ public:
_dup(strBuf);
}

#if __cplusplus >= 201703L
/*
* constexpr compatible variant.
*/
explicit constexpr String(const std::string_view& strView) noexcept
: fBuffer(const_cast<char*>(strView.data())),
fBufferLen(strView.size()),
fBufferAlloc(false) {}
#endif

/*
* Integer.
*/


+ 7
- 6
distrho/src/DistrhoPlugin.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -31,11 +31,12 @@ bool d_nextCanRequestParameterValueChanges = false;
/* ------------------------------------------------------------------------------------------------------------
* Static fallback data, see DistrhoPluginInternal.hpp */

const String PluginExporter::sFallbackString;
/* */ AudioPortWithBusId PluginExporter::sFallbackAudioPort;
const ParameterRanges PluginExporter::sFallbackRanges;
const ParameterEnumerationValues PluginExporter::sFallbackEnumValues;
const PortGroupWithId PluginExporter::sFallbackPortGroup;
const String PluginExporter::sFallbackString;
/* */ AudioPortWithBusId PluginExporter::sFallbackAudioPort;
const ParameterRanges PluginExporter::sFallbackRanges;
const ParameterEnumerationDetails PluginExporter::sFallbackEnumDetails;
const ParameterEnumerationValues PluginExporter::sFallbackEnumValues;
const PortGroupWithId PluginExporter::sFallbackPortGroup;

/* ------------------------------------------------------------------------------------------------------------
* Plugin */


+ 5
- 5
distrho/src/DistrhoPluginCLAP.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -1181,9 +1181,9 @@ public:

for (uint32_t i=0; i < enumValues.count; ++i)
{
if (d_isEqual(static_cast<double>(enumValues.values[i].value), value))
if (d_isEqual(static_cast<double>(enumValues.ptr[i].value), value))
{
d_strncpy(display, enumValues.values[i].label, size);
d_strncpy(display, enumValues.ptr[i].label, size);
return true;
}
}
@@ -1203,9 +1203,9 @@ public:

for (uint32_t i=0; i < enumValues.count; ++i)
{
if (std::strcmp(display, enumValues.values[i].label) == 0)
if (std::strcmp(display, enumValues.ptr[i].label) == 0)
{
*value = enumValues.values[i].value;
*value = enumValues.ptr[i].value;
return true;
}
}


+ 5
- 1
distrho/src/DistrhoPluginChecks.h View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -17,6 +17,10 @@
#ifndef DISTRHO_PLUGIN_CHECKS_H_INCLUDED
#define DISTRHO_PLUGIN_CHECKS_H_INCLUDED

#ifndef DISTRHO_DETAILS_HPP_INCLUDED
# error wrong include order
#endif

#include "DistrhoPluginInfo.h"

// -----------------------------------------------------------------------


+ 15
- 7
distrho/src/DistrhoPluginInternal.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -704,11 +704,18 @@ public:
return fData->parameters[index].description;
}

const ParameterEnumerationDetails& getParameterEnumDetails(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackEnumDetails);

return fData->parameters[index].enumValues;
}

const ParameterEnumerationValues& getParameterEnumValues(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackEnumValues);

return fData->parameters[index].enumValues;
return fData->parameters[index].enumValues.values;
}

const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept
@@ -1045,11 +1052,12 @@ private:
// -------------------------------------------------------------------
// Static fallback data, see DistrhoPlugin.cpp

static const String sFallbackString;
static /* */ AudioPortWithBusId sFallbackAudioPort;
static const ParameterRanges sFallbackRanges;
static const ParameterEnumerationValues sFallbackEnumValues;
static const PortGroupWithId sFallbackPortGroup;
static const String sFallbackString;
static /* */ AudioPortWithBusId sFallbackAudioPort;
static const ParameterRanges sFallbackRanges;
static const ParameterEnumerationDetails sFallbackEnumDetails;
static const ParameterEnumerationValues sFallbackEnumValues;
static const PortGroupWithId sFallbackPortGroup;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)
};


+ 7
- 7
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -820,16 +820,16 @@ void lv2_generate_ttl(const char* const basename)
}

// enumeration
const ParameterEnumerationValues& enumValues(plugin.getParameterEnumValues(i));
const ParameterEnumerationDetails& enumDetails(plugin.getParameterEnumDetails(i));

if (enumValues.count > 0)
if (enumDetails.count > 0)
{
if (enumValues.count >= 2 && enumValues.restrictedMode)
if (enumDetails.count >= 2 && enumDetails.restrictedMode)
pluginString += " lv2:portProperty lv2:enumeration ;\n";

for (uint8_t j=0; j < enumValues.count; ++j)
for (uint8_t j=0; j < enumDetails.count; ++j)
{
const ParameterEnumerationValue& enumValue(enumValues.values[j]);
const ParameterEnumerationValue& enumValue(enumDetails.values[j]);

if (j == 0)
pluginString += " lv2:scalePoint [\n";
@@ -851,7 +851,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " rdf:value " + String(enumValue.value) + " ;\n";
}

if (j+1 == enumValues.count)
if (j+1 == enumDetails.count)
pluginString += " ] ;\n";
else
pluginString += " ] ,\n";


+ 3
- 3
distrho/src/DistrhoPluginVST2.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -527,10 +527,10 @@ public:

for (uint8_t i = 0; i < enumValues.count; ++i)
{
if (d_isNotEqual(value, enumValues.values[i].value))
if (d_isNotEqual(value, enumValues.ptr[i].value))
continue;

strncpy((char*)ptr, enumValues.values[i].label.buffer(), 24);
strncpy((char*)ptr, enumValues.ptr[i].label.buffer(), 24);
return 1;
}



+ 8
- 8
distrho/src/DistrhoPluginVST3.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -1711,7 +1711,7 @@ public:
// set up flags
int32_t flags = 0;

const ParameterEnumerationValues& enumValues(fPlugin.getParameterEnumValues(index));
const ParameterEnumerationDetails& enumDetails(fPlugin.getParameterEnumDetails(index));
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
const uint32_t hints = fPlugin.getParameterHints(index);

@@ -1737,10 +1737,10 @@ public:
else if (hints & kParameterIsInteger)
step_count = ranges.max - ranges.min;

if (enumValues.count >= 2 && enumValues.restrictedMode)
if (enumDetails.count >= 2 && enumDetails.restrictedMode)
{
flags |= V3_PARAM_IS_LIST;
step_count = enumValues.count - 1;
step_count = enumDetails.count - 1;
}

info->flags = flags;
@@ -1810,9 +1810,9 @@ public:

for (uint32_t i=0; i < enumValues.count; ++i)
{
if (d_isEqual(enumValues.values[i].value, value))
if (d_isEqual(enumValues.ptr[i].value, value))
{
strncpy_utf16(output, enumValues.values[i].label, 128);
strncpy_utf16(output, enumValues.ptr[i].label, 128);
return V3_OK;
}
}
@@ -1874,9 +1874,9 @@ public:

for (uint32_t i=0; i < enumValues.count; ++i)
{
if (strcmp_utf16(input, enumValues.values[i].label))
if (strcmp_utf16(input, enumValues.ptr[i].label))
{
*output = ranges.getNormalizedValue(enumValues.values[i].value);
*output = ranges.getNormalizedValue(enumValues.ptr[i].value);
return V3_OK;
}
}


+ 2
- 1
distrho/src/DistrhoUI.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -14,6 +14,7 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "DistrhoDetails.hpp"
#include "src/DistrhoPluginChecks.h"
#include "src/DistrhoDefines.h"



Loading…
Cancel
Save