Browse Source

Merge: origin/develop -> improve/state-allocation

pull/479/head
sevenc-nanashi 3 months ago
parent
commit
116dd854dd
23 changed files with 437 additions and 140 deletions
  1. +3
    -4
      .github/workflows/build.yml
  2. +9
    -9
      .github/workflows/cmake.yml
  3. +9
    -9
      .github/workflows/example-plugins.yml
  4. +6
    -5
      .gitignore
  5. +1
    -1
      README.md
  6. +7
    -1
      dgl/EventHandlers.hpp
  7. +91
    -1
      dgl/src/EventHandlers.cpp
  8. +10
    -14
      dgl/src/WindowPrivateData.cpp
  9. +1
    -1
      dgl/src/WindowPrivateData.hpp
  10. +2
    -1
      dgl/src/pugl.cpp
  11. +28
    -4
      distrho/DistrhoDetails.hpp
  12. +6
    -0
      distrho/DistrhoInfo.hpp
  13. +18
    -4
      distrho/extra/String.hpp
  14. +5
    -3
      distrho/extra/WebViewImpl.cpp
  15. +148
    -68
      distrho/src/DistrhoPluginAU.cpp
  16. +58
    -11
      distrho/src/DistrhoPluginCLAP.cpp
  17. +11
    -0
      distrho/src/DistrhoPluginChecks.h
  18. +10
    -0
      distrho/src/DistrhoPluginLV2export.cpp
  19. +6
    -0
      distrho/src/DistrhoPluginVST3.cpp
  20. +3
    -0
      distrho/src/DistrhoUIAU.mm
  21. +2
    -2
      distrho/src/DistrhoUIInternal.hpp
  22. +1
    -1
      distrho/src/DistrhoUIVST3.cpp
  23. +2
    -1
      distrho/src/lv2/lv2_kxstudio_properties.h

+ 3
- 4
.github/workflows/build.yml View File

@@ -13,10 +13,9 @@ jobs:
strategy:
matrix:
os:
# wrong use of AU MIDIPacket
# - macos-12
# - macos-13
# - macos-14
- macos-13
- macos-14
- macos-15
# webgui failure
# - ubuntu-20.04
- ubuntu-22.04


+ 9
- 9
.github/workflows/cmake.yml View File

@@ -42,11 +42,11 @@ jobs:
suffix: _24_04
target: ${{ matrix.target }}

macos-12:
macos-13:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-12
runs-on: macos-13
steps:
- uses: actions/checkout@v4
with:
@@ -54,14 +54,14 @@ jobs:
- uses: distrho/dpf-cmake-action@v1
with:
dpf_path: .
suffix: _12
suffix: _13
target: ${{ matrix.target }}

macos-13:
macos-14:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
@@ -69,14 +69,14 @@ jobs:
- uses: distrho/dpf-cmake-action@v1
with:
dpf_path: .
suffix: _13
suffix: _14
target: ${{ matrix.target }}

macos-14:
macos-15:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-14
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
@@ -84,7 +84,7 @@ jobs:
- uses: distrho/dpf-cmake-action@v1
with:
dpf_path: .
suffix: _14
suffix: _15
target: ${{ matrix.target }}

cmake_win32:


+ 9
- 9
.github/workflows/example-plugins.yml View File

@@ -39,11 +39,11 @@ jobs:
suffix: _24_04
target: ${{ matrix.target }}

macos-12:
macos-13:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-12
runs-on: macos-13
steps:
- uses: actions/checkout@v4
with:
@@ -51,14 +51,14 @@ jobs:
- uses: distrho/dpf-makefile-action@v1
with:
dpf_path: .
suffix: _12
suffix: _13
target: ${{ matrix.target }}

macos-13:
macos-14:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
@@ -66,14 +66,14 @@ jobs:
- uses: distrho/dpf-makefile-action@v1
with:
dpf_path: .
suffix: _13
suffix: _14
target: ${{ matrix.target }}

macos-14:
macos-15:
strategy:
matrix:
target: [macos-intel, macos-universal, macos-10.15]
runs-on: macos-14
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
@@ -81,5 +81,5 @@ jobs:
- uses: distrho/dpf-makefile-action@v1
with:
dpf_path: .
suffix: _14
suffix: _15
target: ${{ matrix.target }}

+ 6
- 5
.gitignore View File

@@ -15,8 +15,9 @@ CMakeFiles
CMakeSettings.json
cmake_install.cmake

bin/
build/
docs/
utils/lv2_ttl_generator
utils/lv2_ttl_generator.dSYM/
/bin/
/build/
/docs/
/khronos/
/utils/lv2_ttl_generator
/utils/lv2_ttl_generator.dSYM/

+ 1
- 1
README.md View File

@@ -31,7 +31,7 @@ Bug reports happen on the [DPF github project](https://github.com/DISTRHO/DPF/is

Online documentation is available at [https://distrho.github.io/DPF/](https://distrho.github.io/DPF/).

Online help and discussion about DPF happens in the [kx.studio chat, DPF room](https://chat.kx.studio/channel/dpf).
Online help and discussion about DPF happens in the [DPF github discussions](https://github.com/DISTRHO/DPF/discussions).


## List of plugins made with DPF:


+ 7
- 1
dgl/EventHandlers.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 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
@@ -63,6 +63,9 @@ public:
bool isCheckable() const noexcept;
void setCheckable(bool checkable) noexcept;

bool isEnabled() const noexcept;
void setEnabled(bool enabled, bool appliesToEventInput = true) noexcept;

Point<double> getLastClickPosition() const noexcept;
Point<double> getLastMotionPosition() const noexcept;

@@ -121,6 +124,9 @@ public:
KnobEventHandler& operator=(const KnobEventHandler& other);
virtual ~KnobEventHandler();

bool isEnabled() const noexcept;
void setEnabled(bool enabled, bool appliesToEventInput = true) noexcept;

// if setStep(1) has been called before, this returns true
bool isInteger() const noexcept;



+ 91
- 1
dgl/src/EventHandlers.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 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,6 +31,8 @@ struct ButtonEventHandler::PrivateData {
int state;
bool checkable;
bool checked;
bool enabled;
bool enabledInput;

Point<double> lastClickPos;
Point<double> lastMotionPos;
@@ -44,11 +46,16 @@ struct ButtonEventHandler::PrivateData {
state(kButtonStateDefault),
checkable(false),
checked(false),
enabled(true),
enabledInput(true),
lastClickPos(0, 0),
lastMotionPos(0, 0) {}

bool mouseEvent(const Widget::MouseEvent& ev)
{
if (! enabledInput)
return false;

lastClickPos = ev.pos;

// button was released, handle it now
@@ -98,6 +105,9 @@ struct ButtonEventHandler::PrivateData {

bool motionEvent(const Widget::MotionEvent& ev)
{
if (! enabledInput)
return false;

// keep pressed
if (button != -1)
{
@@ -171,6 +181,27 @@ struct ButtonEventHandler::PrivateData {
}
}

void setEnabled(const bool enabled2, const bool appliesToEventInput) noexcept
{
if (appliesToEventInput)
enabledInput = enabled2;

if (enabled == enabled2)
return;

// reset temp vars if disabling
if (! enabled2)
{
button = -1;
state = kButtonStateDefault;
lastClickPos = Point<double>();
lastMotionPos = Point<double>();
}

enabled = enabled2;
widget->repaint();
}

DISTRHO_DECLARE_NON_COPYABLE(PrivateData)
};

@@ -217,6 +248,16 @@ void ButtonEventHandler::setCheckable(const bool checkable) noexcept
pData->checkable = checkable;
}

bool ButtonEventHandler::isEnabled() const noexcept
{
return pData->enabled;
}

void ButtonEventHandler::setEnabled(const bool enabled, const bool appliesToEventInput) noexcept
{
pData->setEnabled(enabled, appliesToEventInput);
}

Point<double> ButtonEventHandler::getLastClickPosition() const noexcept
{
return pData->lastClickPos;
@@ -281,6 +322,8 @@ struct KnobEventHandler::PrivateData {
float value;
float valueDef;
float valueTmp;
bool enabled;
bool enabledInput;
bool usingDefault;
bool usingLog;
Orientation orientation;
@@ -301,6 +344,8 @@ struct KnobEventHandler::PrivateData {
value(0.5f),
valueDef(value),
valueTmp(value),
enabled(true),
enabledInput(true),
usingDefault(false),
usingLog(false),
orientation(Vertical),
@@ -320,6 +365,8 @@ struct KnobEventHandler::PrivateData {
value(other->value),
valueDef(other->valueDef),
valueTmp(value),
enabled(other->enabled),
enabledInput(other->enabledInput),
usingDefault(other->usingDefault),
usingLog(other->usingLog),
orientation(other->orientation),
@@ -338,6 +385,8 @@ struct KnobEventHandler::PrivateData {
value = other->value;
valueDef = other->valueDef;
valueTmp = value;
enabled = other->enabled;
enabledInput = other->enabledInput;
usingDefault = other->usingDefault;
usingLog = other->usingLog;
orientation = other->orientation;
@@ -363,6 +412,9 @@ struct KnobEventHandler::PrivateData {

bool mouseEvent(const Widget::MouseEvent& ev, const double scaleFactor)
{
if (! enabledInput)
return false;

if (ev.button != 1)
return false;

@@ -416,6 +468,9 @@ struct KnobEventHandler::PrivateData {

bool motionEvent(const Widget::MotionEvent& ev, const double scaleFactor)
{
if (! enabledInput)
return false;

if ((state & kKnobStateDragging) == 0x0)
return false;

@@ -501,6 +556,9 @@ struct KnobEventHandler::PrivateData {

bool scrollEvent(const Widget::ScrollEvent& ev)
{
if (! enabledInput)
return false;

if (! widget->contains(ev.pos))
return false;

@@ -541,6 +599,28 @@ struct KnobEventHandler::PrivateData {
return ((usingLog ? invlogscale(value) : value) - minimum) / diff;
}

void setEnabled(const bool enabled2, const bool appliesToEventInput) noexcept
{
if (appliesToEventInput)
enabledInput = enabled2;

if (enabled == enabled2)
return;

// reset temp vars if disabling
if (! enabled2)
{
state = kKnobStateDefault;
lastX = 0.0;
lastY = 0.0;
lastClickTime = 0;
valueTmp = value;
}

enabled = enabled2;
widget->repaint();
}

void setRange(const float min, const float max) noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(max > min,);
@@ -598,6 +678,16 @@ KnobEventHandler::~KnobEventHandler()
delete pData;
}

bool KnobEventHandler::isEnabled() const noexcept
{
return pData->enabled;
}

void KnobEventHandler::setEnabled(const bool enabled, const bool appliesToEventInput) noexcept
{
pData->setEnabled(enabled, appliesToEventInput);
}

bool KnobEventHandler::isInteger() const noexcept
{
return d_isEqual(pData->step, 1.f);


+ 10
- 14
dgl/src/WindowPrivateData.cpp View File

@@ -579,11 +579,11 @@ void Window::PrivateData::runAsModal(const bool blockWait)
// -----------------------------------------------------------------------
// pugl events

void Window::PrivateData::onPuglConfigure(const double width, const double height)
void Window::PrivateData::onPuglConfigure(const uint width, const uint height)
{
DISTRHO_SAFE_ASSERT_INT2_RETURN(width > 1 && height > 1, width, height,);

DGL_DBGp("PUGL: onReshape : %f %f\n", width, height);
DGL_DBGp("PUGL: onReshape : %d %d\n", width, height);

if (autoScaling)
{
@@ -1188,25 +1188,21 @@ static int printEvent(const PuglEvent* event, const char* prefix, const bool ver

if (verbose) {
switch (event->type) {
case PUGL_CREATE:
return fprintf(stderr, "%sCreate\n", prefix);
case PUGL_DESTROY:
return fprintf(stderr, "%sDestroy\n", prefix);
case PUGL_MAP:
return fprintf(stderr, "%sMap\n", prefix);
case PUGL_UNMAP:
return fprintf(stderr, "%sUnmap\n", prefix);
case PUGL_UPDATE:
return 0; // fprintf(stderr, "%sUpdate\n", prefix);
case PUGL_REALIZE:
return PRINT("%sRealize\n", prefix);
case PUGL_UNREALIZE:
return PRINT("%sUnrealize\n", prefix);
case PUGL_CONFIGURE:
return PRINT("%sConfigure " PFMT " " PFMT "\n",
return PRINT("%sConfigure %d %d %d %d\n",
prefix,
event->configure.x,
event->configure.y,
event->configure.width,
event->configure.height);
case PUGL_UPDATE:
return 0; // fprintf(stderr, "%sUpdate\n", prefix);
case PUGL_EXPOSE:
return PRINT("%sExpose " PFMT " " PFMT "\n",
return PRINT("%sExpose %d %d %d %d\n",
prefix,
event->expose.x,
event->expose.y,


+ 1
- 1
dgl/src/WindowPrivateData.hpp View File

@@ -181,7 +181,7 @@ struct Window::PrivateData : IdleCallback {
void runAsModal(bool blockWait);

// pugl events
void onPuglConfigure(double width, double height);
void onPuglConfigure(uint width, uint height);
void onPuglExpose();
void onPuglClose();
void onPuglFocus(bool focus, CrossingMode mode);


+ 2
- 1
dgl/src/pugl.cpp View File

@@ -363,7 +363,8 @@ PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height)

#ifdef DGL_USING_X11
// workaround issues in fluxbox, see https://github.com/lv2/pugl/issues/118
if (view->impl->win && !view->parent && !view->transientParent)
// NOTE troublesome if used under wayland
if (view->impl->win && !view->parent && !view->transientParent && std::getenv("WAYLAND_DISPLAY") == nullptr)
{
view->sizeHints[PUGL_DEFAULT_SIZE].width = view->sizeHints[PUGL_DEFAULT_SIZE].height = 0;
}


+ 28
- 4
distrho/DistrhoDetails.hpp View File

@@ -202,7 +202,7 @@ static constexpr const uint32_t kStateIsOnlyForUI = 0x20;

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

Each designation is unique, there must be only one parameter that uses it.@n
The use of designated parameters is completely optional.
@@ -214,13 +214,20 @@ enum ParameterDesignation {
/**
Null or unset designation.
*/
kParameterDesignationNull = 0,
kParameterDesignationNull,

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

/**
Reset designation.@n
When on (> 0.5f), it means the plugin should reset its internal processing state
(like filters, oscillators, envelopes, lfos, etc) and kill all voices.
*/
kParameterDesignationReset,
};

/**
@@ -234,7 +241,12 @@ namespace ParameterDesignationSymbols {
static constexpr const char bypass[] = "dpf_bypass";

/**
Bypass designation symbol, inverted for LV2 so it becomes "enabled".
Reset designation symbol.
*/
static constexpr const char reset[] = "dpf_reset";

/**
LV2 bypass designation symbol, inverted for LV2 so it becomes "enabled".
*/
static constexpr const char bypass_lv2[] = "lv2_enabled";
};
@@ -728,6 +740,18 @@ struct Parameter {
ranges.min = 0.0f;
ranges.max = 1.0f;
break;
case kParameterDesignationReset:
hints = kParameterIsAutomatable|kParameterIsBoolean|kParameterIsInteger|kParameterIsTrigger;
name = "Reset";
shortName = "Reset";
symbol = ParameterDesignationSymbols::reset;
unit = "";
midiCC = 0;
groupId = kPortGroupNone;
ranges.def = 0.0f;
ranges.min = 0.0f;
ranges.max = 1.0f;
break;
}
}



+ 6
- 0
distrho/DistrhoInfo.hpp View File

@@ -553,6 +553,12 @@ START_NAMESPACE_DISTRHO
*/
#define DISTRHO_PLUGIN_WANT_LATENCY 1

/**
Whether the plugin wants MPE for MIDI input and/or output.
@note Only AU and CLAP formats implement this at the moment
*/
#define DISTRHO_PLUGIN_WANT_MIDI_AS_MPE 0

/**
Whether the plugin wants MIDI input.@n
This is automatically enabled if @ref DISTRHO_PLUGIN_IS_SYNTH is true.


+ 18
- 4
distrho/extra/String.hpp View File

@@ -22,6 +22,10 @@

#include <algorithm>

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

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
@@ -49,10 +53,7 @@ public:
fBufferLen(0),
fBufferAlloc(false)
{
char ch[2];
ch[0] = c;
ch[1] = '\0';

const char ch[2] = { c, '\0' };
_dup(ch);
}

@@ -87,6 +88,19 @@ public:
_dup(strBuf);
}

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

/*
* Integer.
*/


+ 5
- 3
distrho/extra/WebViewImpl.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 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
@@ -106,7 +106,7 @@

@implementation WEB_VIEW_DELEGATE_CLASS_NAME {
@public
WebViewMessageCallback callback;
DISTRHO_NAMESPACE::WebViewMessageCallback callback;
void* callbackPtr;
bool loaded;
}
@@ -1039,7 +1039,9 @@ static bool gtk3(Display* const display,
{
void* lib;
if ((lib = dlopen("libwebkit2gtk-4.0.so.37", RTLD_NOW|RTLD_GLOBAL)) == nullptr &&
(lib = dlopen("libwebkit2gtk-4.0.so", RTLD_NOW|RTLD_GLOBAL)) == nullptr)
(lib = dlopen("libwebkit2gtk-4.1.so.0", RTLD_NOW|RTLD_GLOBAL)) == nullptr &&
(lib = dlopen("libwebkit2gtk-4.0.so", RTLD_NOW|RTLD_GLOBAL)) == nullptr &&
(lib = dlopen("libwebkit2gtk-4.1.so", RTLD_NOW|RTLD_GLOBAL)) == nullptr)
{
d_stdout("WebView gtk3 platform not available: %s", dlerror());
return false;


+ 148
- 68
distrho/src/DistrhoPluginAU.cpp View File

@@ -202,7 +202,8 @@ static constexpr const uint32_t kType = d_cconst(STRINGIFY(DISTRHO_PLUGIN_AU_TYP
static constexpr const uint32_t kSubType = d_cconst(STRINGIFY(DISTRHO_PLUGIN_UNIQUE_ID));
static constexpr const uint32_t kManufacturer = d_cconst(STRINGIFY(DISTRHO_PLUGIN_BRAND_ID));

static constexpr const uint32_t kWantedAudioFormat = kAudioFormatFlagsNativeFloatPacked
static constexpr const uint32_t kWantedAudioFormat = 0
| kAudioFormatFlagsNativeFloatPacked
| kAudioFormatFlagIsNonInterleaved;


@@ -263,7 +264,7 @@ bool isNumChannelsComboValid(const uint16_t numInputs, const uint16_t numOutputs
// --------------------------------------------------------------------------------------------------------------------

struct PropertyListener {
AudioUnitPropertyID prop;
AudioUnitPropertyID prop;
AudioUnitPropertyListenerProc proc;
void* userData;
};
@@ -276,12 +277,28 @@ struct RenderListener {
typedef std::vector<PropertyListener> PropertyListeners;
typedef std::vector<RenderListener> RenderListeners;

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

typedef struct {
UInt32 numPackets;
MIDIPacket packets[kMaxMidiEvents];
} d_MIDIPacketList;
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
// useful definitions
static constexpr const uint32_t kMIDIPacketNonDataSize = sizeof(MIDIPacket)
#if __cplusplus >= 201103L
- sizeof(MIDIPacket::data);
#else
- sizeof(static_cast<MIDIPacket*>(0)->data);
#endif
static constexpr const uint32_t kMIDIPacketListNonDataSize = sizeof(MIDIPacketList)
#if __cplusplus >= 201103L
- sizeof(MIDIPacketList::packet);
#else
- sizeof(static_cast<MIDIPacketList*>(0)->packet);
#endif

// size of data used for midi events
static constexpr const uint32_t kMIDIPacketListMaxDataSize = kMIDIPacketNonDataSize * kMaxMidiEvents
+ sizeof(Byte) * MidiEvent::kDataSize * kMaxMidiEvents;

// size of midi list + data
static constexpr const uint32_t kMIDIPacketListSize = kMIDIPacketListNonDataSize + kMIDIPacketListMaxDataSize;
#endif

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

@@ -331,10 +348,14 @@ public:
fUsingRenderListeners(false),
fParameterCount(fPlugin.getParameterCount()),
fLastParameterValues(nullptr),
fBypassParameterIndex(UINT32_MAX)
fBypassParameterIndex(UINT32_MAX),
fResetParameterIndex(UINT32_MAX)
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
, fMidiEventCount(0)
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
, fMidiOutputDataOffset(0)
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
, fCurrentProgram(-1)
, fLastFactoryProgram(0)
@@ -345,7 +366,7 @@ public:
, fStateCount(fPlugin.getStateCount())
#endif
{
if (fParameterCount != 0)
if (fParameterCount != 0)
{
fLastParameterValues = new float[fParameterCount];
std::memset(fLastParameterValues, 0, sizeof(float) * fParameterCount);
@@ -354,8 +375,17 @@ public:
{
fLastParameterValues[i] = fPlugin.getParameterValue(i);

if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
switch (fPlugin.getParameterDesignation(i))
{
case kParameterDesignationNull:
break;
case kParameterDesignationBypass:
fBypassParameterIndex = i;
break;
case kParameterDesignationReset:
fResetParameterIndex = i;
break;
}
}
}

@@ -370,8 +400,10 @@ public:
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
if ((fMidiOutputPackets = static_cast<MIDIPacketList*>(std::malloc(kMIDIPacketListSize))) != nullptr)
std::memset(fMidiOutputPackets, 0, kMIDIPacketListSize);

std::memset(&fMidiOutput, 0, sizeof(fMidiOutput));
std::memset(&fMidiOutputPackets, 0, sizeof(fMidiOutputPackets));
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -428,6 +460,10 @@ public:
reallocAudioBufferList(false);
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
std::free(fMidiOutputPackets);
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
for (uint32_t i=0; i<fProgramCount; ++i)
CFRelease(fFactoryPresetsData[i].presetName);
@@ -451,7 +487,8 @@ public:
fMidiEventCount = 0;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS
fTimePosition.clear();
@@ -635,7 +672,7 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
#if DISTRHO_PLUGIN_WANT_TIMEPOS
outDataSize = sizeof(HostCallbackInfo);
outWritable = false;
outWritable = true;
return noErr;
#else
return kAudioUnitErr_InvalidProperty;
@@ -659,6 +696,17 @@ public:
outWritable = true;
return noErr;

case kAudioUnitProperty_SupportsMPE:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
#if DISTRHO_PLUGIN_WANT_MIDI_AS_MPE
outDataSize = sizeof(UInt32);
outWritable = false;
return noErr;
#else
return kAudioUnitErr_InvalidProperty;
#endif

case kAudioUnitProperty_CocoaUI:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
@@ -708,7 +756,7 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
outDataSize = sizeof(uint16_t);
outWritable = false;
outWritable = true;
return noErr;

case 'DPFe':
@@ -739,7 +787,7 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
outDataSize = sizeof(uint32_t);
outWritable = false;
outWritable = true;
return noErr;
#endif

@@ -748,7 +796,7 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
outDataSize = sizeof(CFArrayRef);
outWritable = false;
outWritable = true;
return noErr;

case 'DPFs':
@@ -764,7 +812,7 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
outDataSize = sizeof(void*);
outWritable = false;
outWritable = true;
return noErr;
#endif

@@ -885,13 +933,13 @@ public:
case kAudioUnitProperty_FastDispatch:
switch (inElement)
{
case kAudioUnitGetParameterSelect:
case kAudioUnitGetParameterSelect:
*static_cast<AudioUnitGetParameterProc*>(outData) = FastDispatchGetParameter;
return noErr;
case kAudioUnitSetParameterSelect:
case kAudioUnitSetParameterSelect:
*static_cast<AudioUnitSetParameterProc*>(outData) = FastDispatchSetParameter;
return noErr;
case kAudioUnitRenderSelect:
case kAudioUnitRenderSelect:
*static_cast<AudioUnitRenderProc*>(outData) = FastDispatchRender;
return noErr;
}
@@ -1028,6 +1076,12 @@ public:
}
return noErr;

#if DISTRHO_PLUGIN_WANT_MIDI_AS_MPE
case kAudioUnitProperty_SupportsMPE:
*static_cast<UInt32*>(outData) = 1;
return noErr;
#endif

#if DISTRHO_PLUGIN_HAS_UI
case kAudioUnitProperty_CocoaUI:
{
@@ -1414,7 +1468,7 @@ public:
const float value = bypass ? 1.f : 0.f;
fLastParameterValues[fBypassParameterIndex] = value;
fPlugin.setParameterValue(fBypassParameterIndex, value);
notifyPropertyListeners(inProp, inScope, inElement);
notifyPropertyListeners(inProp, inScope, inElement);
}
}
return noErr;
@@ -1436,12 +1490,12 @@ public:
#if DISTRHO_PLUGIN_WANT_TIMEPOS
{
const UInt32 usableDataSize = std::min(inDataSize, static_cast<UInt32>(sizeof(HostCallbackInfo)));
const bool changed = std::memcmp(&fHostCallbackInfo, inData, usableDataSize) != 0;
const bool changed = std::memcmp(&fHostCallbackInfo, inData, usableDataSize) != 0;

std::memcpy(&fHostCallbackInfo, inData, usableDataSize);
std::memcpy(&fHostCallbackInfo, inData, usableDataSize);

if (sizeof(HostCallbackInfo) > usableDataSize)
std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize);
std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize);

if (changed)
notifyPropertyListeners(inProp, inScope, inElement);
@@ -1568,7 +1622,7 @@ public:
AUEventListenerNotify(NULL, NULL, &event);

if (fBypassParameterIndex == inElement)
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
}
return noErr;

@@ -1777,7 +1831,12 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(scope == kAudioUnitScope_Global || scope == kAudioUnitScope_Input || scope == kAudioUnitScope_Output, scope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(elem == 0, elem, kAudioUnitErr_InvalidElement);

if (fPlugin.isActive())
if (fResetParameterIndex != UINT32_MAX)
{
fPlugin.setParameterValue(fResetParameterIndex, 1.f);
fPlugin.setParameterValue(fResetParameterIndex, 0.f);
}
else if (fPlugin.isActive())
{
fPlugin.deactivate();
fPlugin.activate();
@@ -1787,7 +1846,8 @@ public:
fMidiEventCount = 0;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS
fTimePosition.clear();
@@ -2015,7 +2075,7 @@ public:
midiEvent.data[1] = inData1;
midiEvent.data[2] = inData2;

switch (inStatus)
switch (inStatus & 0xF0)
{
case 0x80:
case 0x90:
@@ -2057,6 +2117,8 @@ public:
break;
default:
// invalid
d_debug("auMIDIEvent received invalid event %u %u %u %u @ %u",
inStatus, inData1, inData2, inOffsetSampleFrame, fMidiEventCount);
return kAudioUnitErr_InvalidPropertyValue;
}

@@ -2133,6 +2195,7 @@ private:
const uint32_t fParameterCount;
float* fLastParameterValues;
uint32_t fBypassParameterIndex;
uint32_t fResetParameterIndex;

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
uint32_t fMidiEventCount;
@@ -2141,8 +2204,9 @@ private:
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
uint32_t fMidiOutputDataOffset;
MIDIPacketList* fMidiOutputPackets;
AUMIDIOutputCallbackStruct fMidiOutput;
d_MIDIPacketList fMidiOutputPackets;
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -2172,7 +2236,7 @@ private:
const PropertyListener& pl(*it);

if (pl.prop == prop)
pl.proc(pl.userData, fComponent, prop, scope, elem);
pl.proc(pl.userData, fComponent, prop, scope, elem);
}
}

@@ -2217,7 +2281,8 @@ private:
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif

#if DISTRHO_PLUGIN_WANT_TIMEPOS
@@ -2294,12 +2359,11 @@ private:
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
if (fMidiOutputPackets.numPackets != 0 && fMidiOutput.midiOutputCallback != nullptr)
if (fMidiOutputPackets != nullptr &&
fMidiOutputPackets->numPackets != 0 &&
fMidiOutput.midiOutputCallback != nullptr)
{
fMidiOutput.midiOutputCallback(fMidiOutput.userData,
inTimeStamp,
0,
reinterpret_cast<const ::MIDIPacketList*>(&fMidiOutputPackets));
fMidiOutput.midiOutputCallback(fMidiOutput.userData, inTimeStamp, 0, fMidiOutputPackets);
}
#else
// unused
@@ -2716,17 +2780,21 @@ private:
bool writeMidi(const MidiEvent& midiEvent)
{
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("MIDI output unsupported", fMidiOutput.midiOutputCallback != nullptr, false);
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("Out of memory", fMidiOutputPackets != nullptr, false);

if (midiEvent.size > sizeof(MIDIPacket::data))
return true;
if (fMidiOutputPackets.numPackets == kMaxMidiEvents)
if (fMidiOutputDataOffset + kMIDIPacketNonDataSize + midiEvent.size >= kMIDIPacketListMaxDataSize)
return false;

const uint8_t* const midiData = midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data;
MIDIPacket& packet(fMidiOutputPackets.packets[fMidiOutputPackets.numPackets++]);
packet.timeStamp = midiEvent.frame;
packet.length = midiEvent.size;
std::memcpy(packet.data, midiData, midiEvent.size);
MIDIPacket* const packet = reinterpret_cast<MIDIPacket*>(
reinterpret_cast<uint8_t*>(fMidiOutputPackets->packet) + fMidiOutputDataOffset);

packet->timeStamp = midiEvent.frame;
packet->length = midiEvent.size;
std::memcpy(packet->data, midiData, midiEvent.size);

++fMidiOutputPackets->numPackets;
fMidiOutputDataOffset += kMIDIPacketNonDataSize + midiEvent.size;
return true;
}

@@ -2793,7 +2861,7 @@ private:
// --------------------------------------------------------------------------------------------------------------------

struct AudioComponentPlugInInstance {
AudioComponentPlugInInterface acpi;
AudioComponentPlugInInterface acpi;
PluginAU* plugin;

AudioComponentPlugInInstance() noexcept
@@ -2802,9 +2870,9 @@ struct AudioComponentPlugInInstance {
{
std::memset(&acpi, 0, sizeof(acpi));
acpi.Open = Open;
acpi.Close = Close;
acpi.Lookup = Lookup;
acpi.reserved = nullptr;
acpi.Close = Close;
acpi.Lookup = Lookup;
acpi.reserved = nullptr;
}

~AudioComponentPlugInInstance()
@@ -2812,14 +2880,18 @@ struct AudioComponentPlugInInstance {
delete plugin;
}

static OSStatus Open(void* const self, const AudioUnit component)
static OSStatus Open(void* const self, const AudioUnit component)
{
d_debug("AudioComponentPlugInInstance::Open(%p)", self);

static_cast<AudioComponentPlugInInstance*>(self)->plugin = new PluginAU(component);
return noErr;
}

static OSStatus Close(void* const self)
static OSStatus Close(void* const self)
{
d_debug("AudioComponentPlugInInstance::Close(%p)", self);

delete static_cast<AudioComponentPlugInInstance*>(self);
return noErr;
}
@@ -2908,15 +2980,15 @@ struct AudioComponentPlugInInstance {
d_debug("AudioComponentPlugInInstance::GetPropertyInfo(%p, %d:%x:%s, %d:%s, %d, ...)",
self, inProp, inProp, AudioUnitPropertyID2Str(inProp), inScope, AudioUnitScope2Str(inScope), inElement);

UInt32 dataSize = 0;
Boolean writable = false;
UInt32 dataSize = 0;
Boolean writable = false;
const OSStatus res = self->plugin->auGetPropertyInfo(inProp, inScope, inElement, dataSize, writable);

if (outDataSize != nullptr)
*outDataSize = dataSize;
if (outDataSize != nullptr)
*outDataSize = dataSize;

if (outWritable != nullptr)
*outWritable = writable;
if (outWritable != nullptr)
*outWritable = writable;

return res;
}
@@ -2928,8 +3000,16 @@ struct AudioComponentPlugInInstance {
void* const outData,
UInt32* const ioDataSize)
{
d_debug("AudioComponentPlugInInstance::GetProperty(%p, %d:%x:%s, %d:%s, %d, ...)",
self, inProp, inProp, AudioUnitPropertyID2Str(inProp), inScope, AudioUnitScope2Str(inScope), inElement);
#ifdef DEBUG
switch (inProp) {
case kAudioUnitProperty_PresentPreset:
break;
default:
d_debug("AudioComponentPlugInInstance::GetProperty(%p, %d:%x:%s, %d:%s, %d, ...)",
self, inProp, inProp, AudioUnitPropertyID2Str(inProp), inScope, AudioUnitScope2Str(inScope), inElement);
break;
}
#endif
DISTRHO_SAFE_ASSERT_RETURN(ioDataSize != nullptr, kAudio_ParamError);

Boolean writable;
@@ -2952,24 +3032,24 @@ struct AudioComponentPlugInInstance {
if (res != noErr)
return res;

void* outBuffer;
void* outBuffer;
uint8_t* tmpBuffer;
if (inDataSize < outDataSize)
{
tmpBuffer = new uint8_t[outDataSize];
outBuffer = tmpBuffer;
}
{
tmpBuffer = new uint8_t[outDataSize];
outBuffer = tmpBuffer;
}
else
{
tmpBuffer = nullptr;
outBuffer = outData;
}
tmpBuffer = nullptr;
outBuffer = outData;
}

res = self->plugin->auGetProperty(inProp, inScope, inElement, outBuffer);

if (res != noErr)
if (res != noErr)
{
*ioDataSize = 0;
*ioDataSize = 0;
return res;
}



+ 58
- 11
distrho/src/DistrhoPluginCLAP.cpp View File

@@ -751,6 +751,7 @@ public:
updateStateValueCallback),
fHost(host),
fOutputEvents(nullptr),
fResetParameterIndex(UINT32_MAX),
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0
fUsingCV(false),
#endif
@@ -763,7 +764,19 @@ public:
#endif
fHostExtensions(host)
{
fCachedParameters.setup(fPlugin.getParameterCount());
if (const uint32_t paramCount = fPlugin.getParameterCount())
{
fCachedParameters.setup(paramCount);

for (uint32_t i=0; i<paramCount; ++i)
{
if (fPlugin.getParameterDesignation(i) == kParameterDesignationReset)
{
fResetParameterIndex = i;
break;
}
}
}

#if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT
fNotesRingBuffer.setRingBuffer(&fNotesBuffer, true);
@@ -821,6 +834,22 @@ public:
#endif
}

void reset()
{
if (fResetParameterIndex != UINT32_MAX)
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
fMidiEventCount = 0;
#endif
fPlugin.setParameterValue(fResetParameterIndex, 1.f);
fPlugin.setParameterValue(fResetParameterIndex, 0.f);
}
else
{
fHost->request_restart(fHost);
}
}

bool process(const clap_process_t* const process)
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -1114,14 +1143,19 @@ public:
{
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));

if (fPlugin.getParameterDesignation(index) == kParameterDesignationBypass)
switch (fPlugin.getParameterDesignation(index))
{
case kParameterDesignationBypass:
info->flags = CLAP_PARAM_IS_STEPPED|CLAP_PARAM_IS_BYPASS|CLAP_PARAM_IS_AUTOMATABLE;
std::strcpy(info->name, "Bypass");
std::strcpy(info->module, "dpf_bypass");
}
else
{
break;
case kParameterDesignationReset:
info->flags = CLAP_PARAM_IS_STEPPED|CLAP_PARAM_IS_READONLY;
std::strcpy(info->name, "Reset");
std::strcpy(info->module, "dpf_reset");
break;
default:
const uint32_t hints = fPlugin.getParameterHints(index);
const uint32_t groupId = fPlugin.getParameterGroupId(index);

@@ -1151,6 +1185,7 @@ public:
}

d_strncpy(info->module + wrtn, fPlugin.getParameterSymbol(index), CLAP_PATH_SIZE - wrtn);
break;
}

info->id = index;
@@ -1786,6 +1821,7 @@ private:
const clap_host_t* const fHost;
const clap_output_events_t* fOutputEvents;

uint32_t fResetParameterIndex;
#if DISTRHO_PLUGIN_NUM_INPUTS != 0
const float* fAudioInputs[DISTRHO_PLUGIN_NUM_INPUTS];
#endif
@@ -2284,23 +2320,33 @@ static bool CLAP_ABI clap_plugin_note_ports_get(const clap_plugin_t*, uint32_t,
{
if (is_input)
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
info->id = 0;
#if DISTRHO_PLUGIN_WANT_MIDI_AS_MPE
info->supported_dialects = CLAP_NOTE_DIALECT_MIDI | CLAP_NOTE_DIALECT_MIDI_MPE;
info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI_MPE;
#else
info->supported_dialects = CLAP_NOTE_DIALECT_MIDI;
info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI;
#endif
std::strcpy(info->name, "Event/MIDI Input");
return true;
#endif
#endif
}
else
{
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
info->id = 0;
#if DISTRHO_PLUGIN_WANT_MIDI_AS_MPE
info->supported_dialects = CLAP_NOTE_DIALECT_MIDI | CLAP_NOTE_DIALECT_MIDI_MPE;
info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI_MPE;
#else
info->supported_dialects = CLAP_NOTE_DIALECT_MIDI;
info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI;
#endif
std::strcpy(info->name, "Event/MIDI Output");
return true;
#endif
#endif
}

return false;
@@ -2440,9 +2486,10 @@ static void CLAP_ABI clap_plugin_stop_processing(const clap_plugin_t*)
// nothing to do
}

static void CLAP_ABI clap_plugin_reset(const clap_plugin_t*)
static void CLAP_ABI clap_plugin_reset(const clap_plugin_t* const plugin)
{
// nothing to do
PluginCLAP* const instance = static_cast<PluginCLAP*>(plugin->plugin_data);
instance->reset();
}

static clap_process_status CLAP_ABI clap_plugin_process(const clap_plugin_t* const plugin, const clap_process_t* const process)


+ 11
- 0
distrho/src/DistrhoPluginChecks.h View File

@@ -65,6 +65,10 @@
# define DISTRHO_PLUGIN_WANT_LATENCY 0
#endif

#ifndef DISTRHO_PLUGIN_WANT_MIDI_AS_MPE
# define DISTRHO_PLUGIN_WANT_MIDI_AS_MPE 0
#endif

#ifndef DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
# define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0
#endif
@@ -178,6 +182,13 @@
# error Synths need audio output to work!
#endif

// --------------------------------------------------------------------------------------------------------------------
// Test if MIDI as MPE enabled where it doesn't make sense

#if DISTRHO_PLUGIN_WANT_MIDI_AS_MPE && ! (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT)
# error MIDI as MPE needs MIDI input or output to work!
#endif

// --------------------------------------------------------------------------------------------------------------------
// Enable MIDI input if synth, test if midi-input disabled when synth



+ 10
- 0
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -758,6 +758,16 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:portProperty lv2:toggled , lv2:integer ;\n";
pluginString += " lv2:designation lv2:enabled ;\n";
break;
case kParameterDesignationReset:
designated = true;
pluginString += " lv2:name \"Reset\" ;\n";
pluginString += " lv2:symbol \"" + String(ParameterDesignationSymbols::reset) + "\" ;\n";
pluginString += " lv2:default 0 ;\n";
pluginString += " lv2:minimum 0 ;\n";
pluginString += " lv2:maximum 1 ;\n";
pluginString += " lv2:portProperty lv2:toggled , lv2:integer , <" LV2_PORT_PROPS__trigger "> ;\n";
pluginString += " lv2:designation <" LV2_KXSTUDIO_PROPERTIES__Reset "> ;\n";
break;
}
}



+ 6
- 0
distrho/src/DistrhoPluginVST3.cpp View File

@@ -1763,6 +1763,12 @@ public:
case kParameterDesignationBypass:
flags |= V3_PARAM_IS_BYPASS;
break;
case kParameterDesignationReset:
info->flags = V3_PARAM_READ_ONLY | V3_PARAM_IS_HIDDEN;
info->step_count = 1;
strncpy_utf16(info->title, "Reset", 128);
strncpy_utf16(info->short_title, "Reset", 128);
return V3_OK;
}

if (hints & kParameterIsOutput)


+ 3
- 0
distrho/src/DistrhoUIAU.mm View File

@@ -387,6 +387,9 @@ END_NAMESPACE_DISTRHO
#define COCOA_VIEW_CLASS_NAME \
MACRO_NAME(CocoaView_, DISTRHO_PLUGIN_AU_TYPE, _, DISTRHO_PLUGIN_UNIQUE_ID, _, DISTRHO_PLUGIN_BRAND_ID)

using DISTRHO_NAMESPACE::DPF_UI_AU;
using DISTRHO_NAMESPACE::d_nextSampleRate;

@interface COCOA_VIEW_CLASS_NAME : NSView
{
@public


+ 2
- 2
distrho/src/DistrhoUIInternal.hpp View File

@@ -267,12 +267,12 @@ public:
uiData->app.repaintIfNeeeded();
}

void addIdleCallbackForNativeIdle(IdleCallback* const cb, const uint timerFrequencyInMs)
void addIdleCallbackForNativeIdle(DGL_NAMESPACE::IdleCallback* const cb, const uint timerFrequencyInMs)
{
uiData->window->addIdleCallback(cb, timerFrequencyInMs);
}

void removeIdleCallbackForNativeIdle(IdleCallback* const cb)
void removeIdleCallbackForNativeIdle(DGL_NAMESPACE::IdleCallback* const cb)
{
uiData->window->removeIdleCallback(cb);
}


+ 1
- 1
distrho/src/DistrhoUIVST3.cpp View File

@@ -129,7 +129,7 @@ static uint translateVST3Modifiers(const int64_t modifiers) noexcept
* Helper class for getting a native idle timer.
*/
#if !DPF_VST3_USING_HOST_RUN_LOOP
class NativeIdleCallback : public IdleCallback
class NativeIdleCallback : public DGL_NAMESPACE::IdleCallback
{
public:
NativeIdleCallback(UIExporter& ui)


+ 2
- 1
distrho/src/lv2/lv2_kxstudio_properties.h View File

@@ -1,6 +1,6 @@
/*
LV2 KXStudio Properties Extension
Copyright 2014-2021 Filipe Coelho <falktx@falktx.com>
Copyright 2014-2024 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
@@ -27,6 +27,7 @@
#define LV2_KXSTUDIO_PROPERTIES_PREFIX LV2_KXSTUDIO_PROPERTIES_URI "#"

#define LV2_KXSTUDIO_PROPERTIES__NonAutomatable LV2_KXSTUDIO_PROPERTIES_PREFIX "NonAutomatable"
#define LV2_KXSTUDIO_PROPERTIES__Reset LV2_KXSTUDIO_PROPERTIES_PREFIX "Reset"
#define LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat LV2_KXSTUDIO_PROPERTIES_PREFIX "TimePositionTicksPerBeat"
#define LV2_KXSTUDIO_PROPERTIES__TransientWindowId LV2_KXSTUDIO_PROPERTIES_PREFIX "TransientWindowId"



Loading…
Cancel
Save